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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM