Пример #1
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            OsharpOptions          options        = provider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(TDbContext));

            if (contextOptions?.DatabaseType != DatabaseType)
            {
                return;
            }

            using (IServiceScope scope = provider.CreateScope())
            {
                TDbContext context = CreateDbContext(scope.ServiceProvider);
                if (context != null && contextOptions.AutoMigrationEnabled)
                {
                    context.CheckAndMigration();
                    DbContextModelCache modelCache = scope.ServiceProvider.GetService <DbContextModelCache>();
                    modelCache?.Set(context.GetType(), context.Model);
                }
            }

            //种子数据
            var seedDataInitializers = provider.GetServices <ISeedDataInitializer>().OrderBy(m => m.Order);

            foreach (ISeedDataInitializer initializer in seedDataInitializers)
            {
                initializer.Initialize();
            }


            IsEnabled = true;
        }
Пример #2
0
        /// <summary>
        /// 获取指定类型的数据上下文对象
        /// </summary>
        /// <param name="resolveOptions">上下文解析选项</param>
        /// <returns></returns>
        public IDbContext Resolve(DbContextResolveOptions resolveOptions)
        {
            Type dbContextType = resolveOptions.DbContextType;
            IDbContextOptionsBuilderCreator builderCreator = _serviceProvider.GetServices <IDbContextOptionsBuilderCreator>()
                                                             .FirstOrDefault(m => m.Type == resolveOptions.DatabaseType);

            if (builderCreator == null)
            {
                throw new OsharpException($"无法解析类型为“{resolveOptions.DatabaseType}”的 {typeof(IDbContextOptionsBuilderCreator).FullName} 实例");
            }
            DbContextOptionsBuilder optionsBuilder = builderCreator.Create(resolveOptions.ConnectionString, resolveOptions.ExistingConnection);
            DbContextModelCache     modelCache     = _serviceProvider.GetService <DbContextModelCache>();
            IModel model = modelCache.Get(dbContextType);

            if (model != null)
            {
                optionsBuilder.UseModel(model);
            }
            DbContextOptions options = optionsBuilder.Options;

            //创建上下文实例
            if (!(ActivatorUtilities.CreateInstance(_serviceProvider, dbContextType, options) is DbContext context))
            {
                throw new OsharpException($"实例化数据上下文“{dbContextType.AssemblyQualifiedName}”失败");
            }
            return(context as IDbContext);
        }
Пример #3
0
        /// <summary>
        /// 构建<see cref="DbContextOptionsBuilder"/>,附加必要的扩展属性
        /// </summary>
        public static DbContextOptionsBuilder BuildDbContextOptionsBuilder <TDbContext>(this IServiceProvider provider, DbContextOptionsBuilder builder)
            where TDbContext : DbContext
        {
            Type                   dbContextType          = typeof(TDbContext);
            OsharpOptions          osharpOptions          = provider.GetOSharpOptions();
            OsharpDbContextOptions osharpDbContextOptions = osharpOptions?.GetDbContextOptions(dbContextType);

            if (osharpDbContextOptions == null)
            {
                throw new OsharpException($"无法找到数据上下文 {dbContextType.DisplayName()} 的配置信息");
            }

            ILogger logger = provider.GetLogger(typeof(ServiceExtensions));

            //启用延迟加载
            if (osharpDbContextOptions.LazyLoadingProxiesEnabled)
            {
                builder = builder.UseLazyLoadingProxies();
                logger.LogDebug($"数据上下文类型 {dbContextType} 应用延迟加载代理");
            }
            DatabaseType databaseType = osharpDbContextOptions.DatabaseType;

            //处理数据库驱动差异处理
            IDbContextOptionsBuilderDriveHandler driveHandler = provider.GetServices <IDbContextOptionsBuilderDriveHandler>()
                                                                .LastOrDefault(m => m.Type == databaseType);

            if (driveHandler == null)
            {
                throw new OsharpException($"无法解析类型为 {databaseType} 的 {typeof(IDbContextOptionsBuilderDriveHandler).DisplayName()} 实例,是否未在Startup执行AddPack<{databaseType}DefaultDbContextMigrationPack>()");
            }

            //选择主/从数据库连接串
            IConnectionStringProvider connectionStringProvider = provider.GetRequiredService <IConnectionStringProvider>();
            string connectionString = connectionStringProvider.GetConnectionString(typeof(TDbContext));

            ScopedDictionary scopedDictionary = provider.GetRequiredService <ScopedDictionary>();
            string           key = $"DbConnection_{connectionString}";
            DbConnection     existingDbConnection = scopedDictionary.GetValue <DbConnection>(key);

            builder = driveHandler.Handle(builder, connectionString, existingDbConnection);

            //使用模型缓存
            DbContextModelCache modelCache = provider.GetService <DbContextModelCache>();
            IModel model = modelCache?.Get(dbContextType);

            if (model != null)
            {
                builder = builder.UseModel(model);
            }

            return(builder);
        }
