Sabyasachi Mukherjee Ответов: 0

Использовать MEF, чтобы правильно распорядиться DbContext можно


Я использую MEF в качестве контейнера IoC в WPF с Caliburn.Микро-фреймворк. Контейнер MEF находится в загрузчике. Загрузчик имеет метод:
protected override void OnStartup(object sender, StartupEventArgs e)
{            
   DisplayRootViewFor<ViewModels.Main.MainViewModel>();
}

Сейчас, в MainViewModel это:
private IEnumerable<ExportFactory<Screen>> _screenList { get; set; }

[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator, [ImportMany] IEnumerable<ExportFactory<Screen>> screenList)
{
    _screenList = screenList;
    eventAggregator = eventAggregator;
    _eventAggregator.Subscribe(this);        
}

Класс в основном имеет IEnumerable ExportFactory. Экран-это в основном ViewModel, который наследуется от VMBase, которая, в свою очередь, наследуется от Screen. Теперь некоторые из этих ViewModel используют единицу работы, которая, в свою очередь, имеет DbContext, введенный в нее через конструктор.

Таким образом, в основном цепочка зависимостей выглядит следующим образом:
DbContext -> UnitOfWork (IDisposable) -> ViewModelBase(IDisposable) -> ViewModels.
Эти ViewModel создаются с помощью ExportFactory в MainViewModel.

MainViewModel подписывается на eventAggregator, и обработчик MainViewModel вызывает ExportFactory для создания нового экземпляра ViewModel по мере необходимости. Проблема в том, что когда эта ViewModel закрыта, DbContext не утилизируется должным образом.

Это способ обработки :
public void Handle(Type message)
{            
   DeactivateItem(ActiveItem, true);           
   ActivateItem(screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport().Value);           
}

Это создает новые экземпляры DbContext, но никогда не вызывает Dispose() ViewModelBase, как я проверил с помощью точек останова.

Как я могу правильно распорядиться DbContext в моем приложении?

Что я уже пробовал:

Я попытался изменить метод дескриптора, чтобы вызвать Dispose() следующим образом:
DeactivateItem(ActiveItem, true);
_currentLifetimeContext?.Dispose();
_currentLifetimeContext = _screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport();
ActivateItem(_currentLifetimeContext.Value);

но он выдает ошибку "операция не может быть завершена, потому что DbContext был удален". во второй раз я пытаюсь создать ViewModel с помощью ExportFactory.
После того, как DbContext был удален, ExportFactory больше не может создавать экземпляр ViewModel, который имеет DbContext, введенный в его конструктор.

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

0 Ответов