Autofac - InstancePerLifetimeScope与ASP.NET Web窗体中Application_Start中的InstancePerRequest

问题描述 投票:0回答:2

我正在使用Autofac与ASP.NET Webforms。当我在global.asx的App_Start方法中注册依赖项时,我想了解InstancePerLifetimeScope和InstancePerRequest之间的区别。

看起来对于它们两者来说,依赖关系的新实例只在Every HttpRequest中创建一次(通过断点进入依赖关系的构造函数和对象的HashCode)。

有任何想法吗?

谢谢

autofac
2个回答
1
投票

@Travis提供了描述其工作原理的文档的良好链接。但是,我更愿意举一些例子来更好地说明理论。那么,让我们来看一个简单的例子。

假设您有两个类ClassA和ClassB实现了一些简单的接口IClassA和IClassB。

public class ClassA : IClassA
{
    public ClassA() {
    }
}

public class ClassB : IClassB
{
    public ClassB() {
    }
}

现在,让我们看看当我们以不同的方式注册它们时会发生什么。

例A

builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();    
builder.RegisterType<ClassB>().As<IClassB>().InstancePerLifetimeScope();

然后,在控制器中,您执行以下操作:

public class HomeController : Controller
{
    private readonly IClassA _classA;
    private readonly IClassB _classB;
    private readonly IComponentContext _ctx;

    public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
        _classA = classA;
        _classB = classB;
        _ctx = ctx;
    }

    public string Get() {
        using (var scope = _ctx.BeginLifetimeScope()) {
            var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
            var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == false
            return "Ok";
        }
    }
}

在此示例中,Get()方法中的两个“新”变量将接收新实例,因为它们都被注册为每个生命周期范围内唯一。我们开始了新的生命范围 - 我们得到了新的实例。

现在,我们来看看另一个例子。

例B

builder = new ContainerBuilder();
builder.RegisterType<ClassA>().As<IClassA>().InstancePerLifetimeScope();
builder.RegisterType<ClassB>().As<IClassB>().InstancePerRequest(); // now they have different life time!

// controller:

public class HomeController : Controller
{
    private readonly IClassA _classA;
    private readonly IClassB _classB;
    private readonly IComponentContext _ctx;

    public HomeController(IClassA classA, IClassB classB, IComponentContext ctx) {
        _classA = classA;
        _classB = classB;
        _ctx = ctx;
    }

    public string Get() {
        using (var scope = _ctx.BeginLifetimeScope()) {
            var newClassA = scope.Resolve<IClassA>(); // Object.ReferenceEquals(newClassA, _classA) == false
            var newClassB = scope.Resolve<IClassB>(); // Object.ReferenceEquals(newClassB, _classB) == true
            return "Ok";
        }
    }

}

看看这里发生了什么?即使我们开始了新的生命周期范围 - 仍然可以从请求范围而不是从我们的新范围中解析ClassB。这是InstancePerLifetimeScope()和InstancePerRequest()之间的区别。

正如文档所暗示的那样,内部它基于另一个Autofac概念 - InstancePerMatchingLifetimeScope()


2
投票

在许多情况下,它相同。 This is an FAQ on the Autofac doc site.

© www.soinside.com 2019 - 2024. All rights reserved.