internal class Program : IPartImportsSatisfiedNotification
{
private static void Main(string[] args)
{
var mefs = new CommonPartsManager<IMefInterface>();
mefs.Run();
var demo = mefs.GetClass("2");
demo.Send("456778899");
Console.WriteLine("按任意键退出..............");
Console.ReadKey();
}
public void OnImportsSatisfied()
{
throw new NotImplementedException();
}
}
部件接口
/// <summary>
/// 部件统一接口
/// </summary>
public interface IMefInterface
{
void Send(string msg);
}
/// <summary>
/// 部件描述类
/// </summary>
public interface IMefInterfaceDepict
{
string Depict { get; }
}
派生类
// Export标记需要导出的接口类部件
[Export(typeof(IMefInterface))]
[ExportMetadata("Depict", "1")]
public class DemoOneInherit1 : IMefInterface, IDisposable
{
public void Dispose()
{
// release
}
public void Send(string msg)
{
Console.WriteLine("DemoOneInherit1 send {0}", msg);
}
}
[Export(typeof(IMefInterface))]
[ExportMetadata("Depict", "2")]
public class DemoOneInherit2 : IMefInterface, IDisposable
{
public void Dispose()
{
// release
}
public void Send(string msg)
{
Console.WriteLine("DemoOneInherit2 send {0}", msg);
}
}
[Export(typeof(IMefInterface))]
[ExportMetadata("Depict", "3")]
public class DemoOneInherit3 : IMefInterface, IDisposable
{
public void Dispose()
{
// release
}
public void Send(string msg)
{
Console.WriteLine("DemoOneInherit3 send {0}", msg);
}
}
部件管理类
/// <summary>
/// 部件管理类
/// </summary>
/// <typeparam name="T">部件接口类型</typeparam>
public class CommonPartsManager<T>
{
public CommonPartsManager()
{
this.ComposePartsSelf();
}
// Import标记需要导入的对象
[ImportMany(AllowRecomposition = true)]
private IEnumerable<Lazy<IMefInterface, IMefInterfaceDepict>> _mefs = null;
/// <summary>
/// 通过名称反射出对应的类
/// </summary>
/// <param name="depictName">部件描述</param>
/// <returns></returns>
public T GetClass(string depictName)
{
if (Names.Any(x => x == depictName))
{
var rslt = _mefs.Where(x => x.Metadata.Depict == depictName).Select(p => p.Value).FirstOrDefault();
return (T)rslt;
}
return default;
}
/// <summary>
/// 部件名称
/// </summary>
public IEnumerable<string> Names
{
get => _mefs.Select(x => x.Metadata.Depict);
}
// test
public void Run()
{
foreach (var item in _mefs)
{
item.Value.Send($"DemoOne.Run {item.Metadata.Depict}");
}
}
}
MEF扩展
public static partial class ObjectExt
{
/// <summary>
/// 自定义组合部件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T ComposePartsSelf<T>(this T obj, string dirName = ".") where T : class
{
var cataLog = new AggregateCatalog();
// 在程序集中查找目录
cataLog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
// 在路径中查找
cataLog.Catalogs.Add(new DirectoryCatalog(dirName)); //遍历运行目录下的文件夹,查找所需的插件
var container = new CompositionContainer(cataLog);
try
{
container.ComposeParts(obj);
}
catch (CompositionException ex)
{
Console.WriteLine(ex.ToString());
}
return obj;
}
/// <summary>
/// 对目录中部件的筛选
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="dirName"></param>
/// <param name="metadataKey"></param>
/// <param name="metadataValue"></param>
/// <returns></returns>
public static T ComposePartsFilter<T>(this T obj, string dirName = ".", string metadataKey = "", string metadataValue = "") where T : class
{
var cataLog = new AggregateCatalog();
// 在程序集中查找目录
cataLog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
// 在路径中查找
cataLog.Catalogs.Add(new DirectoryCatalog(dirName)); //遍历运行目录下的文件夹,查找所需的插件
var containerParent = new CompositionContainer(cataLog);
var filteredCat = new FilteredCatalog(cataLog, def =>
def.Metadata.ContainsKey(metadataKey) &&
def.Metadata[metadataKey].ToString() == metadataValue);
var preRequest = new CompositionContainer(filteredCat, containerParent);
try
{
preRequest.ComposeParts(obj);
}
catch (CompositionException ex)
{
Console.WriteLine(ex.ToString());
}
return obj;
}
}
/// <summary>
/// 目录筛选
/// </summary>
public class FilteredCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
{
private readonly ComposablePartCatalog _inner;
private readonly INotifyComposablePartCatalogChanged _innerNotifyChange;
private readonly IQueryable<ComposablePartDefinition> _partsQuery;
public FilteredCatalog(ComposablePartCatalog inner, Expression<Func<ComposablePartDefinition, bool>> expression)
{
_inner = inner;
_innerNotifyChange = inner as INotifyComposablePartCatalogChanged;
_partsQuery = inner.Parts.Where(expression);
}
public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed
{
add
{
if (_innerNotifyChange != null)
{
_innerNotifyChange.Changed += value;
}
}
remove
{
if (_innerNotifyChange != null)
{
_innerNotifyChange.Changed -= value;
}
}
}
public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing
{
add
{
if (_innerNotifyChange != null)
{
_innerNotifyChange.Changing += value;
}
}
remove
{
if (_innerNotifyChange != null)
{
_innerNotifyChange.Changing -= value;
}
}
}
public override IQueryable<ComposablePartDefinition> Parts => _partsQuery;
}