Автозаводы и фабрики 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 < > для создания следующих компонентов.
Я не могу понять, где проблема, можете ли вы мне помочь, что мне не хватает?
Спасибо.
Ответы
Ответ 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);
};
});