C# 尝试了解IoC(使用Autofac)中的寿命范围意味着什么?

C# 尝试了解IoC(使用Autofac)中的寿命范围意味着什么?,c#,dependency-injection,inversion-of-control,autofac,lifetime-scoping,C#,Dependency Injection,Inversion Of Control,Autofac,Lifetime Scoping,起初我确实私下假设我能理解它,但通过Autofac的一些简单示例,似乎我可能理解错了,下面是我尝试过的代码: //register the service autofacBuilder.RegisterType<MyService>() .As<IMyService>().InstancePerLifetimeScope(); //testing code void _test1() { var myService = autofacCo

起初我确实私下假设我能理解它,但通过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对其进行测试,您可以简单地检查在这两个方法中解析的实例

因此,通过上面的代码,我理解_test1中的myService和_test2中的myService应该是不同的。因为我认为_test1中myService的生存期范围应该正好在该方法中,而_test2中myService的生存期范围也应该在_test2中。我们这里有两个不同的作用域,但不知何故,myService的解析实例是相同的

那么,你能向我解释一下这个问题吗,生命周期的范围到底意味着什么?在同一个班级里?或者更大的东西?

你弄糊涂了。这就像比较苹果和栅栏一样他们只是不同而已,彼此没有任何关系

因此,为了澄清这一点,请看下面的基本示例。请注意,如果您是启动这些作用域的人(如示例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);

您没有创建嵌套的生存期范围,所以我希望实例是相同的。我相信容器的生存期是相同的。容器对你的花括号一无所知。它是根目录而不是收集的,并且引用了它正在管理的MyService实例。因此,每次您向同一容器请求该类型的实例时,由于您的配置,您得到的都是同一个实例。@DavidG那么您的意思是我们需要声明它的工作范围吗?我想它可以为我自动检测范围。在不声明任何作用域的情况下,.InstancePerLifetimeScope的工作原理与.SingleInstance?@非常类似。您所说的会让我感到困惑。InstancePerLifetimeScope和.SingleInstance。基本上是的,您需要手动创建一个作用域,否则您就有一个单例。请看这里:谢谢,我真的认为它应该与代码范围相匹配,这将是如此美妙。在使用IoC时,除非您希望将autoFac作为紧耦合组件正确地放在复杂服务中,否则我们并不总是显式地声明作用域。