Если вы подаете команду/обработчик и шаблоны запросов/обработчиков, как описано here и here, наиболее логичным, что нужно сделать, чтобы объем время жизни DbContext
вокруг выполнения команды и запроса.
Это может быть достигнуто путем определения одного общего декоратор, что позволяет применять обзорное:
using SimpleInjector;
using SimpleInjector.Extensions.LifetimeScoping;
public class LifetimeScopedCommandHandlerDecorator<T> : ICommandHandler<T>
{
private readonly Container container;
private readonly Func<ICommandHandler<T>> decorateeProvider;
public LifetimeScopedCommandHandlerDecorator(Container container,
Func<ICommandHandler<T>> decorateeProvider) {
this.container = container;
this.decorateeProvider = decorateeProvider;
}
public void Handle(T command) {
using (container.BeginLifetimeScope()) {
this.decorateeProvider().Handle(command);
}
}
}
Этот декоратор может быть зарегистрирован в качестве последнего декоратора следующим образом:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(LifetimeScopedCommandHandlerDecorator<>),
Lifestyle.Singleton);
После этого, вы можете зарегистрируйте свой DbContext
, используя LifetimeScopeLifestyle
.
Вы можете сделать тот же трюк с обработчиками запросов.
Огромное преимущество этого заключается в том, что вы позволяете вашей силе строго изолировать обработчики команд и обработчики запросов, сводя к минимуму риск влияния друг на друга через общий DbContext
, и это облегчает перенос ваших обработчиков на другой уровня, отправив команду и запросить сообщения по проводу, как объяснено here.
Спасибо Стивен, да, эти статьи вдохновили меня на реорганизацию моей архитектуры. Я хотел бы также вызвать GetInstance() в другом месте и все равно получить тот же экземпляр, например, в WPF ValueConverter, чтобы получить текущий DbContext из реального ViewModel с намерением изменить цвет строк DataGrid на основе состояния текущих записей (Добавлено, Модифицировано, Удалено и т. Д.). –
Я думаю, мне нужен какой-то определенный образ жизни: во время создания ViewModel контейнер должен рассматривать DbContext как Transient, но после его создания он должен вести себя как singleton (каждый вызов GetInstance будет возвращать один и тот же экземпляр) до тех пор, пока ViewModel жив. В вашем примере область ограничена созданием определенных обработчиков, я думаю, поэтому все ваши декораторы получат один и тот же экземпляр. Но мне нужно, чтобы такое поведение было также недоступным для обработчиков. Это возможно? –
Мой совет - подойти к вашей проблеме по-другому. Если вы используете команды и запросы, только обработчики команд и запросов должны использовать DbContext. Поэтому переместите операцию, которая получает цвет в обработчик запроса, и вставьте обработчик запроса в исходный класс. Проблема решена – Steven