了解Autofac中的生命周期范围的概念

Joe*_*ang 9 autofac

原谅我,我刚学会了Autofac.我有一些问题,了解Lifetime scopeAutofac.请帮助查看以下内容.

假设我们有以下代码.

using(var scope = container.BeginLifetimeScope())
{
  // Resolve services from a scope that is a child
  // of the root container.
  var service = scope.Resolve<IService>();

  // You can also create nested scopes...
  using(var unitOfWorkScope = scope.BeginLifetimeScope())
  {
    var anotherService = unitOfWorkScope.Resolve<IOther>();
  }
}
Run Code Online (Sandbox Code Playgroud)

正如文件所说.Lifetime scopes are disposable and they track component disposal.

这是否service是一次性的,并且在声明using(var scope = container.BeginLifetimeScope())完成后可以由GC回收?

anotherService在嵌套范围内也是如此??

我怎么能通过一些实验证明呢?

谢谢.

Mic*_*iey 25

我想您首先必须了解Autofac允许注册具有不同生命周期的组件:

  • 瞬态生命周期,via InstancePerDependency,这意味着每次要求解析组件时,容器都会创建一个新实例
  • 每个生命周期范围,via InstancePerLifetimeScope,这意味着容器将解析为特定生命周期范围内的组件的同一实例
  • 单身人士,通过SingleInstance.在这种情况下,组件最多只能创建一个组件实例

那么组件处理轨道意味着什么?

这意味着每个生命周期范围都会跟踪它拥有的组件.在处理寿命范围时,一次性使用的每个自有组件 - 即实施IDisposable- 将被处置.

那么我的组件何时处理?

回到第一点,这取决于他们注册的生命周期.

  • 如果组件已注册瞬态生命周期,则在处置拥有生命周期范围时将处置所有实例

  • 如果它已被注册为生命周期范围,则在处置拥有生命周期范围时将处置一个实例

  • 如果组件已注册为单例,则该实例由根生存期范围拥有,并且仅在该根生命周期范围被处置时处置

一些支持代码

public class TransientService : IDisposable
{
    private static int _instanceCount = 0;
    private readonly int _instanceNumber;

    public TransientService()
    {
        _instanceCount++;
        _instanceNumber = _instanceCount;

        Console.WriteLine($"Just created TransientService #{_instanceNumber}");
    }

    public void Dispose()
    {
        Console.WriteLine($"Disposing TransientService #{_instanceNumber}");
    }
}

public class LifetimeScopeService : IDisposable
{
    private static int _instanceCount = 0;
    private readonly int _instanceNumber;

    public LifetimeScopeService()
    {
        _instanceCount++;
        _instanceNumber = _instanceCount;

        Console.WriteLine($"Just created LifetimeScopeService #{_instanceNumber}");
    }

    public void Dispose()
    {
        Console.WriteLine($"Disposing LifetimeScopeService #{_instanceNumber}");
    }
}

public class SingletonService : IDisposable
{
    private static int _instanceCount = 0;
    private readonly int _instanceNumber;

    public SingletonService()
    {
        _instanceCount++;
        _instanceNumber = _instanceCount;

        Console.WriteLine($"Just created SingletonService #{_instanceNumber}");
    }

