Jos*_*osh 4 .net mef composition
我对MEF比较新,所以我不完全了解这些功能.我正在尝试实现与Unity的InjectionMember类似的功能.
假设我有一个导入MEF部件的类.为简单起见,我们将以下类作为导出部分的示例.
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class Logger {
public string Category {
get;
set;
}
public void Write(string text) {
}
}
public class MyViewModel {
[Import]
public Logger Log {
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想弄清楚的是,是否可以在导入时为Category属性指定值.就像是:
public class MyViewModel {
[MyImportAttribute(Category="MyCategory")]
public Logger Log {
get;
set;
}
}
public class MyOtherViewModel {
[MyImportAttribute(Category="MyOtherCategory")]
public Logger Log {
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
目前,我正在做的是实现IPartImportsSatisfiedNotification并在代码中设置Category.但显然我宁愿把一切都整齐地放在一个地方.
在MEF编程指南中,阅读有关导出和元数据的部分.它显示了如何通过使用ExportMetadata属性或通过定义自己的自定义导出属性在导出的部件上添加元数据.
然后,您可以定义如下ILoggerMetadata界面:
public interface ILoggerMetadata
{
string Catagory { get; }
}
Run Code Online (Sandbox Code Playgroud)
并执行ImportManya IEnumerable<Lazy<ILogger,ILoggerMetadata>>并在代码中选择您想要的那个:
private ILogger fooLogger;
[ImportMany]
public IEnumerable<Lazy<ILogger,ILoggerMetadata>> Loggers
{
set
{
this.fooLogger = value.First(x => x.Metadata.Catagory == "foo").Value;
}
}
Run Code Online (Sandbox Code Playgroud)
我同意将元数据约束直接放在import属性中会更好,但目前在MEF中无法实现这一点.(有可能扩展MEF来做到这一点.)
另一种方法是从中导出IFooLogger接口ILogger,并在导入和导出中使用它.这很简单,与将约束放在导入中的效果基本相同.但是,如果您有多个元数据属性和/或许多可能的值,则此方法不起作用.
编辑:我巧妙地误解了你的问题; 我认为这是关于约束导入,而不是使用一些额外的参数配置导入的对象.
我认为Kathleen Dollard 最近发表的这篇文章也存在同样的问题.此外,在这篇关于组件关系的文章中,Nicholas Blumhardt将这种"参数化"关系建模为注入Func<X,Y>(或Func<ILogger,string>在您的情况下).
您可以通过[Export(typeof(Func<ILogger,string>))]直接在方法上放置属性来在MEF中执行相同操作.或者,如果您需要一个不那么模糊的合同,您可以定义一个ILoggerFactory接口并导入/导出:
public ILoggerFactory
{
ILogger Create(string category);
}
Run Code Online (Sandbox Code Playgroud)
最后,您仍然需要在代码中调用工厂.