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

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

    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
{
    serviceCollection.TryAdd(
        new ServiceDescriptor(
            typeof(DbContextOptions<TContextImplementation>),
            p => DbContextOptionsFactory<TContextImplementation>(p, optionsAction),
            optionsLifetime));

    serviceCollection.Add(
        new ServiceDescriptor(
            typeof(DbContextOptions),
            p => p.GetRequiredService<DbContextOptions<TContextImplementation>>(),
            optionsLifetime));
}

private static DbContextOptions<TContext> DbContextOptionsFactory<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;
}

private static void CheckContextConstructors<TContext>()
    where TContext : DbContext
{
    var declaredConstructors = typeof(TContext).GetTypeInfo().DeclaredConstructors.ToList();
    if (declaredConstructors.Count == 1
        && declaredConstructors[0].GetParameters().Length == 0)
    {
        throw new ArgumentException(CoreStrings.DbContextMissingConstructor(typeof(TContext).ShortDisplayName()));
    }
}

最新文章

  1. ABP理论学习之Swagger UI集成
  2. Linux SSH,FTP服务配置
  3. JS中级 - 02:表单、表格
  4. Function---hdu5875(大连网选,区间连续求余)
  5. 查看django里所有的url
  6. 九度OJ 1514 数值的整数次方【算法】
  7. doGet与doPost的区别
  8. 11136-Hoax or what
  9. vs2012编译在win7 32位电脑和win xp电脑上运行的win32程序遇到的问题记录
  10. 关于C++ const 的全面总结《转》
  11. Git综合使用命令行和gui工具小结
  12. 生产apollo搭建记录(五)
  13. 7--Python入门--条件和循环
  14. Java基础知识(抽象类和接口)
  15. confluence部署与破解
  16. (转)JDK工具-javadoc命令
  17. HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
  18. spring定时,cronExpression表达式解释
  19. Eclipse项目红色叹号解决方法
  20. 使用Echarts进行可视化的数据线呈现

热门文章

  1. 第05组 Beta版本演示
  2. Exe4j 打包: this executable was created with an evaluation version of exe4j
  3. 【SDOI 2015】约数个数和
  4. Ext.ux.UploadDialog上传大文件 HTTP 错误 413.1 - Request Entity Too Large Web 服务器拒绝为请求提供服务,因为该请求实体过大。Web 服务器无法为请求提供服务,因为它正尝试与客户证书进行协商,但请求实体过大。
  5. $和jquery的关系
  6. 甲方安全之安卓App第三方加固对比
  7. Pandas:DataFrame数据选择方法(索引)
  8. React Native之React Navigation踩坑
  9. opencv-python图像处理基础(一)
  10. QJsonObject与QString转化封装