2012-02-01 1 views
0

У меня возникла проблема при получении информации из импортированного атрибута. Атрибут остается нулевым после вызова .ComposeParts(), но композиция в порядке, потому что после этого я могу вызвать .GetExportedValues ​​() и получить необходимый экземпляр. Вот код:Вложение свойств MEF не происходит

Bootstrapper делает композицию

[Export] 
public class Bootstrapper 
{ 
    public void Run() 
    { 
     doComposition(); 
    } 

    private void doComposition() 
    { 
     var catalog = new AggregateCatalog(); 

     catalog.Catalogs.Add(new DirectoryCatalog("./Applications")); 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(Loader).Assembly)); 

     Container = new CompositionContainer(catalog); 
     // Apps = Container.GetExportedValues<IApplication>(); - this gets me the IApplication(s), but I dont understand why Apps isn't injected automatically 
     Container.ComposeParts(catalog); 
     IEnumerable<IApplication> app = Container.GetExportedValues<IApplication>(); 
    } 

    public CompositionContainer Container { get; set; } 

    private IEnumerable<IApplication> apps; 

    [ImportMany(typeof(IApplication))] 
    public IEnumerable<IApplication> Apps 
    { 
     get { return apps; } 
     set 
     { 
      apps = value; 
     } 
    } 

Подпись одного из классов, реализующих IApplication

[Export(typeof(IApplication))] 
public class MDFApplication : IApplication {...} 

Все указатели оценили, спасибо много.

ответ

2

Вы никогда не вызываете код, чтобы составить класс Bootstrapper. ComposeParts создаст каталог, он не будет создавать или составлять какие-либо классы, пока вы их не попросите.

Контейнер не ищет всех участников, которым требуется импорт, когда вы вызываете GetExportedValues. Он либо возвращает уже существующий экземпляр, либо создает новый, удовлетворяющий всем его атрибутам импорта.

Другими словами, следующий код будет возвращать полностью сконструированный Bootstraper класс:

 var b= Container.GetExportedValue<Bootstrapper>(); 
     Debug.Assert(b.Apps!=null);    

Чтобы составить объект, который уже существует, необходимо вызвать метод SatisfyImportsOnce. Это найдет все импорт и удовлетворит их, если это возможно. Например.

 Container.SatisfyImportsOnce(this); 
     Debug.Assert(this.Apps != null);