微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Autofac如何将自动解决的服务与生命周期相关联

如何解决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 举报,一经查实,本站将立刻删除。