zoukankan      html  css  js  c++  java
  • 利用MEF实现插件机制(可根据输入类型来加载特定dll)

      最近在做PACS的项目中想利用插件来加载各个不同的SCP的操作实现。比如Worklist的查询数据库,可以有多个实现。 比如MPPS的更新,也可以有多个实现。 为了统一弹性处理插件模块,增加了类型输入,用来只加载特定的服务的实现。
    
      [InheritedExport(typeof(ISCPBase))]
        public interface ISCPBase
        {
            ISCPCfg SCPCfg
            {
                get;
                set;
            }
     
            string CustomModuleName
            {
                get;
            }
        }
    


      public class CustomExtensionManager
        {
            [ImportMany(typeof(ISCPBase), AllowRecomposition = true)]
            public IEnumerable<ISCPBase> CustomModules { get; set; }
     
            public CompositionContainer Container;
     
            private Type[] _filterTypes;
     
            private ModulesManagerCfg _mgrCfg;
            public ModulesManagerCfg ModulesManagerConfig
            {
                get
                {
                    if (_mgrCfg == null)
                    {
                        try
                        {
                            _mgrCfg = XmlSerializeHelper<ModulesManagerCfg>.LoadFromFile(@"ModulesManagerCfg.xml");
                        }
                        catch (Exception ex)
                        {
                            Logger.ErrorWithFormat("Failed to load ModulesManagerCfg from ModulesManagerCfg.xml. {0}", ex.Message);
                        }
     
                        if (_mgrCfg == null)
                            Logger.Error("ModulesManagerCfg is null, please check whether ModulesManagerCfg.xml exists.");
                    }
     
                    return _mgrCfg;
                }
            }
     
            /// <summary>
            /// Initialize the custom modules by interface type. It is well you can spec types.
            /// If you do not care types, you can pass null. It will load all modules if inherited from ISCPBase.
            /// </summary>
            /// <param name="scpTypes">The type that inherited from ISCPBase. Like IWorklistQuery...</param>
            public void Initialize(params Type[] scpTypes)
            {
                try
                {
                    if (null != scpTypes)
                    {
                        _filterTypes = scpTypes;
     
                        var catalog = new AggregateCatalog(new TypeCatalog(scpTypes), new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
     
                        Container = new CompositionContainer(catalog);
                    }
                    else
                    {
                        var catalog = new AggregateCatalog(new TypeCatalog(scpTypes), new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
     
                        Container = new CompositionContainer(catalog);
                    }
     
                    Container.ComposeParts(this);
                }
                catch (Exception ex)
                {
                    Logger.ErrorWithFormat("Failed to initialize CustomExtensionManager. {0}", ex.Message);
                }
            }
     
            public ISCPBase GetCurrentUsedModule()
            {
                if (null == ModulesManagerConfig)
                {
                    throw new ArgumentNullException("ModulesManagerCfg is null, please check whether ModulesManagerCfg.xml exists.");
                }
     
                if (String.IsNullOrEmpty(ModulesManagerConfig.CurrentUsedModuleName))
                {
                    throw new Exception("CurrentUsedModuleName is empty, please check ModulesManagerCfg.xml.");
                }
     
                if (null == Container)
                {
                    throw new Exception("Modules container is null, you can check your custom module and call Initialize() function to load modules.");
                }
     
                //var m = _container.GetExports<ISCPBase>()
                //    .Where(e => e.Value.CustomModuleName.Equals(ModulesManagerConfig.CurrentUsedModuleName))
                //    .FirstOrDefault();
     
                //if (null != m)
                //{
                //    return m.Value;
                //}
     
                //return null;
     
                if (null == _filterTypes)
                {
                    var m = CustomModules.FirstOrDefault(e => e.CustomModuleName.Equals(ModulesManagerConfig.CurrentUsedModuleName));
                    return m;
                }
                else
                {
                     var m = from c in CustomModules
                             where _filterTypes.All(f => f.IsAssignableFrom(c.GetType()))
                             select c;
     
                    return m.FirstOrDefault();
                }
            }
        }
    
  • 相关阅读:
    系统设计的定量原理
    [Java-基础]单元测试Junit
    二维图元生成:直线生成算法
    [Java-基础]反射_Class对象_动态操作
    浅说模板的局限性
    普通函数和函数模板调用规则
    普通函数和函数模板的区别
    十大排序算法(原理及代码实现细节)
    linux远程登陆以及从其他服务器下载文件
    循环队列-抽象数据类型
  • 原文地址:https://www.cnblogs.com/muzizongheng/p/3170842.html
Copyright © 2011-2022 走看看