MVC3 ImportMany на конструкторе Параметр для экспортируемого контроллера - PullRequest
1 голос
/ 10 февраля 2011

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

    [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.

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

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

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

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 всегда заполняется?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2011

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

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

0 голосов
/ 10 февраля 2011

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

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

...