您好我在WPF应用程序中使用MEF和caliburn.micro。我想知道怎样才能破坏用MEF创造的实例。
例如简单的shell:
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IShellViewModel
{
protected override void OnInitialize()
{
ShowLogOn();
base.OnInitialize();
}
//first screen
public void ShowLogOn()
{
var vm = IoC.Get<ILogOnViewModel>();
ActivateItem(vm);
}
//second screen
public void ShowMessenger(Account account)
{
ActiveItem.Deactivate(true);
var vm = IoC.Get<IMessengerViewModel>();
vm.Account = account;
ActivateItem(vm);
}
}
第一个屏幕
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen,ILogOnViewModel
{
User user=new User();
}
第二个屏幕:
[Export(typeof(IMessengerViewModel))]
public class MessengerViewModel : Screen, IViewModelIdentity,
IMessengerViewModel, IHandle<Rp>, IHandle<string>
{..}
WPF应用程序以与ILogOnViewModel接口关联的第一个屏幕开始。然后我停用此屏幕并激活与IMessengerViewModel界面关联的第二个屏幕。
我使用ANTS Mememory探查器检查内存使用情况,但ILogOnViewModel的实例仍处于活动状态,同时用户还活着。
我是IoC的新手,DI ......所有使用MEF导出的类必须在整个WPF应用程序生命周期内生效?
其他例子,我用窗口管理器创建了新的wpf窗口。
[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IViewModelIdentity,
IChatViewModel, IHandle<Rp>, IHandle<DetailData>
{}
ChatViewModel是WPF窗口。
创建IChatViewModel的实例:
private IWindowManager _windowManager;
var chatScreen = IoC.Get<IChatViewModel>();
_windowManager.Show(chatScreen);
然后我关闭(点击窗口上的X(关闭)按钮)WPF窗口,ChatViewModel被停用 但是这个班级的实力仍然存在。
存在如何杀死/破坏这种情况的方式?
答案 0 :(得分:1)
MEF容器负责管理导出的生命周期,因此无论使用哪个CreationPolicy
(默认为Shared
),对容器的Dispose
方法的最终调用将处理任何Export
实例(包装实际的类实例)。此外,在Dispose
实例上调用Export
也会导致实际的类实例处置。
要记住的是,GC正在查看对象图并确定是否有0或更多对该特定实例的引用,因为引用由MEF CompositionContainer
维护(包含在{ {1}})它不会处置该项目。
如果您强制在插件中实施Export
,例如
IDisposable
确保在实现dispose模式时,允许多次调用它:
public interface ILogOnViewModel : IDisposable { }
然后,您可以安全地在public void Dispose(bool disposing)
{
if (disposing && !disposed)
{
// Clean up?
}
}
public void Dispose()
{
Dispose(true);
GC.SurpressFinalize(this);
}
实施的实例上调用Dispose
,而不会在实际容器处理时造成问题。