Подтвердить что ты не робот

Автозаводы и фабрики Func

Я работаю над приложением с использованием Caliburn.Micro и Autofac.

В моем составе root я столкнулся с проблемой с Autofac: Я должен добавить глобально используемый IEventAggregator в свой FirstViewModel и второй IEventAggregator, который должен использоваться только этим FirstViewModel и его дочерними элементами.

Моя идея состояла в том, чтобы сделать второй, который был введен как Owned<IEA>, и он работает, контейнер предоставляет другой экземпляр IEA.

public FirstViewModel(
    IEventAggregator globalEA,
    IEventAggregator localEA,
    Func<IEventAggregator, SecondViewModel> secVMFactory) {}

Проблема возникает, когда я должен предоставить агрегаторы событий в SecondViewModel.

Чтобы создать SecondViewModel, я использую метод factory как Func<IEA, SecondVM>. Конструктор SecondViewModel выглядит следующим образом:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}

Я хочу, чтобы контейнер вводил первый как зарегистрированный, а второй - параметр IEA Func<IEA, SecVM>.

это функция, которую я зарегистрировал в контейнере:

builder.Register<Func<IEventAggregator, SecondViewModel>>(
     c =>
         (ea) =>
         {
             return new SecondViewModel(
                 c.Resolve<IEventAggregator>(),
                 ea);
         }
);

но когда он вызывается FirstViewModel, я получаю следующую ошибку:

Исключение типа "System.ObjectDisposedException" произошло в Autofac.dll, но не было обработано в коде пользователя

Дополнительная информация: эта операция разрешения уже завершена. При регистрации компонентов с использованием лямбда параметр IComponentContext 'c' для лямбда не может быть сохранен. Вместо этого либо разрешите IComponentContext снова с 'c', либо разрешите factory на основе Func < > для создания следующих компонентов.

Я не могу понять, где проблема, можете ли вы мне помочь, что мне не хватает?

Спасибо.

4b9b3361

Ответ 1

Вы вызываете secVMFactory вне вашего конструктора FirstViewModel, поэтому к этому времени утилита ResolveOperation будет удалена, а в вашем методе factory c.Resolve будет генерировать исключение.

К счастью, сообщение об исключении очень описательно и говорит вам, что делать:

При регистрации компонентов, использующих lambdas, IComponentContext 'c' параметр лямбда не может быть сохранен. Вместо этого либо разрешите IComponentContext снова из 'c'

Поэтому вместо вызова c.Resolve вам нужно разрешить IComponentContext из c и использовать его в factory func:

builder.Register<Func<IEventAggregator, SecondViewModel>>(c => {
     var context = c.Resolve<IComponentContext>();
     return ea => { 
          return new SecondViewModel(context.Resolve<IEventAggregator>(), ea); 
     };
});