Пример #4
0
        /// <summary>
        /// 将基于Osharp数据上下文基类<see cref="DbContextBase"/>上下文类型添加到服务集合中
        /// </summary>
        /// <typeparam name="TDbContext">基于Osharp数据上下文基类<see cref="DbContextBase"/>上下文类型</typeparam>
        /// <param name="services">依赖注入服务集合</param>
        /// <param name="optionsAction">数据库选项创建配置,将在内置配置后运行</param>
        /// <returns>依赖注入服务集合</returns>
        public static IServiceCollection AddOsharpDbContext <TDbContext>(this IServiceCollection services, Action <IServiceProvider, DbContextOptionsBuilder> optionsAction = null) where TDbContext : DbContextBase
        {
            services.AddDbContext <TDbContext>((provider, builder) =>
            {
                Type dbContextType          = typeof(TDbContext);
                OsharpOptions osharpOptions = provider.GetOSharpOptions();
                OsharpDbContextOptions osharpDbContextOptions = osharpOptions?.GetDbContextOptions(dbContextType);
                if (osharpDbContextOptions == null)
                {
                    throw new OsharpException($"无法找到数据上下文“{dbContextType.DisplayName()}”的配置信息");
                }

                //启用延迟加载
                if (osharpDbContextOptions.LazyLoadingProxiesEnabled)
                {
                    builder = builder.UseLazyLoadingProxies();
                }
                DatabaseType databaseType = osharpDbContextOptions.DatabaseType;

                //处理数据库驱动差异处理
                IDbContextOptionsBuilderDriveHandler driveHandler = provider.GetServices <IDbContextOptionsBuilderDriveHandler>()
                                                                    .FirstOrDefault(m => m.Type == databaseType);
                if (driveHandler == null)
                {
                    throw new OsharpException($"无法解析类型为“{databaseType}”的 {typeof(IDbContextOptionsBuilderDriveHandler).DisplayName()} 实例");
                }

                ScopedDictionary scopedDictionary = provider.GetService <ScopedDictionary>();
                string key = $"DnConnection_{osharpDbContextOptions.ConnectionString}";
                DbConnection existingDbConnection = scopedDictionary.GetValue <DbConnection>(key);
                builder = driveHandler.Handle(builder, osharpDbContextOptions.ConnectionString, existingDbConnection);

                //使用模型缓存
                DbContextModelCache modelCache = provider.GetService <DbContextModelCache>();
                IModel model = modelCache?.Get(dbContextType);
                if (model != null)
                {
                    builder = builder.UseModel(model);
                }

                //额外的选项
                optionsAction?.Invoke(provider, builder);
            });
            return(services);
        }
Пример #5
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            OSharpOptions          options        = provider.GetOSharpOptions();
            OSharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(TDbContext));

            if (contextOptions?.DatabaseType != DatabaseType)
            {
                return;
            }

            using (IServiceScope scope = provider.CreateScope())
            {
                TDbContext context = CreateDbContext(scope.ServiceProvider);
                if (context != null && contextOptions.AutoMigrationEnabled)
                {
                    context.CheckAndMigration();
                    DbContextModelCache modelCache = scope.ServiceProvider.GetService <DbContextModelCache>();
                    modelCache?.Set(context.GetType(), context.Model);
                }
            }

            IsEnabled = true;
        }
Пример #6
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            OsharpOptions          options        = provider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(TDbContext));

            if (contextOptions?.DatabaseType != DatabaseType)
            {
                return;
            }

            ILogger logger = provider.GetLogger(GetType());

            using (IServiceScope scope = provider.CreateScope())
            {
                TDbContext context = CreateDbContext(scope.ServiceProvider);
                if (context != null && contextOptions.AutoMigrationEnabled)
                {
                    context.CheckAndMigration(logger);
                    DbContextModelCache modelCache = scope.ServiceProvider.GetService <DbContextModelCache>();
                    modelCache?.Set(context.GetType(), context.Model);
                }
            }

            //初始化种子数据,只初始化当前上下文的种子数据
            IEntityManager entityManager = provider.GetService <IEntityManager>();

            Type[] entityTypes = entityManager.GetEntityRegisters(typeof(TDbContext)).Select(m => m.EntityType).Distinct().ToArray();
            IEnumerable <ISeedDataInitializer> seedDataInitializers = provider.GetServices <ISeedDataInitializer>()
                                                                      .Where(m => entityTypes.Contains(m.EntityType)).OrderBy(m => m.Order);

            foreach (ISeedDataInitializer initializer in seedDataInitializers)
            {
                initializer.Initialize();
            }

            IsEnabled = true;
        }