1

嗨,我在 WPF 应用程序中使用 MEF 和 caliburn.micro。我想知道如何销毁使用 MEF 创建的实例。

例如简单的外壳:

 [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 已停用,但此类的实例仍然存在。

它存在方式如何杀死/销毁这个实例?

4

1 回答 1

1

MEF 容器负责管理导出的生命周期,因此无论使用哪个CreationPolicy(默​​认为Shared),对容器Dispose方法的最终调用都将处理任何Export实例(包装您的实际类实例)。此外,调用实例也会导致实际DisposeExport类实例也被释放。

要记住的是,GC 正在查看对象图并确定是否有 0 个或多个对该特定实例的引用,因为引用由 MEF 维护CompositionContainer(包装在 中Export)它不会处理该项目.

如果你强制IDisposable在你的插件中实现,例如

public interface ILogOnViewModel : IDisposable { }

并确保在实现 dispose 模式时,允许多次调用它:

public void Dispose(bool disposing)
{
    if (disposing && !disposed)
    {
        // Clean up?
    }
}

public void Dispose()
{
    Dispose(true);
    GC.SurpressFinalize(this);
}

然后,您可以安全地调用Dispose您的ILogOnViewModel实现实例,而不会在实际容器处理时引起问题。

于 2011-01-03T11:57:36.100 回答