最近在做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();
}
}
}