Click here to Skip to main content
15,888,301 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm using MEF as the IoC container in WPF with Caliburn.Micro framework. The MEF container resides in the Bootstrapper. Bootstrapper has the method:
C#
protected override void OnStartup(object sender, StartupEventArgs e)
{            
   DisplayRootViewFor<ViewModels.Main.MainViewModel>();
}

Now, the MainViewModel has this:
C#
private IEnumerable<ExportFactory<Screen>> _screenList { get; set; }

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

The class basically has an IEnumerable of ExportFactory. A Screen is basically a ViewModel that inherits from VMBase which in turn inherits from Screen. Now, some of those ViewModel use a Unit of Work, which, in turn, has a DbContext injected into it via the constructor.

So basically, the dependency chain is like this:
DbContext -> UnitOfWork (IDisposable) -> ViewModelBase(IDisposable) -> ViewModels.
These ViewModel are instantiated using the ExportFactory in the MainViewModel.

The MainViewModel is subscribed to the eventAggregator, and Handler of MainViewModel calls the ExportFactory to create a new instance of a ViewModel as necessary. The problem is, when that ViewModel is closed, the DbContext is not properly disposed of.

This is the Handle method:
C#
public void Handle(Type message)
{            
   DeactivateItem(ActiveItem, true);           
   ActivateItem(screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport().Value);           
}

This creates new instances of DbContext, but doesn't call Dispose() of ViewModelBase ever, as I verified using breakpoints.

How can I properly dispose of the DbContext in my application?

What I have tried:

I tried changing the Handle method to call Dispose() like this:
C#
DeactivateItem(ActiveItem, true);
_currentLifetimeContext?.Dispose();
_currentLifetimeContext = _screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport();
ActivateItem(_currentLifetimeContext.Value);

but it throws an error "The operation cannot be completed because the DbContext has been disposed." the second time I try to create a ViewModel using the ExportFactory.
Once the DbContext has been disposed, the ExportFactory cannot create any instance of ViewModel that has the DbContext injected into its constructor anymore.

I want to dispose the DbContext every time a ViewModel is closed, and when a new ViewModel is activated, create a new instance of DbContext and inject it to the ViewModel as necessary.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900