Ejemplo n.º 1
0
        /// <summary>
        /// 通过定位器解析上下文
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="dbContextLocator"></param>
        /// <returns></returns>
        private static DbContext ResolveDbContext(IServiceProvider provider, Type dbContextLocator)
        {
            // 判断数据库上下文定位器是否绑定
            Penetrates.CheckDbContextLocator(dbContextLocator, out var dbContextType);

            // 动态解析数据库上下文
            var dbContext = provider.GetService(dbContextType) as DbContext;

            // 实现动态数据库上下文功能,刷新 OnModelCreating
            var dbContextAttribute = DbProvider.GetAppDbContextAttribute(dbContextType);

            if (dbContextAttribute?.Mode == DbContextMode.Dynamic)
            {
                DynamicModelCacheKeyFactory.RebuildModels();
            }

            // 添加数据库上下文到池中
            var dbContextPool = provider.GetService <IDbContextPool>();

            dbContextPool?.AddToPool(dbContext);

            return(dbContext);
        }
        /// <summary>
        /// 添加数据库上下文
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configure">配置</param>
        /// <param name="migrationAssemblyName">迁移类库名称</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddDatabaseAccessor(this IServiceCollection services, Action <IServiceCollection> configure = null, string migrationAssemblyName = default)
        {
            // 设置迁移类库名称
            if (!string.IsNullOrEmpty(migrationAssemblyName))
            {
                Db.MigrationAssemblyName = migrationAssemblyName;
            }

            // 配置数据库上下文
            configure?.Invoke(services);

            // 注册数据库上下文池
            services.TryAddScoped <IDbContextPool, DbContextPool>();

            // 注册 Sql 仓储
            services.TryAddScoped(typeof(ISqlRepository <>), typeof(SqlRepository <>));

            // 注册 Sql 非泛型仓储
            services.TryAddScoped <ISqlRepository, SqlRepository>();

            // 注册多数据库上下文仓储
            services.TryAddScoped(typeof(IRepository <,>), typeof(EFCoreRepository <,>));

            // 注册泛型仓储
            services.TryAddScoped(typeof(IRepository <>), typeof(EFCoreRepository <>));

            // 注册主从库仓储
            services.TryAddScoped(typeof(IMSRepository <,>), typeof(MSRepository <,>));
            services.TryAddScoped(typeof(IMSRepository <, ,>), typeof(MSRepository <, ,>));
            services.TryAddScoped(typeof(IMSRepository <, , ,>), typeof(MSRepository <, , ,>));
            services.TryAddScoped(typeof(IMSRepository <, , , ,>), typeof(MSRepository <, , , ,>));
            services.TryAddScoped(typeof(IMSRepository <, , , , ,>), typeof(MSRepository <, , , , ,>));
            services.TryAddScoped(typeof(IMSRepository <, , , , , ,>), typeof(MSRepository <, , , , , ,>));
            services.TryAddScoped(typeof(IMSRepository <, , , , , , ,>), typeof(MSRepository <, , , , , , ,>));

            // 注册非泛型仓储
            services.TryAddScoped <IRepository, EFCoreRepository>();

            // 注册多数据库仓储
            services.TryAddScoped(typeof(IDbRepository <>), typeof(DbRepository <>));

            // 解析数据库上下文
            services.AddTransient(provider =>
            {
                DbContext dbContextResolve(Type locator, ITransient transient)
                {
                    // 判断定位器是否绑定了数据库上下文
                    var isRegistered = Penetrates.DbContextWithLocatorCached.TryGetValue(locator, out var dbContextType);
                    if (!isRegistered)
                    {
                        throw new InvalidOperationException("The DbContext for locator binding was not found.");
                    }

                    // 动态解析数据库上下文
                    var dbContext = provider.GetService(dbContextType) as DbContext;

                    // 实现动态数据库上下文功能,刷新 OnModelCreating
                    var dbContextAttribute = DbProvider.GetAppDbContextAttribute(dbContextType);
                    if (dbContextAttribute?.Mode == DbContextMode.Dynamic)
                    {
                        DynamicModelCacheKeyFactory.RebuildModels();
                    }

                    // 添加数据库上下文到池中
                    var dbContextPool = App.GetService <IDbContextPool>();
                    dbContextPool?.AddToPool(dbContext);

                    return(dbContext);
                }
                return((Func <Type, ITransient, DbContext>)dbContextResolve);
            });

            services.AddScoped(provider =>
            {
                DbContext dbContextResolve(Type locator, IScoped scoped)
                {
                    // 判断定位器是否绑定了数据库上下文
                    var isRegistered = Penetrates.DbContextWithLocatorCached.TryGetValue(locator, out var dbContextType);
                    if (!isRegistered)
                    {
                        throw new InvalidOperationException("The DbContext for locator binding was not found.");
                    }

                    // 动态解析数据库上下文
                    var dbContext = provider.GetService(dbContextType) as DbContext;

                    // 实现动态数据库上下文功能,刷新 OnModelCreating
                    var dbContextAttribute = DbProvider.GetAppDbContextAttribute(dbContextType);
                    if (dbContextAttribute?.Mode == DbContextMode.Dynamic)
                    {
                        DynamicModelCacheKeyFactory.RebuildModels();
                    }

                    // 添加数据库上下文到池中
                    var dbContextPool = App.GetService <IDbContextPool>();
                    dbContextPool?.AddToPool(dbContext);

                    return(dbContext);
                }
                return((Func <Type, IScoped, DbContext>)dbContextResolve);
            });

            // 注册 Sql 代理接口
            services.AddScopedDispatchProxyForInterface <SqlDispatchProxy, ISqlDispatchProxy>();

            // 注册全局工作单元过滤器
            services.AddMvcFilter <UnitOfWorkFilter>();

            return(services);
        }