正在处理通过Autofac中没有生存期作用域的构造函数注入的组件



我不明白为什么我的组件从未在Autofac中被处理/释放。我有一个标准的WPF应用程序,它在app.xaml.cs中启动,解析作为单例的MainVM,并显示MainWindowMainVMDataContext

然后,我主要处理注册组件的构造函数注入,这些组件是singleton或(默认(instancePerDependency,每次注入时都会创建新组件。或者我有时会让工厂传递一些自定义参数。

例如,工厂看起来是这样的:

public delegate MyComponent Factory(string parameter1, int parameter2);

注入看起来像这样:

public MainVM(MyComponent.Factory createMyComponent)
...
public void makeNewComponent()
{
var myComponent = this.createMyComponent("test", 1);
myComponent.DoStuff();
}

我的组件就是这样注册的:

containerBuilder.RegisterType<T>().OnActivated(args => (args.Instance as IInitializable)?.Initialize());
builder.RegisterType<MyComponent>().As<IMyComponent>().OnActivated(args => (args.Instance as IInitializable)?.Initialize());
// This will never be called in my code: .OnRelease(instance => (instance as IInitializable)?.Uninitialize())*/;

现在让我们想象一下,我有许多这样的视图模型,它们是在其他视图模型中创建的,所以我们有类似MainVM->MyComponent->OtherComponent,在操作完成后,我希望它们进行处理(或者只是以某种方式从内存中消失(,调用Dispose()或从Autofac调用OnRelease事件。这些都可以。

但我的问题是-我没有使用这种模式:

using(var scope = container.BeginLifetimeScope())

因为我不是在一个从{到}的方法中工作。在许多方法中,我需要我的组件生活在对象中,例如,在我从视图堆栈中删除ViewModel1之后,我希望在该ViewModel1中创建的所有内容都能处理/释放其子级。是什么导致组件认为它们可以被处理?如果视图模型不是在生命周期范围内创建的,我如何告诉它不再需要它?

您不应该关心那些没有实现IDisposable的类。即使它们的实例是由Autofac容器创建的,只要对象没有GC根引用(例如,一个视图被关闭,对它的所有引用都是null-ed(,它们就会被自动GC化。这会影响整个依赖关系图——不管它有多深

如果的设置中有IDisposable对象,容器当然会保存对它们的引用,因为它需要处理这些对象。然而,你仍然可以控制这种情况是如何发生的。

为此,您可以使用IDisposable依赖项的Owned<T>实例。

举个例子:

class MainVM 
{
private readonly Owned<IMyComponent> _myComponent;
public MainVM(Owned<IMyComponent> myComponent) => _myComponent = myComponent;
public void DoStuff() => _myComponent.Value.DoStuff();
public void OnViewClosed() => _myComponent.Dispose();
}
class MyComponent : IMyComponent, IDisposable
{
public MyComponent(IOtherComponent otherComponent) { /* ... */ }
}
class OtherComponent : IOtherComponent, IDisposable
{
}

现在,当调用OnViewClosed方法时,MyComponent的所有实例将被处理,包括MyComponent的所有非共享、可丢弃的依赖项,在我们的示例中就是OtherComponent

考虑阅读文档中所拥有的实例。

最新更新