如何破坏使用MEF创建的对象

时间:2011-01-02 17:39:30

标签: ioc-container mef caliburn.micro memory-management

您好我在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被停用 但是这个班级的实力仍然存在。

存在如何杀死/破坏这种情况的方式?

1 个答案:

答案 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,而不会在实际容器处理时造成问题。