利用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 CustomModuleswhere _filterTypes.All(f => f.IsAssignableFrom(c.GetType()))select c;return m.FirstOrDefault(); } } }
https://muzizongheng.blog.csdn.net/