2010-09-02 9 views
5

Próbuję to zrozumieć przez kilka dni, bez powodzenia.ImportMany z metadanymi nie importującymi

Próbuję użyć [ImportMany] do zaimportowania z katalogu pełnego bibliotek DLL z eksportami typu IEditorSystem, które mają niestandardowy metadane typu IEditorSystemMetadata. Chciałbym najpierw pobrać metadane i wypchnąć je do niektórych pól tekstowych itp., Aby użytkownik mógł wybrać, który system EditorSystem ma użyć, a po wybraniu załadować ten system ...

Podążałem za przykładami jak najlepiej jak tylko mogę, oto, co mam do tej pory.

[ImportMany] 
public ObservableCollection<Lazy<IEditorSystem, IEditorSystemMetadata>> EditorSystemList 

To jest to, co powinno być importowania:

[Export(typeof(IEditorSystem))] 
    [SignalSystemData("Very Very Long Name", "Short Name")] 
    public class MyEditorSystem: IEditorSystem 
    { 
     public MyEditorSystem() 
     { 
     } 
    } 

i uruchamiania:

AggregateCatalog Catalog = new AggregateCatalog(
       new DirectoryCatalog(@".\EditorSystems"), 
       new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
      CompositionContainer Container = new CompositionContainer(Catalog); 
      Container.ComposeParts(this); 

widzę w Catalog.Parts zarówno MyEditorSystem i ViewModel, które ma ImportMany, ale program EditorSystemList nigdy nie zostanie zapełniony. Nie otrzymuję błędów składu.

Pomyślałem, że może to mieć coś wspólnego z leniwym <>, więc próbowałem

public ObservableCollection<IEditorSystem> EditorSystemList 

No szczęście albo.

Jedyną komplikacją, o jakiej mogę myśleć, jest to, że używam Cinch, który używa MEFedMVVM, który również używa MEF. Nie myślę, że to przeszkadza, ale nie jestem pewien.

Myślę, że robię to źle, czy ktokolwiek może to zrozumieć?

Aktualizacja:

Wdrożenie nowego IComposer, z dokładnie tego katalogu trzeba.

ImportMany nadal nie działa, ale tylko wtedy, gdy próbuję zaimportować z niego metadane. Metadane to tylko kilka ciągów i, o ile jestem w stanie to ustalić, podążam za przykładami.

W KOŃCU znaleziono przyczynę: Implementacje IEditorSystem znajdują się w oddzielnej bibliotece DLL, jak wspomniano wcześniej. Jednak wszystkie nowe kompilacje biblioteki dll nie są kopiowane do wyjściowego podrejestru głównego projektu. Skopiowałem pierwszy ręcznie i zapomniałem dodać kopię post-build do projektu dll. No cóż, nauczyłem się kilka rzeczy o MEF, więc nie całkowicie zmarnowane dni :)

Odpowiedz

1

Nie widząc swój kod, wierzę, wszystko, co trzeba zmienić to

public ObservableCollection<Lazy<IEditorSystem, IEditorSystemMetadata>> EditorSystemList 

powinny być

public IEnumerable<Lazy<IEditorSystem, IEditorSystemMetadata>> EditorSystemList; 

Oto przykład:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var c = new Class1(); 
     var v = c.EditorSystemList; 
     foreach (var lazy in v) 
     { 
      if (lazy.Metadata.LongName == "Very Very Long Name") 
      { 
       var v2 = lazy.Value; 
       // v2 is the instance of MyEditorSystem 
      } 
     } 
    } 
} 

public class Class1 
{ 
    [ImportMany] 
    public IEnumerable<Lazy<IEditorSystem, IEditorSystemMetadata>> EditorSystemList; 

    public Class1() 
    { 
     var catalog = new AggregateCatalog(
      new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 
    } 
} 

[Export(typeof(IEditorSystem))] 
[SignalSystemData("Very Very Long Name", "Short Name")] 
public class MyEditorSystem : IEditorSystem { } 

public interface IEditorSystem { } 

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
public class SignalSystemDataAttribute : ExportAttribute 
{ 
    public SignalSystemDataAttribute(string longName, string shortName) 
     : base(typeof(IEditorSystem)) 
    { 
     LongName = longName; 
     ShortName = shortName; 
    } 
    public string LongName { get; set; } 
    public string ShortName { get; set; } 
} 

public interface IEditorSystemMetadata 
{ 
    string LongName { get; } 
    string ShortName { get; } 
} 
+0

Zmieniłem go na IEnumerable, ale import nigdy nie wydaje się gotowy, EditorSystemList pozostaje w [0] ... – Kage

+0

Czy próbowałeś uruchomić dokładny kod z góry? powinieneś być w stanie stworzyć aplikację Console, aby to sprawdzić. – JoshVarga

+0

Tak, konsola działa, ale wygląda na to, że może to być spowodowane tym, że MEFedMVVM zepsuł wszystko, zaktualizuje – Kage

0

Może mój rozwiązanie rozwiązuje również twój problem.

Ciężko pracowałem, próbując odkryć problem.

potem mam następujące rozwiązanie:

interfejs Metadane powinny zawierać tylko jeden obiekt tego samego typu:

int, bool, string itd Jeśli umieścisz dwie właściwości int, na przykład, ImportMany<Lazy<t,m>> nie będzie działał i zawsze będzie zwracał 0.

dla każdej właściwości interfejsu, należy umieścić atrybut ExportMetadata w wyeksportowanej klasie na.

np

public interface IMyExportMetadata 
{ 
    int a {get;} 
    string b {get;} 
    bool c {get;} 
} 

[Export(typeof(IMyInterface)) 
[ExportMetadata("a", 0)] 
[ExportMetadata("b", "string")] 
[ExportMetadata("c", true)] 
public class myExportedClass: IMyInterface 
{ 
} 
1

Może moje rozwiązanie rozwiązuje problem zbyt.

Ciężko pracowałem, próbując odkryć problem.

potem mam następujące rozwiązanie:

interfejs Metadane powinny zawierać tylko jeden obiekt tego samego typu:

int, bool, sznurka, itd. Jeśli umieścisz dwie właściwości Int, na przykład, funkcja ImportMany> nie będzie działać i zawsze będzie zwracać 0.

dla każdej właściwości interfejsu, należy umieścić atrybut ExportMetadata w wyeksportowanej klasie na.

np

public interface IMyExportMetadata { int a {get;} ciąg b {get; } BOOL c {get;} }

[eksportowego (typeof (IMyInterface)) [ExportMetadata ("a", 0)] [ExportMetadata ("B", "łańcuch")] [ExportMetadata ("c", true)] myExportedClass public class: IMyInterface { }

pracować z wieloma logicznych, na przykład, należy utworzyć atrybut niestandardowy eksportowej wdrożenie interfejsu metadanych takiego:

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] 
public class ExportUserPartAttribute : ExportAttribute, IUserPartMetadata 
{ 
    #region Implementation of IUserPartMetadata 

    public int TipoPart { get; set; } 
    public string Regiao { get; set; } 
    public bool IsLogin { get; set; } 
    public bool IsMenu { get; set; } 
    public bool IsHome { get; set; } 
    public bool IsListagem { get; set; } 
    public bool IsFormulario { get; set; } 

    #endregion 

    public ExportUserPartAttribute() 
     : base(typeof(IUserPart)) 
    { 

    } 

    /* 
    public ExportUserPartAttribute(int tipoPart, string regiao) 
     : base(typeof(IUserPart)) 
    { 
     this.TipoPart = tipoPart; 
     this.Regiao = regiao; 
    } 
    */ 
} 
Powiązane problemy