如何解决Autofac如何将自动解决的服务与生命周期相关联
嗨,我是Autofac的新手,所以也许我对生命周期范围的理解是完全错误的,但是在通过处置生命周期来处置自动解决的服务时,我遇到了以下问题。 我的App.xaml.cs看起来像这样:
protected override void OnStartup(StartupEventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MainModule>();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var mainWindow = scope.Resolve<MainWindow>();
mainWindow.ShowDialog();
}
}
所以我认为在解析我的MainWindow时将解决的所有服务(在生命周期中注册为实例)将与范围相关联。这意味着在生存期结束时将处置所有实现Idisposable的服务。但事实并非如此。
我在尝试此操作时发现了
protected override void OnStartup(StartupEventArgs e)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MainModule>();
var container = builder.Build();
var mainWindow = container.Resolve<MainWindow>();
mainWindow.ShowDialog();
container.dispose();
}
Autofac在自动解析服务时将自动解析的服务与根容器(而不是范围)相关联,因为在这种情况下,按预期调用了“ dispose”方法。
有人可以解释我为什么会发生这种情况吗?处理这些自动解决的服务的最佳方法是什么?
顺便说一句,我要说“自动解决”是指不是我本人来手动解决服务,例如在我的MainWindow中,处置在生命周期范围内就可以正常工作。
解决方法
这意味着所有实现IDisposable的服务都将 生命周期范围结束时处理。
Autofac不会处理注册为实例的服务!为什么?因为一旦解决的实例将再次需要到另一个不同的范围。
让我们看一个例子,假设我们有一个Foo
类:
public class Foo : IDisposable
{
private readonly Guid _id;
public ConsoleLog()
{
this_id = Guid.NewGuid();
}
public void Dispose()
{
Console.WriteLine("Foo has been disposed.");
}
public void GetId()
{
return this_id;
}
}
我们正在向new Foo()
注册一个RegisterInstance
实例:
[TestMethod]
public void Dispose1Test()
{
var builder = new ContainerBuilder();
builder.RegisterInstance(new Foo());
var container = builder.Build();
如果要处理两个不同的作用域,则autofac会将Foo
的实例保存在构建器中:
Guid guid1;
using (var scope = container.BeginLifetimeScope())
{
id1 = scope.Resolve<Foo>().GetId();
}
Guid guid2;
using (var scope2 = container.BeginLifetimeScope())
{
id2 = scope.Resolve<Foo>().GetId(); //--> this will resolve the exact same instance!
}
//It **does not** print: "Foo has been disposed."
Assert.AreEqual(guid1,guid2);
}
什么是处理这些废物的最佳方法? 自动解决的服务
您可以使用using语句对所有容器应用处置:
[TestMethod]
public void Dispose2Test()
{
var builder = new ContainerBuilder();
builder.RegisterInstance(new Foo());
using (var container = builder.Build())
{
using (var scope = container.BeginLifetimeScope())
{
scope.Resolve<Foo>();
}
}
//Should output "Foo has been disposed."
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。