+ 1的问题 - 自从4.5出来以后,我没有机会看看MEF,所以它迫使我赶上新增的RegistrationBuilder
课程!
我猜你的例子不起作用的原因是因为据我了解,RegistrationBuilder
被设计来取代MEF依赖于如此严重到.NET 4.0的属性角色。 ExportMetadataAttribute
是老办法的一部分,这只是我的猜测,新旧不兼容。
由于加入RegistrationBuilder
就可以达到你想要什么,而无需他们正在使用MEF建立的任何知识导出类。在我看来,这是MEF从4.0的巨大改进。
首先让我们从我们想要导出的类开始。首先,我定义MyMetadataAttribute
类,它封装相关联的,我们将要过滤的类型的元数据:那我可能要出口
public enum MyClassType
{
TypeOne,
TypeTwo
}
[AttributeUsage(AttributeTargets.Class)]
public class MyMetadataAttribute: Attribute
{
public MyMetadataAttribute(MyClassType type)
{
Type = type;
}
public MyClassType Type { get; private set; }
}
现在想来类:
public interface IClass
{
}
[MyMetadata(MyClassType.TypeOne)]
public class MyClassA : IClass
{
public MyClassType Type
{
get { return MyClassType.TypeOne; }
}
}
[MyMetadata(MyClassType.TypeTwo)]
public class MyClassB : IClass
{
public MyClassType Type
{
get { return MyClassType.TypeTwo; }
}
}
的解决问题的关键是RegistrationBuilder
上的ForTypesMatching()
方法。参数是一个谓词,它接受该类型并根据是否要将类型包含在导出结果中返回true或false。下面的代码演示了这样一个例子:
internal class Program
{
private static void Main(string[] args)
{
var registrationBuilder = new RegistrationBuilder();
registrationBuilder
.ForTypesMatching<IClass>(t => FilterOnMetadata(t, MyClassType.TypeOne))
.ExportInterfaces();
var assemblyCatalog = new AssemblyCatalog(typeof (MyClassType).Assembly, registrationBuilder);
var compositionContainer = new CompositionContainer(assemblyCatalog);
var ic = new TestImportContainer();
compositionContainer.ComposeParts(ic);
var count = ic.ImportedParts.Count();
}
public static bool FilterOnMetadata(Type t, MyClassType classType)
{
var metadataAttribute =
(MyMetadataAttribute) t.GetCustomAttributes(true)
.SingleOrDefault(at => at is MyMetadataAttribute);
if (metadataAttribute != null)
return metadataAttribute.Type == classType;
return false;
}
private sealed class TestImportContainer
{
[ImportMany(typeof(IClass))]
public IEnumerable<IClass> ImportedParts { get; set; }
}
}
现货!非常感谢你。一个问题想到,Export和ExportInterface有什么区别? – clicky
假设你有一个'T'类来实现'IIntefaceOne'和'IInterfaceTwo'。用'Export()'配置这个类将匹配'T'类型的输入。使用'Export'将匹配那个类和'IIntefaceOne'类型的输入。使用'ExportInterfaces()'将匹配'IIntefaceOne'和'IInterfaceTwo'类型的导入。这个评论可能没有很好的解释它。有一篇很棒的文章[这里](http://msdn.microsoft.com/en-us/magazine/jj133818.aspx),我发现它非常有用。 –
Lawrence