none
MEF : Mehrere Interfaces laden RRS feed

  • Frage

  • Hallo,

    ich bin beim Debugen grad auf was gestoßen was ich mir nicht erklären kann :

     

    [ImportMany(typeof(IModule.IModule),AllowRecomposition = true)]
        private IModule.IModule[] _modules;
    
        [ImportMany(typeof (IGenericRepository.IRepository))] 
        private IGenericRepository.IRepository[] _repos;
    
        [ImportMany(typeof (IFileSearcher.IFileSearcher))]
        private IFileSearcher.IFileSearcher[] _fileSearcher;
    
        [ImportMany(typeof(IFileUploader.IFileUploader))]
        private IFileUploader.IFileUploader[] _fileUploader;
    

    Für jedes Interfaces rufe ich eine Private Mthode auf zB.

     private void LoadModuleExtensions()
        {
          var dirCatalogModules = new DirectoryCatalog("Modules");
          var container = new CompositionContainer(dirCatalogModules);
          CompositionBatch compBatch = new CompositionBatch();
          compBatch.AddPart(this);
          compBatch.AddPart(dirCatalogModules);
          container.Compose(compBatch);
        }
    

    Bei meinen FileSearchern ist das Array nach der ersten Methode gefüllt, sobald er aber danach eine MEthode zum füllend er FileUploader ausführt sind meine FileSearcher wieder leer Oo.

    Habe ich was übersehen ? 

     

    Grüße

    Montag, 21. Februar 2011 12:38

Antworten

  • Hallo Frank,

    mein Problem hat sich erledigt.

    Vorher: Ich habe in einer Klasse alle meine Parts composed (mit unterschiedlichen typen)

    Die letzte Methode in der Klasse hatte damit immer die Oberhand also zB 

    ReihenFolge ComposeFileSearcher,ComposeModules , dann war das ModuleArray nur gefüllt.

    Ich habe nun für jeden Part einen eigenen Composer somit klappt es wunderbar.

    zB :

    class RepositoryComposer:IDisposable
      {
        [ImportMany(typeof(IGenericRepository.IRepository), AllowRecomposition = true)]
        private IEnumerable<IGenericRepository.IRepository> Modules { get; set; }
    
        public List<IGenericRepository.IRepository> GetModules()
        {
          AggregateCatalog catalog = new AggregateCatalog();
          catalog.Catalogs.Add(new DirectoryCatalog("Repository"));
          CompositionContainer container = new CompositionContainer(catalog);
          container.ComposeParts(this);
          return Modules.ToList();
        }
    
        public void Dispose()
        {
          Modules = null;
        }
      }
    

     

    Grüße

    Pawel

    • Als Antwort markiert Pawel Warmuth Mittwoch, 23. Februar 2011 10:42
    Mittwoch, 23. Februar 2011 10:42

Alle Antworten

  • Hallo Pawel,

    könntest Du ein minimal reproduzierbares Projekt machen - oder halt sonst etwas eindeutiger machen?
    Es ist nicht klar, wie die Imports der anderen Module in welchen Projekten wie verbunden letztlich implementiert/deklariert sind. Auch sollte klar sein, dass wirklich die gewünschten DLLs im Verzeichnis "Modules" liegen. Dieses Modules-Verzeichnis ist (so wie Du es implementiert hast) relativ zum Basisverzeichnis der aktuellen AppDomain (AppDomain.CurrentDomain.BaseDirectory). Das "kann" in einigen Situationen problematisch sein - muß es aber natürlich nicht. Es wird zum Teil auch folgendes benutzt:

         catalog.Catalogs.Add(new DirectoryCatalog(
             Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));

    [.NET by Example: A very basic MEF sample using ImportMany]
    http://dotnetbyexample.blogspot.com/2010/04/very-basic-mef-sample-using-importmany.html

    benutzt. Ähnlich der best practice, nicht von dem aktuellen Verzeichnis (CurrentDirectory) anhängig zu sein.
    Aber gut, das ist nur ein kleiner Teil der Möglichkeiten. Mal schauen, ob Du das Szenario präzisieren kannst.


    ciao Frank
    Dienstag, 22. Februar 2011 08:23
  • Hallo Frank,

    mein Problem hat sich erledigt.

    Vorher: Ich habe in einer Klasse alle meine Parts composed (mit unterschiedlichen typen)

    Die letzte Methode in der Klasse hatte damit immer die Oberhand also zB 

    ReihenFolge ComposeFileSearcher,ComposeModules , dann war das ModuleArray nur gefüllt.

    Ich habe nun für jeden Part einen eigenen Composer somit klappt es wunderbar.

    zB :

    class RepositoryComposer:IDisposable
      {
        [ImportMany(typeof(IGenericRepository.IRepository), AllowRecomposition = true)]
        private IEnumerable<IGenericRepository.IRepository> Modules { get; set; }
    
        public List<IGenericRepository.IRepository> GetModules()
        {
          AggregateCatalog catalog = new AggregateCatalog();
          catalog.Catalogs.Add(new DirectoryCatalog("Repository"));
          CompositionContainer container = new CompositionContainer(catalog);
          container.ComposeParts(this);
          return Modules.ToList();
        }
    
        public void Dispose()
        {
          Modules = null;
        }
      }
    

     

    Grüße

    Pawel

    • Als Antwort markiert Pawel Warmuth Mittwoch, 23. Februar 2011 10:42
    Mittwoch, 23. Februar 2011 10:42