利用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();
            }
        }
    }
原文地址:https://www.cnblogs.com/muzizongheng/p/3170842.html