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.
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.
From what I understand, if I were to call
_container.ComposeParts(this);
…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
}
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.
In order to satisfy the requirements, I created 3 classes:
The
CompositionFactoryinitializes MEF to discover theAssemblyProvider. When the provider initializes:…we return a
CatalogExportProvider. I can now use an API to the CompositionFactory:…to query for the correct composable part using a contract name:
The work is then completed in the ComposableAggregate helper class: