MEF ExportFactory不会处理IDisposable ViewModels

时间:2017-05-21 14:42:16

标签: c# wpf mef dispose idisposable

我在使用Caliburn.Micro框架的WPF中使用MEF作为IoC容器。 MEF容器位于BootstrapperBootstrapper的方法有:

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 ExportFactoryScreen基本上是ViewModel,继承自VMBaseScreen继承自ViewModel。现在,其中一些DbContext使用工作单元,而工作单元又通过constructor注入了DbContext -> UnitOfWork (IDisposable) -> ViewModelBase(IDisposable) -> ViewModels

所以基本上,依赖链是这样的: ViewModel。这些ExportFactory使用MainViewModel中的MainViewModel进行实例化。

eventAggregator订阅Handler,而MainViewModel ExportFactory调用ViewModel来创建ViewModel的新实例有必要的。问题是,当DbContext关闭时,Handle未正确处理。

这是public void Handle(Type message) { DeactivateItem(ActiveItem, true); ActivateItem(screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport().Value); } 方法:

DbContext

这会创建Dispose()的新实例,但不会调用ViewModelBase的{​​{1}},因为我使用断点进行了验证。

我尝试更改Handle方法,以便像这样调用Dispose()

DeactivateItem(ActiveItem, true);
_currentLifetimeContext?.Dispose();
_currentLifetimeContext = _screenList.FirstOrDefault(c => c.CreateExport().Value.GetType() == message).CreateExport();
ActivateItem(_currentLifetimeContext.Value);

但它会抛出一个错误“无法完成操作,因为已经处理了DbContext。”

如何在我的应用程序中正确处理DbContext

1 个答案:

答案 0 :(得分:1)

几乎不可能在没有完整测试的情况下说明代码失败的原因。但是,由于我对MEF的经验有限,我发现当导出未明确标记为NonShared时,会产生大多数处理问题。这是MEF的烦恼之一,默认情况下它将所有组件视为单例。我的建议是明确标记你的每个导出为NonShared,除非你想要一个单身人士。不只是ViewModels。如果有效,请告诉我们。