在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);
services.AddDbContext<ApplicationDbContext>(Action<IServiceProvider, DbContextOptionsBuilder> optionsAction);
//其它相关服务:DbContextOptionsBuilder 的方法与 属性 Options = DbContextOptions
UseSqlServer(DbContextOptionsBuilder, String, Action<SqlServerDbContextOptionsBuilder>);
} }
AddDBContext 的 Github源代码,有几个,最后调用 最全参数的那个,efcore/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)
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)
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;
}