我已经建立了一个组装目录:
I have set up an assembly catalog:
private CompositionContainer GetContainer() {
// initialize directory info
ExtensionDirectory = new DirectoryInfo(settings.ExtensionsPath);
// directory catalog
var dirCatalog = new DirectoryCatalog(ExtensionDirectory.FullName);
return new CompositionContainer(dirCatalog);
}
容器中的内容将加载在该目录中的所有组件预期。我并不想真正构成任何事情,因为我将与依赖注入的构造函数。
The contents of the container will load up all the assemblies in the directory as expected. I do not want to actually compose anything yet because I have constructors that will be injected with dependencies.
我想要做的就是使用 AssemblyCatalog
作为存储库;查询具体的出口,通过构造函数依赖,然后撰写的只有的参与这一过程的部分。
What I want to do is use the AssemblyCatalog
as a repository; query for a specific export, pass the constructor dependency, then compose only the parts involved in this process.
据我了解,如果我叫
_container.ComposeParts(this);
...无需提供出口的 [ImportingConstructor]
S,那么所有的部件将被列入 _container
。
...without providing exports for the [ImportingConstructor]
s, then none of the parts would be included in the _container
.
为了便于查询到容器上,我有一个方法,如下所示:
In order to facilitate queries to the container, I have a method as follows:
public Lazy<IEntity> GetPart(Func<Lazy<IEntity, IEntityMetaData>, bool> selector) {
var entity = _container.GetExports<IEntity, IEntityMetaData>()
.Where(selector)
.Select(e => e as Lazy<IEntity>)
.FirstOrDefault();
return entity; // this will be passed up to the composition service
}
看来, GetExports&LT; T,M&GT;()
将不会返回包含出口的 [ImportingConstructor]
如果这将满足依赖性的部分不包括在容器
It seems that GetExports<T, M>()
will not return an export containing an [ImportingConstructor]
if the part which would satisfy the dependency is not included in the container.
我的做法是有一个支线集装箱/目录中处于较低水平;更高层次的组合服务将接收所有部件和组成最终目标。我决定在这个办法,所以我们就可以添加/扩展类型,将来可用目录中。
My approach is to have an extension container/catalog at a low level; a higher level composition service will receive all parts and compose the final object. I decided on this approach so we would be able to add/extend the types of catalogs available in the future.
为了满足需求,我创建了3类:
In order to satisfy the requirements, I created 3 classes:
public sealed class CompositionFactory {
[Import("Provider")]
private IProvider importProvider;
/* MEF initialization */
}
[Export("Provider")]
public sealed class AssemblyProvider : IProvider {
private CatalogExportProvider _provider;
}
internal sealed class ComposableAggregate { }
在 CompositionFactory
初始化MEF发现的 AssemblyProvider
。当提供初始化:
The CompositionFactory
initializes MEF to discover the AssemblyProvider
. When the provider initializes:
private CatalogExportProvider InitializeProvider() {
// directory catalog
var dirCatalog = new DirectoryCatalog(ExtensionDirectory.FullName);
return new CatalogExportProvider(dirCatalog);
}
...我们返回一个 CatalogExportProvider
。我现在可以使用API将CompositionFactory:
...we return a CatalogExportProvider
. I can now use an API to the CompositionFactory:
public ISomething GetSomething(string ContractName, object ContractParam) {
// implementation
}
...来查询使用合同名称的正确组合的一部分:
...to query for the correct composable part using a contract name:
public ComposablePartDefinition GetPartDefinition(string ContractName) {
return _provider.Catalog.Parts
.Where(p => p.ExportDefinitions
.Select(e => e.ContractName)
.Any(c => c == ContractName))
.FirstOrDefault();
}
这项工作,然后在ComposableAggregate辅助类完成的:
The work is then completed in the ComposableAggregate helper class:
internal ISomething Value {
get {
return _container.GetExport<IEntity>(_contractName).Value;
}
}
private CompositionBatch CreateBatch() {
CompositionBatch batch = new CompositionBatch();
// create composable part from definition
ComposablePart importDef = CreatePart(_contractName);
batch.AddPart(importDef);
return batch;
}
private ComposablePart CreatePart(string ContractName) {
// get part definition from catalog
return _provider.GetPartDefinition(ContractName).CreatePart();
}