C#实现插件式架构的方法

来源:互联网 发布:ip反查域名在线工具 编辑:程序博客网 时间:2024/05/17 00:13

原文:http://www.renfb.com/blog/2011/Article/259

插件式架构,一种全新的、开放性的、高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。下面已C# .Net简要介绍一下插件式架构的方法.

定义插件接口,将其编译成dllnamespace PluginInterface{      public interface IPlugin      {             string Show();      }}


编写插件,引用上面的DLL,实现上面定义的接口,也编译为DLL//插件Anamespace PluginA{    public class PluginA:IPlugin    {        public string Show()        {            return "插件A";        }    }}


//插件Bnamespace PluginB{    public class PluginB : IPlugin    {        public string Show()        {            return "插件B";        }    }}


新建一个控制台程序,需要引用定义插件接口的dll,生成之后,需要在exe所在的目录里建一个Plugins子文件夹,将上面生成的PluginA.dll,和PluginB.dll拷贝进去。

namespace ConsolePluginTest{    class Program    {        static void Main(string[] args)        {            Program p = new Program();            List<string> pluginpath =  p.FindPlugin();            pluginpath = p.DeleteInvalidPlungin(pluginpath);            foreach (string filename in pluginpath)            {                try                {                    //获取文件名                    string asmfile = filename;                    string asmname = Path.GetFileNameWithoutExtension(asmfile);                    if (asmname != string.Empty)                    {                        // 利用反射,构造DLL文件的实例                        Assembly asm = Assembly.LoadFile(asmfile);                        //利用反射,从程序集(DLL)中,提取类,并把此类实例化                        Type[] t = asm.GetExportedTypes();                        foreach (Type type in t)                        {                            if (type.GetInterface("IPlugin") != null)                            {                                IPlugin show = (IPlugin)Activator.CreateInstance(type);                                Console.Write(show.Show());                            }                        }                    }                }                catch(Exception ex)                {                    Console.Write(ex.Message);                }            }        }        //查找所有插件的路径        private List<string> FindPlugin()        {            List<string> pluginpath = new List<string>();            try            {                //获取程序的基目录                string path = AppDomain.CurrentDomain.BaseDirectory;                //合并路径,指向插件所在目录。                path = Path.Combine(path,"Plugins");                foreach (string filename in Directory.GetFiles(path, "*.dll"))                {                    pluginpath.Add(filename);                }            }            catch(Exception ex)            {                Console.Write(ex.Message);            }            return pluginpath;        }        //载入插件,在Assembly中查找类型        private object LoadObject(Assembly asm, string className, string interfacename                        , object[] param)        {            try            {                //取得className的类型                Type t =asm.GetType(className);                if (t == null                    || !t.IsClass                    || !t.IsPublic                    || t.IsAbstract                    || t.GetInterface(interfacename) == null                   )                {                    return null;                }                //创建对象                Object o = Activator.CreateInstance(t,param);                if (o == null)                {                    //创建失败,返回null                    return null;                }                return o;            }            catch            {                return null;            }        }        //移除无效的的插件,返回正确的插件路径列表,Invalid:无效的        private List<string> DeleteInvalidPlungin(List<string> PlunginPath)        {            string interfacename = typeof(IPlugin).FullName;            List<string> rightPluginPath = new List<string>();            //遍历所有插件。            foreach (string filename in PlunginPath)            {                try                {                    Assembly asm = Assembly.LoadFile(filename);                    //遍历导出插件的类。                    foreach (Type t in asm.GetExportedTypes())                    {                        //查找指定接口                        Object plugin = LoadObject(asm,t.FullName,interfacename,null);                        //如果找到,将插件路径添加到rightPluginPath列表里,并结束循环。                        if (plugin != null)                        {                            rightPluginPath.Add(filename);                            break;                        }                    }                }                catch                {                    throw new Exception(filename+"不是有效插件");                }            }            return rightPluginPath;        }    }}

0 0
原创粉丝点击