利用MEF實現外掛機制(可根據輸入型別來載入特定dll)
阿新 • • 發佈:2019-01-25
<?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; privateModulesManagerCfg _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();
}
}
}