我正在使用Autofac和ASP.NET Webforms。当我在global.asx的App_Start方法中注册依赖项时,我想了解InstancePerLifetimeScope和InstancePerRequest之间的区别。
对于他们两个来说,在Every HttpRequest中只创建一次新的依赖实例(使用断点进入依赖关系的构造函数和对象的HashCode)。
有什么想法吗?
谢谢
答案 0 :(得分:2)
在许多情况下,它相同。 This is an FAQ on the Autofac doc site.
答案 1 :(得分: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()。