How to manage discovery and composition as 2 separate concerns?

后端 未结 2 1840
野的像风
野的像风 2021-01-27 09:52

I have set up an assembly catalog:

  private CompositionContainer GetContainer() {
     // initialize directory info
     ExtensionDirectory = new DirectoryInfo(         


        
2条回答
  •  半阙折子戏
    2021-01-27 10:26

    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 { }
    

    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);
    }
    

    ...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();
    }
    

    The work is then completed in the ComposableAggregate helper class:

    internal ISomething Value {
       get {
          return _container.GetExport(_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();
    }
    

提交回复
热议问题