AddDBContext 的源代码

在Aspnet Core 的启动配置中,StartUp 类中,有配置数据库 DI服务的部分: 

按个人看源代码的理解,下列方法实际是在DI 注册了两个类:

 一个是:ApplicationDbContext,另一个是: DbContextOptions,及 DbContextOptions<ApplicationDbContext>,

实际主要涉及三个类:DbContext,DbContextOptionsBuilder,及  DbContextOptions (通过 DbContextOptionsBuilder.Options 获得,没有 Build 方法)

public class Startup  {

     public void ConfigureServices(IServiceCollection services) {

           services.AddDbContext<ApplicationDbContext>(Action<DbContextOptionsBuilder> optionsAction); 

 

           //或  AddDbContext<TContextService,TContextImplementation>(IServiceCollection, Action<IServiceProvider,DbContextOptionsBuilder>, ServiceLifetime, ServiceLifetime)

           services.AddDbContext<ApplicationDbContext>(Action<IServiceProvider, DbContextOptionsBuilder> optionsAction);

           //对应还有 AddDbContextPool<TContextService,TContextImplementation>(IServiceCollection, Action<IServiceProvider,DbContextOptionsBuilder>, Int32)

          //其它相关服务:DbContextOptionsBuilder  的方法与 属性 Options = DbContextOptions

             UseSqlServer(DbContextOptionsBuilder, String, Action<SqlServerDbContextOptionsBuilder>)

             

     }  }

AddDBContext 的 Github源代码,有几个,最后调用 最全参数的那个,efcore/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs, 参考 : 

https://github.com/dotnet/efcore/blob/c69926a8cdd05f4427e89ac8bac734e490b3d23a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs 

public static IServiceCollection AddDbContext<TContextService, TContextImplementation> (

      [NotNull] this IServiceCollection serviceCollection,
      [CanBeNull]  Action<IServiceProvider, DbContextOptionsBuilder> optionsAction,
      ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
      ServiceLifetime optionsLifetime = ServiceLifetime.Scoped   )    where TContextImplementation : DbContext, TContextService
{
      Check.NotNull(serviceCollection, nameof(serviceCollection));        // 这个方法在哪里定义???

     if (contextLifetime == ServiceLifetime.Singleton)
     {
         optionsLifetime = ServiceLifetime.Singleton;
     }

     if (optionsAction != null)
    {
        CheckContextConstructors<TContextImplementation>();              // 检查TContextImplementation类的构造器是可有参数。
    }

    AddCoreServices<TContextImplementation>(serviceCollection, optionsAction, optionsLifetime);

    // TryAdd 方法定义:Add(IServiceCollection, ServiceDescriptor)   其中  ServiceDescriptor  的定义。

    //  使用 构造函数  ServiceDescriptor(Type, Type, ServiceLifetime)

    //  官方  https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection?view=dotnet-plat-ext-3.1

    serviceCollection.TryAdd(new ServiceDescriptor(typeof(TContextService), typeof(TContextImplementation), contextLifetime));

    return serviceCollection;
}

private static void AddCoreServices<TContextImplementation> (
     IServiceCollection serviceCollection,
     Action<IServiceProvider, DbContextOptionsBuilder> optionsAction,
     ServiceLifetime optionsLifetime )    where TContextImplementation : DbContext
{

    // TryAdd 方法定义:Add(IServiceCollection, ServiceDescriptor)   

    //  使用 构造函数  ServiceDescriptor(Type, Func<IServiceProvider,Object>, ServiceLifetime)

    //  官方  https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.extensions.dependencyinjection.iservicecollection?view=dotnet-plat-ext-3.1

    serviceCollection.TryAdd( new ServiceDescriptor( typeof(DbContextOptions<TContextImplementation>),
                                              p => CreateDbContextOptions<TContextImplementation>(p, optionsAction),  optionsLifetime));

   serviceCollection.Add( new ServiceDescriptor( typeof(DbContextOptions), 

                                        p => p.GetRequiredService<DbContextOptions<TContextImplementation>>(), optionsLifetime));
}

private static DbContextOptions<TContext> CreateDbContextOptions<TContext>(
      [NotNull] IServiceProvider applicationServiceProvider,
      [CanBeNull] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction)   where TContext : DbContext
{
      var builder = new DbContextOptionsBuilder<TContext>(
      new DbContextOptions<TContext>(new Dictionary<Type, IDbContextOptionsExtension>()));

      builder.UseApplicationServiceProvider(applicationServiceProvider);

      optionsAction?.Invoke(applicationServiceProvider, builder);

      return builder.Options;
}

 

posted @ 2020-02-29 13:03  Hopesun  阅读(1111)  评论(0编辑  收藏  举报