原谅我刚刚学会了Autofac
.我在理解 Lifetime scope
时遇到了一些问题在 Autofac
.请帮助查看下面的内容。
假设我们有下面的代码。
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>();
}
}
如Document放。
Lifetime scopes are disposable and they track component disposal
.是不是意思
service
是一次性的,可以在声明using(var scope = container.BeginLifetimeScope())
后被GC回收完成了吗?anotherService
也是如此在嵌套范围内? ?我如何通过一些实验来证明它?
谢谢。
最佳答案
我认为您首先必须了解 Autofac 允许注册具有不同生命周期的组件:
InstancePerDependency
,这意味着容器每次被要求解析组件时都会创建一个新实例 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();
}
}
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
一些观察,始终牢记所有服务都已解决 6 次由 3 不同的生命周期范围
TransientService
的 6 个实例。 ,这与我们对容器进行的注册相匹配。在处置方面,每个生命周期范围在自己被处置时处置了它们的 2 个实例。 LifetimeScopeService
的实例被创建。虽然每个生命周期范围两次解析此服务,但 Autofac 始终在同一生命周期范围内第二次解析相同的实例时返回相同的实例。每个实例都由拥有的生命周期范围处理。 SingletonService
的实例在整个应用程序中。这里没有生命周期范围边界,因为 3 个生命周期范围解析为服务的同一个实例,在根范围被释放时被释放。 编辑:缩进输出以使其更具可读性并使层次结构更清晰
关于autofac - 理解 Autofac 中 Lifetime 范围的概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41135292/