zoukankan      html  css  js  c++  java
  • C#实现插件式架构的方法

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

    定义插件接口,将其编译成dll

    namespace PluginInterface
    {
          public interface IPlugin
          {
                 string Show();
          }
    }
    

    编写插件,引用上面的DLL,实现上面定义的接口,也编译为DLL

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

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

        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;
            }
        }
    

    原文

  • 相关阅读:
    VC++导入导出类
    SVN操作手册
    stdcall与cdecl的区别
    VC++编译MPIR 2.7.0
    zabbix 监控 WEB 应用性能
    zabbix 常用监控模板
    zabbix 自定义 windows 监控项
    zabbix 自定义 nginx 监控模板
    zabbix agent 自定义 UserParameter
    zabbix python 微信告警脚本
  • 原文地址:https://www.cnblogs.com/zbfamily/p/9634908.html
Copyright © 2011-2022 走看看