2013-03-02 3 views
2

У меня есть импорт, который не работает - объект имеет значение null. Первоначально это был ImportMany, но я упростил его до импорта, чтобы попытаться определить проблему, но мне это не удалось.MEF Import is null

Я прошел через этот сайт, и Google, и затем основные идеи:

  • Не экземпляр класса самостоятельно, пусть MEF сделать это, иначе называют container.getExport() - до сих пор не work
  • Поместите [Export] в класс, содержащий свойство [Import], иначе он не будет выбран в качестве части процесса составления контейнера (подтвержденный при отладке).

Мой код настройки выглядит следующим образом (упрощенно ради компактности):

Ассамблеи1

public class MyBootstrapper 
{ 
    //Automatically called by ExcelDna library, I do not instantiate this class 
    public void AutoOpen() 
    { 
     var ac1 = new AssemblyCatalog(typeof(XLHandler).Assembly); 
     var ac2 = new AssemblyCatalog(typeof(MyComponent).Assembly); 

     var agc = new AggregateCatalog(); 
     agc.Catalogs.Add(ac1); 
     agc.Catalogs.Add(ac2); 

     var cc = new CompositionContainer(agc); 

     try 
     { 
      cc.ComposeParts(this); 
     } 
     catch (CompositionException exception) {} 
    } 
} 

[Export] 
public class XLHandler 
{ 
    [Import(typeof(IMyComponent))] 
    public IMyComponent _component; 

    public void SomeMethod() 
    { 
     //try to use _component but it is null 
    } 
} 

Assembly2

public interface IMyComponent 
{ 
    //stuff... 
} 

Ассамблеей3

[Export(typeof(IMyComponent)] 
public MyComponent : IMyComponent 
{ 
    //more stuff... 
} 

Кто-нибудь знает/есть идея, почему переменная _component в XLHandler не вводится в в MEF контейнера?

Нужно ли мне экспортировать/создавать AssemblyCatalog для интерфейса в Assembly2?

+0

Не уверен в этом, но атрибут импорта не должен быть '[Import (typeof (IMycomponent))]'? –

+0

Да, вы экспортируете как 'IMyComponent', поэтому вы также должны импортировать его. Вы можете удалить определение типаof из импорта, потому что ваш тип переменной уже IMyComponent. – ChrisO

+0

Yup, это была опечатка в Q. Я исправлю это. – clicky

ответ

7

При импорте деталей вы можете использовать атрибут [Import] в свойстве Property или запросить его как часть конструктора и использовать атрибут [ImportingConstructor].

Любая часть импортируется с помощью атрибута [Import] не будут доступны в конструкторе класса

Так что в вашем случае измените XLHandler класс как это:

[Export] 
public class XLHandler 
{ 
    [ImportingConstructor] 
    public void SomeMethod(MyComponent component) 
    { 
     _component = component; 
     // You can use _component, since it has already been resolved... 
    } 
} 
+0

Тогда в чем смысл [Импорт] - извините, я не понимаю его. Как я могу непосредственно вводить переменную property/class? – clicky

+1

'[Import]' может использоваться всякий раз, когда вам не нужна эта часть, разрешенная немедленно в конструкторе. Он будет разрешен через некоторое время, после завершения конструктора и времени, когда вы вызываете какое-либо свойство/метод этого экземпляра. – Blachshma

+0

Итак, я изменил переменную класса как свойство (добавлено {get; set;}), но все равно null. В идеале я не хочу передавать переменную в качестве параметра метода, поэтому все еще озадачен тем, почему [Import] не вводит Свойство. – clicky

2

В MyBootstrapper.AutoOpen вам необходимо заменить:

cc.ComposeParts(this); 

что-то вроде:

var handler = new XLHandler(); 
cc.ComposeParts(handler); 

или:

var handler = cc.GetExportedValue<XLHandler>(); 

Вы не можете создавать части MyBootstrapper, так как он не имеет импорта. ComposeParts ничего не делает.

Другой подход заключается в добавлении импорта в MyBootstrapper. Нравится:

public class MyBootstrapper 
{ 
    [Import] 
    XLHandler XLHandler; 

    //Automatically called by ExcelDna library, I do not instantiate this class 
    public void AutoOpen() 
    { 
     //Leave your implementation unchanged. 
    } 
} 

К сожалению, MyComponent не компилируется.

+0

Cheers. Я фактически использовал комбо из обоих ответов, но не уверен, как принять оба. Поднялись оба. – clicky

+0

@Murtuza проблем нет. Благодарю. –