1. 程式人生 > >利用MEF實現外掛機制(可根據輸入型別來載入特定dll)

利用MEF實現外掛機制(可根據輸入型別來載入特定dll)

<?xml version="1.0" encoding="UTF-8"?>
  最近在做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 { varm = fromcin CustomModules
where_filterTypes.All(f => f.IsAssignableFrom(c.GetType()))
                         select c;
 
                return m.FirstOrDefault();
            }
        }
    }