基于这个问题的答案CompositionBatch 和目录有什么区别?这表明组合批处理的使用在对象由其他组件构建的情况下很有用。这让我想,它适用于哪些现实生活中的例子?然后我开始思考那些你无法控制的构建对象。如果您无法添加未标记为导出的部件,您将如何将这些实例添加到容器中?唯一想到的是使用所需类型的成员设置一个类并将其标记为导出。
如果实例未标记为导出,是否可以将实例添加到容器中?
基于这个问题的答案CompositionBatch 和目录有什么区别?这表明组合批处理的使用在对象由其他组件构建的情况下很有用。这让我想,它适用于哪些现实生活中的例子?然后我开始思考那些你无法控制的构建对象。如果您无法添加未标记为导出的部件,您将如何将这些实例添加到容器中?唯一想到的是使用所需类型的成员设置一个类并将其标记为导出。
如果实例未标记为导出,是否可以将实例添加到容器中?
我将假设您的意思是“未标记为导出的类”而不是“实例”。
对于 .NET4.5 及更高版本,您可以使用MEF 的约定模型。
对于 .NET4,Mark Seemann 在博客中介绍了如何巧妙地利用泛型和属性导出来导出现有类型。您可以像这样创建一个类:
public class MefAdapter<T> where T : new()
{
private readonly T export;
public MefAdapter()
{
this.export = new T();
}
[Export]
public virtual T Export
{
get { return this.export; }
}
}
然后您可以构造一个类型目录来导出不支持 MEF 的现有类型,如下所示:
var catalog = new TypeCatalog(
typeof(MefAdapter<Foo>),
typeof(MefAdapter<Bar>),
...);
您可以修改此示例以添加对具有构造函数参数的类型的支持、导出接口而不仅仅是类类型等。
您需要创建自己的目录。这不是一件容易的事,但这是一个例子 (我自己没有使用过。我可以用InheritedExport解决我的类似问题)
如果链接失效,我在这里重复代码。
public class ConventionalCatalog : ComposablePartCatalog {
private List<ComposablePartDefinition> _parts = new List<ComposablePartDefinition>();
public void RegisterType<TImplementation, TContract>() {
var part = ReflectionModelServices.CreatePartDefinition(new Lazy<Type>(() => typeof(TImplementation)),
false,
new Lazy<IEnumerable<ImportDefinition>>(() => GetImportDefinitions(typeof(TImplementation))),
new Lazy<IEnumerable<ExportDefinition>>(() => GetExportDefinitions(typeof(TImplementation), typeof(TContract))),
new Lazy<IDictionary<string, object>>(() => new Dictionary<string, object>()),
null);
_parts.Add(part);
}
private ImportDefinition[] GetImportDefinitions(Type implementationType) {
var constructors = implementationType.GetConstructors()[0];
var imports = new List<ImportDefinition>();
foreach (var param in constructors.GetParameters()) {
imports.Add(ReflectionModelServices.CreateImportDefinition(
new Lazy<ParameterInfo>(() => param),
AttributedModelServices.GetContractName(param.ParameterType),
AttributedModelServices.GetTypeIdentity(param.ParameterType),
Enumerable.Empty<KeyValuePair<string,Type>>(),
ImportCardinality.ExactlyOne,
CreationPolicy.Any,
null));
}
return imports.ToArray();
}
private ExportDefinition[] GetExportDefinitions(Type implementationType, Type contractType) {
var lazyMember = new LazyMemberInfo(implementationType);
var contracName = AttributedModelServices.GetContractName(contractType);
var metadata = new Lazy<IDictionary<string, object>>(() => {
var md = new Dictionary<string, object>();
md.Add(CompositionConstants.ExportTypeIdentityMetadataName,
AttributedModelServices.GetTypeIdentity(contractType));
return md;
});
return new ExportDefinition[] {
ReflectionModelServices.CreateExportDefinition(lazyMember, contracName, metadata, null)
};
}
public override IQueryable<ComposablePartDefinition> Parts {
get { return _parts.AsQueryable(); }
}
}
像这样使用它:
using (var myCatalog = new ConventionalCatalog()) {
myCatalog.RegisterType<MyClass, IMyClass>();
using (var container = new CompositionContainer(myCatalog)) {
container.ComposeParts(this);
...
}
}