尝试了解 IoC(使用 Autofac)中的生命周期范围意味着什么?
Try to understand what lifetime scope means in IoC (with Autofac)?
起初我私下认为我可以理解它,但是通过Autofac
的一些简单示例,看来我可能理解错了,这是我试过的代码:
//register the service
autofacBuilder.RegisterType<MyService>()
.As<IMyService>().InstancePerLifetimeScope();
//testing code
void _test1()
{
var myService = autofacContainer.Resolve<IMyService>();
}
void _test2()
{
_test1();
var myService = autofacContainer.Resolve<IMyService>();
}
通过运行_test2()
测试,您可以简单地检查2种方法中解析的实例。
所以通过上面的代码,我理解 _test1
中的 myService
和 _test2
中的 myService
应该是不同的。因为我认为 _test1
中 myService
的生命周期范围应该在那个方法中,而 _test2
中 myService
的生命周期范围也应该在 _test2
中.所以我们这里有2个不同的作用域,但是myService
的解析实例是同一个
那么请您向我解释一下这个问题,lifetime scope
在这里到底是什么意思?在同一个 class 内?或者更大的东西?
你搞糊涂了c# scopes and autofac's scopes。这就像比较苹果和栅栏。 :) 它们只是不同而已,彼此没有任何关系。
因此,为了阐明它,请查看下面的基本示例。请注意,如果您是像示例 1 中那样启动它们的人,那么实际上您应该销毁这些范围。在其他示例中,为简洁起见,我跳过了它。
// example 1
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// the same scope is used here and in _test1()
// this means that the service instance will be the same here and there
_test1(scope);
var myService = scope.Resolve<IMyService>();
}
// it's only here that DI lifetime scope starts
using (var scope = container.BeginLifetimeScope()) {
_test2(scope);
}
// example 2
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// now new scope is used in _test1() call
// this means that instances will be different here and there since they are resolved from different scopes
_test1(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);
// example 3
// NOTE THIS!
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerDependency();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// the same scope is used here and in _test1()
// but now service instances will be different even though they are resolved from the same scope
// since registration directs to create new instance each time the service is requested.
_test1(scope);
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);
// example 4
autofacBuilder.RegisterType<MyService>().As<IMyService>().SingleInstance();
var container = autofacBuilder.Build();
void _test0(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test1(IComponentContext scope){
_test0(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// all the scopes used here and in other calls are different now
// but the service instance will be the same in all of them even though it is requested from different scopes
// since registration directs to get the same instance each time the service is requested regardless of the lifetime scope.
_test1(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);
起初我私下认为我可以理解它,但是通过Autofac
的一些简单示例,看来我可能理解错了,这是我试过的代码:
//register the service
autofacBuilder.RegisterType<MyService>()
.As<IMyService>().InstancePerLifetimeScope();
//testing code
void _test1()
{
var myService = autofacContainer.Resolve<IMyService>();
}
void _test2()
{
_test1();
var myService = autofacContainer.Resolve<IMyService>();
}
通过运行_test2()
测试,您可以简单地检查2种方法中解析的实例。
所以通过上面的代码,我理解 _test1
中的 myService
和 _test2
中的 myService
应该是不同的。因为我认为 _test1
中 myService
的生命周期范围应该在那个方法中,而 _test2
中 myService
的生命周期范围也应该在 _test2
中.所以我们这里有2个不同的作用域,但是myService
的解析实例是同一个
那么请您向我解释一下这个问题,lifetime scope
在这里到底是什么意思?在同一个 class 内?或者更大的东西?
你搞糊涂了c# scopes and autofac's scopes。这就像比较苹果和栅栏。 :) 它们只是不同而已,彼此没有任何关系。
因此,为了阐明它,请查看下面的基本示例。请注意,如果您是像示例 1 中那样启动它们的人,那么实际上您应该销毁这些范围。在其他示例中,为简洁起见,我跳过了它。
// example 1
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// the same scope is used here and in _test1()
// this means that the service instance will be the same here and there
_test1(scope);
var myService = scope.Resolve<IMyService>();
}
// it's only here that DI lifetime scope starts
using (var scope = container.BeginLifetimeScope()) {
_test2(scope);
}
// example 2
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// now new scope is used in _test1() call
// this means that instances will be different here and there since they are resolved from different scopes
_test1(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);
// example 3
// NOTE THIS!
autofacBuilder.RegisterType<MyService>().As<IMyService>().InstancePerDependency();
var container = autofacBuilder.Build();
void _test1(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// the same scope is used here and in _test1()
// but now service instances will be different even though they are resolved from the same scope
// since registration directs to create new instance each time the service is requested.
_test1(scope);
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);
// example 4
autofacBuilder.RegisterType<MyService>().As<IMyService>().SingleInstance();
var container = autofacBuilder.Build();
void _test0(IComponentContext scope){
var myService = scope.Resolve<IMyService>();
}
void _test1(IComponentContext scope){
_test0(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
void _test2(IComponentContext scope){
// all the scopes used here and in other calls are different now
// but the service instance will be the same in all of them even though it is requested from different scopes
// since registration directs to get the same instance each time the service is requested regardless of the lifetime scope.
_test1(scope.BeginLifetimeScope());
var myService = scope.Resolve<IMyService>();
}
var scope = container.BeginLifetimeScope();
_test2(scope);