c# - 在 Autofac 中处理通过构造函数注入的没有生命周期范围的组件
问题描述
我不明白为什么我的组件永远不会在 Autofac 中处理/发布。我有一个标准的 WPF 应用程序,它从 app.xaml.cs 开始,解析MainVM
这是一个单例并显示MainWindow
with DataContext
of MainVM
。
然后我主要使用我的注册组件的构造函数注入,这些组件是单例或(默认)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()
或OnRelease
从 Autofac调用事件。这些中的任何一个都可以。
但我的问题是 - 我没有使用这种模式:
using(var scope = container.BeginLifetimeScope())
因为我没有在从 { 到 } 的一种方法中工作。我需要我的组件以多种方法存在于对象中,并且在我ViewModel1
从视图堆栈中删除之后,我希望在其中创建的所有内容都ViewModel1
可以释放/释放其子级。是什么导致组件认为它们可以被丢弃?如果视图模型不是在生命周期范围内创建的,我如何告诉它不再需要它?
解决方案
你不应该关心没有实现的类IDisposable
。即使它们的实例是由 Autofac 容器创建的,一旦没有对它们的 GC 根引用(例如,视图已关闭并且对它的所有引用都被null
-ed),对象将自动被 GC。这会影响整个依赖关系图——不管它有多深。
如果你的设置中有IDisposable
对象,容器当然会保存对它们的引用,因为它需要处理这些对象。但是,您仍然可以控制这种情况的发生方式。
您可以为此使用依赖项的Owned<T>
实例。IDisposable
考虑你的例子:
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
在我们的示例中。
考虑阅读文档中有关拥有的实例的信息。
推荐阅读
- c - C 语言 - 由于全局变量,函数的不同定义
- javascript - 我输入的输入值未显示在 JavaScript 中
- gps - 哪些类型的 GPS 数据(即 GGA、RMC 等)只有在获得定位后才可用?
- amazon-web-services - 在 Athena 中创建仅包含存储在存储桶中的文件名的表
- wordpress - 在 htaccess [WordPress] 中重定向分页 URL
- python - POST 返回“详细信息”:“方法 \"GET\" 不允许。”
- python - 获取列表中重复次数最多的元素重复的次数
- rust - Rust 反序列化:将字节向量转换为 uuid 的哈希集
- html - 简单的初学者问题:在下拉列表中随机启动选项?
- c# - C# - 对不止一个词使用自动完成