pe _lifetimeScope;
public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope)
{
this._lifetimeScope = lifetimeScope;
}
public IServiceScope CreateScope()
{
return new AutofacServiceScope(this._lifetimeScope.BeginLifetimeScope());
}
}
这里可以看到,在构建这个工厂的时候,会注入一个 ILifetimScope
,这个东西就是 AutoFac 提供的 子容器。在 CreateScope()
方法内部,我们通过构造一个 Scope 作为具体的范围解析对象,并将子容器传入到它的内部。
internal class AutofacServiceScope : IServiceScope
{
private readonly ILifetimeScope _lifetimeScope;
public AutofacServiceScope(ILifetimeScope lifetimeScope)
{
// 构造子容器。
this._lifetimeScope = lifetimeScope;
this.ServiceProvider = this._lifetimeScope.Resolve<IServiceProvider>();
}
public IServiceProvider ServiceProvider { get; }
public void Dispose()
{
// 范围释放的时候,释放子容器。
this._lifetimeScope.Dispose();
}
}
那么是在什么时候,我们的范围工厂会被调用来构造一个 IServiceScope
对象呢?就是在 ASP.NET Core 每次请求的时候,它在获得其内部的 RequestServices
时,就会通过 IServiceProvidersFeature
来创建一个 Scope 范围。
public IServiceProvider RequestServices
{
get
{
if (!_requestServicesSet)
{
_context.Response.RegisterForDispose(this);
// 通过工厂,创建一个范围解析对象,这里就是 AutofacServiceScopeFactory。
_scope = _scopeFactory.CreateScope();
_requestServices = _scope.ServiceProvider;
_requestServicesSet = true;
}
return _requestServices;
}
set
{
_requestServices = value;
_requestServicesSet = true;
}
}
所以,我们在每次请求的时候,针对于 Scope 声明周期的对象,默认的话都是在整个请求处理期间,都是单例的,除非显式使用 using
语句块声明作用域。
而在 ABP vNext 中给我们提供了两个 Scoped Factory,分别是 HttpContextServiceScopeFactory
和 DefaultServiceScopeFactory
,它们都继承自 IHybridServiceScopeFactory
接口。
这个 IHybridServiceScopeFactory
接口只是一个空的接口,并继承自 Microsoft Dependency Inject 提供的 IServiceScopeFactory
工厂接口。
但在实际注入的时候,并不会替换掉默认的 IServiceScopeFactory
实现。因为在 IHybridServiceScopeFactory
的默认两个实现的定义上,他们都显式得通过 ExposeServices
特性说明了自己是哪些类型的默认实现,且一般使用的时候,都是通过注入 IHybridServiceScopeFactory
并结合 using
语句块来操作。
例如在 Volo.Abp.Data 库的 DataSeeder
类型中,有如下用法。
public async Task SeedAsync(DataSeedContext context)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
foreach (var contributorType in Options.Contributors)
{
var contributor = (IDataSeedContributor) scope
.ServiceProvider
.GetRequiredService(contributorType);
await contributor.SeedAsync(context);
}
}
}
只是这两个实现有什么不同呢?通过两个类型的名字就可以看出来,一个是给 ASP.NET Core MVC 程序使用的,另一个则是默认的范围工厂,下面我们从代码层面上来比较一下两者之间的差别。
[ExposeServices(
typeof(IHybridServiceScopeFactory),
typeof(DefaultServiceScopeFactory)
)]
public class DefaultServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency
{
// 直接注入封装的 AutofacServiceScopeFactory。
protected IServiceScopeFactory Factory { get; }
public DefaultServiceScopeFactory(IServiceScopeFactory factory)
{
Factory = factory;
}
public IServiceScope CreateScope()
{
// 通过 AutofacServiceScopeFactory 创建一个 scope。
return Factory.CreateScope();
}
}
HttpContextServiceScopeFactory
是放在 AspNetCore 模块下的,从他的 Dependency
特性可以看出来,他会替换掉默认的 DefaultServiceScopeFactory
实现。
[ExposeServices(
typeof(IHybridServiceScopeFactory),
typeof(HttpContextServiceScopeFactory)
)]
[Dependency(ReplaceServices = true)]
public class HttpContextServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency
{
protected IHttpContextAccessor HttpContextAccessor { get; }
// AutoFacServiceScopeFac