设为首页 加入收藏

TOP

[Abp vNext 源码分析] - 3. 依赖注入与拦截器(六)
2019-09-17 18:45:30 】 浏览:129
Tags:Abp vNext 源码 分析 依赖 注入 拦截
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,分别是 HttpContextServiceScopeFactoryDefaultServiceScopeFactory ,它们都继承自 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
首页 上一页 3 4 5 6 7 下一页 尾页 6/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇本地Git仓库和Github仓库的关联 下一篇Asp .Net core 2 学习笔记(3) —..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目