Caliburn Micro和Castle Windsor中的ViewModel处理方法

5
我正在使用Castle-Windsor作为Caliburn-Micro Silverlight应用程序中的容器。我的ViewModel对象相当庞大,因为它们调用WCF服务和一堆其他内容。因此,当窗口关闭时,我想调用container.Release(viewModel),以便Castle可以管理整个退役/处置过程,并遵守配置的各种生命周期(如此文章所述)。
在我的AppBootstrapper中,我已经重写了GetInstance,代码如下:
protected override object GetInstance(Type serviceType, string key)
{
    if (string.IsNullOrEmpty(key)) return container.Resolve(serviceType);
    return container.Resolve(key, serviceType);
}

但我无法想出一种干净/优雅的方法来调用container.Release(viewModel)。似乎没有可用的钩子。

在Caliburn Micro应用程序中释放从ViewModelLocator返回的ViewModel对象的最简单方法是什么?

1个回答

0

你想要为每个VM类型设置的生命周期会对此产生影响,因此对于你提供的上下文,实际上并没有正确答案。

CM的Screen基类为你提供了protected virtual void OnDeactivate(bool close);,这是一个很好的起点。对于你的重量级VMs,你应该重写这个方法,并且如果VM正在关闭(由close参数指示),则释放任何需要处理的资源(如WCF通道等),这将包括处理资源(如果与IDisposable相关)以及断开任何引用,以便GC可以清理它们。

我不使用Castle,所以无法帮助你配置生命周期等。但是,如果你遵循上述步骤,就不会持有任何重量级的东西。我假设在正确的生命周期配置下,Castle将自动清理任何你不再使用的旧实例,而无需显式调用Release


非常感谢@Simon。我一直在探索OnDeactivate路由作为挂钩的地方。是的,如果您有一个具有长构造函数参数列表的VM,则Castle将满足该组件构造函数的所有依赖项。然后,当释放组件时,Castle将根据为每个依赖项配置的生命周期来释放所有依赖项。这里重要的是,Vms本身不负责任何清理工作-所有工作都是自动完成的。 - Phil Degenhardt
将责任推给 VM 本身可能是可行的,但这意味着 VM 开始被生命周期责任所污染,如果可能的话,我真的希望把它们排除在外。理想情况下,发布的责任应该与解析的责任一起存在 - 即在调用堆栈的更高位置,在引导程序或容器本身中... - Phil Degenhardt
是的,这就是我所说的。例如,如果您将VM类型配置为“单次使用”(在Castle中映射到什么),那么下一次请求该类型的实例时,容器应该只释放已使用的实例,因为它已经被使用了……不需要明确调用释放命令。 - Simon Fox
根据您提供的WCF服务示例,您的VM可能在其参数列表中具有用于创建WCF通道的工厂抽象。Castle将为您注入该工厂,但是这样的东西应该具有更长的生命周期,并且您不需要释放它。只要您在OnDeactivate中处理任何通过该工厂创建的通道并断开连接,就应该没问题了。明白吗? - Simon Fox
我完全同意,并且并不建议您从VM中调用Release。我只是不明白为什么容器会保留一个临时实例(这可能只是因为我对Castle经验不足),一旦构建完成,容器应该能够忘记它。正如我之前提到的,像服务工厂这样的东西可以留在容器中并重复使用,直到应用程序关闭时才需要释放它(您可以从引导程序进行钩子操作)。 - Simon Fox
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接