2011-02-10 1 views
1

У меня есть контроллер, который экспортируется с использованием MEF и загружается фабрикой Controller.MVC3 ImportMany по параметру конструктора для экспортированного контроллера

[Export(Controller)] 
    public class MyController : Controller 
    { 

     private IRepository MyRepsoitory; 

     [ImportMany] 
     public IEnumerable<MyImportedItem> TestImportItems {get;set;} 

     public MyController([ImportMany]IEnumberable<MyImportedItem> items, [Import]IRepository repository) 
     { 
      // items here is always null 
      // However if I grab the container that the ControllerFactory used and tell it ComposeParts on this the TestImportItems will be filled with 50+ items 
      // repository however is instantiated appropriately. 

      GlobalItems.Container.ComposeParts(this); 
      //Now TestImportItems if filled but my items parameter alway null... how do I get constructor to fill 

     } 

    } 

Так MEF создает MyController, но только создает хранилище и отправляет нуль для ImportMany, даже если он может заполнить свойство позже с таким же контейнером.

Что также странно, если я делаю что-то, что ломает один из элементов, которые создает MyConroller в ControllerFactory .. как будто он проверяет, имеет ли части для конструктора, но никогда не подталкивает их к параметру IEnumerable.

Что мне не хватает?

Очевидно, что я есть детали доступны, если же Container работает .ComposingParts на (это) (и я отражал каталог, который имеет соответствующие импорта/экспорта частей, доступных на момент создания контроллера.

Я мог бы переписать мой класс использовать наполненное свойство, но я бы очень хотел мой импортирования конструктора, чтобы получить заполненную коллекцию

UPDATE:.

Если добавить простой класс обертки для импорта многого MEF загрузит [ImportMany] параметр .

Так следующее заполнит IEnumerable для меня ...

public MyController(TestImportClass test, [Import]IRepository repository) 
{ 
    //test.Items != null 
} 

public class TestImportClass 
{ 

    public IEnumberable<MyImportedItem> Items {get;set;} 

    [ImportingConstructor] 
    public TestImportClass([ImportMany]IEnumberable<MyImportedItem> items) 
    { 
     this.Items = items; 
    } 
} 

Я использую систему «Конвенция» в моем фактическом коде, чтобы отметить контроллер для экспорта. Может быть, по какой-то причине MEF не понимает импорт в исходном параметре конструктора? Если это так, хотя я не уверен, почему мой IRepository всегда заполняется?

+0

Интересно ... Если изменить параметр на мой контроллер Конструктора из ImportMany IEnumerable <...> к простому классу интерфейса с конструктором, который принимает в параметре ImportMany он работает. По какой-то причине MEF не хочет заполнять параметр ImportMany на моем конструкторе Contoller, но будет делать это на один уровень вниз по цепочке. – Andy

ответ

0

Когда вы вызываете ComposeParts, вы передаете объекты, которые уже были построены. Невозможно вызвать конструктор снова на существующий объект. (И в этом случае, если вы это сделали, вы закончите бесконечную рекурсию). Поэтому ComposeParts не удовлетворяет импорту конструктора.

Если ваш контроллер вытащил из контейнера каким-либо другим способом, и вы введете ImportStructorAttribute в конструктор, импорт конструктора должен быть выполнен.

+0

Я только делаю ComposeParts (вызывающий пост), чтобы показать, что я могу заполнить свойство IEnumerable. Однако сам контроллер загружается из того же контейнера, который я называю ComposeParts (this) on. IRepository действительно получает экземпляр в конструкторе, а не параметр IEnumerable . Это моя проблема. Также я проверил код, добавляющий атрибут [ImportingConstructor] вместе с ImportMany в параметре, но все же не создавал экземпляр IEnumerable. – Andy

0

Возможно, система конвенций, которую вы используете, не поддерживает ImportMany в аргументах конструктора. Предположительно, соглашение не применяется к TestImportClass, поэтому ImportMany работает над этим конструктором.

Мы планируем иметь официальную поддержку условной модели в следующей версии MEF, и мы должны скоро отправить новый выпуск кода с предварительным просмотром этой поддержки.

Смежные вопросы