    public void Dispose()
    {
        Console.WriteLine($"Disposing SingletonService #{_instanceNumber}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        builder
            .RegisterType<TransientService>()
            .AsSelf()
            .InstancePerDependency();

        builder
            .RegisterType<LifetimeScopeService>()
            .AsSelf()
            .InstancePerLifetimeScope();

        builder
            .RegisterType<SingletonService>()
            .AsSelf()
            .SingleInstance();

        using (var container = builder.Build())
        {
            Console.WriteLine("Created the root scope");

            var rootTransientService = container.Resolve<TransientService>();
            var rootLifetimeScopeService = container.Resolve<LifetimeScopeService>();
            var rootSingletonService = container.Resolve<SingletonService>();

            var rootTransientServiceTwo = container.Resolve<TransientService>();
            var rootLifetimeScopeServiceTwo = container.Resolve<LifetimeScopeService>();
            var rootSingletonServiceTwo = container.Resolve<SingletonService>();

            using (var outerLifetimeScope = container.BeginLifetimeScope())
            {
                Console.WriteLine("Created the outer lifetime scope");

                var outerTransientService = outerLifetimeScope.Resolve<TransientService>();
                var outerLifetimeScopeService = outerLifetimeScope.Resolve<LifetimeScopeService>();
                var outerSingletonService = outerLifetimeScope.Resolve<SingletonService>();

                var outerTransientServiceTwo = outerLifetimeScope.Resolve<TransientService>();
                var outerLifetimeScopeServiceTwo = outerLifetimeScope.Resolve<LifetimeScopeService>();
                var outerSingletonServiceTwo = outerLifetimeScope.Resolve<SingletonService>();

                using (var innerLifetimeScope = container.BeginLifetimeScope())
                {
                    Console.WriteLine("Created the inner lifetime scope");

                    var innerTransientService = innerLifetimeScope.Resolve<TransientService>();
                    var innerLifetimeScopeService = innerLifetimeScope.Resolve<LifetimeScopeService>();
                    var innerSingletonService = innerLifetimeScope.Resolve<SingletonService>();

                    var innerTransientServiceTwo = innerLifetimeScope.Resolve<TransientService>();
                    var innerLifetimeScopeServiceTwo = innerLifetimeScope.Resolve<LifetimeScopeService>();
                    var innerSingletonServiceTwo = innerLifetimeScope.Resolve<SingletonService>();
                }

                Console.WriteLine("Disposed the inner lifetime scope");
            }

            Console.WriteLine("Disposed the outer lifetime scope");
        }

        Console.WriteLine("Disposed the root scope");

        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

3个服务,Autofac支持的每个生命周期一个.该程序非常简单,我们有根生命周期范围,外部生命周期范围和内部生命周期范围.

这些生命周期范围中的每一个都解析每个服务的2个实例,因此每个服务被解析6次.这是输出:

Created the root scope

    Just created TransientService #1
    Just created LifetimeScopeService #1
    Just created SingletonService #1
    Just created TransientService #2

        Created the outer lifetime scope

            Just created TransientService #3
            Just created LifetimeScopeService #2
            Just created TransientService #4

                Created the inner lifetime scope

                    Just created TransientService #5
                    Just created LifetimeScopeService #3
                    Just created TransientService #6

                    Disposing TransientService #6
                    Disposing LifetimeScopeService #3
                    Disposing TransientService #5

                Disposed the inner lifetime scope

            Disposing TransientService #4
            Disposing LifetimeScopeService #2
            Disposing TransientService #3

        Disposed the outer lifetime scope

    Disposing TransientService #2
    Disposing SingletonService #1
    Disposing LifetimeScopeService #1
    Disposing TransientService #1

Disposed the root scope
Run Code Online (Sandbox Code Playgroud)

一些观察结果,始终牢记所有服务已经被3个不同的生命周期范围解决了6

  • 我们最终得到了6个实例TransientService,它与我们对容器的注册相匹配.处置方面,每个生命范围在他们自己处置时处理他们的2个实例.

  • LifetimeScopeService创建了3个实例.虽然每个生命周期范围都解析了此服务两次,但Autofac始终在相同的生命周期范围内返回第二次解析时的相同实例.每个实例都由拥有的生命周期范围处理.

  • SingletonService整个应用程序中只有1个实例.此处没有生命周期范围边界,因为3个生命周期范围已解析为服务的同一实例,并在处置根范围时处理.

编辑:缩进输出以使其更具可读性并使层次结构更清晰

  • 抱歉迟到了.这是很好的解释和良好的例子+ 1.非常感激.非常感谢. (2认同)