Prism IDDisposable Autofac 和 Lifetime Scope

Prism IDisposable Autofac and Lifetime Scope

我正在使用 Prism 在我的 WPF 应用程序的视图之间导航。特别是我用 IRegionMemberLifetime.KeepAlive => returns false 实现的一个视图;每次我们导航到视图时创建一个新的视图实例(出于显示原因,我们需要这样做)。此视图还包含一个自定义 win32 控件,我需要在使用 IDisposable.Dispose 时对其进行一些清理。当我导航到我的视图然后离开它时,我希望 Dispose 被调用(运行 清理)。我能够通过实现此处讨论的自定义区域行为来实现这一点,https://github.com/PrismLibrary/Prism/issues/7. All this is working fine except everything gets marked for disposal but the GC doesn't actually get rid of anything. I'm using Autofac as my IOC container and after doing some research I've concluded the reason comes down to Autofac and lifetime scopes of IDisposables, https://nblumhardt.com/2011/01/an-autofac-lifetime-primer/。基本上 Autofac 持有对 IDisposable 的引用,因此 GC 不会摆脱旧视图。例如,我在模块中将我的视图注册为 _container.RegisterTypeForNavigation();我无法在任何类型的生命周期内注册这个,我不确定如何在指定的生命周期内解决这个问题?当我调用 RegionManager.RequestNavigate 时,我没有看到任何类型的重载来指定生命周期?任何想法将不胜感激。

RegisterTypeForNavigation 本质上是 builder.RegisterType(type).Named<object>(name); ,你当然也可以自己做,并应用你想要的任何生命周期。注册导航没有魔法,RegisterTypeForNavigation只是一个shorthand.

要使 Autofac 忽略 IDisposables,可以写

builder.RegisterType<SomeView>().Named<object>(typeof(SomeView).Name).ExternallyOwned();

来自the docs

Disabling Disposal

Components are owned by the container by default and will be disposed by it when appropriate. To disable this, register a component as having external ownership:

builder.RegisterType<SomeComponent>().ExternallyOwned();

The container will never call Dispose() on an object registered with external ownership. It is up to you to dispose of components registered in this fashion.

所以扩展@Haukinger 的回答。这就是最终对我有用的东西:

//builder.RegisterTypeForNavigation<SomeView>();
builder.RegisterType<SomeView>().Named<object> 
(typeof(SomeView).Name).ExternallyOwned();

ExternallyOwned() 向 autofac 发出信号,表明用户将处理调用 dispose 并且 autofac 不应跟踪 IDisposable。