예제 #1
0
        public static StartupConfig AddEventBusEFCoreStorage <TContext>(this StartupConfig config, Action <EFOptions> configure)
            where TContext : DbContext
        {
            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }
            EFOptions eFOptions = new EFOptions();

            configure(eFOptions);
            Action <PostgreSqlOptions> postgreSqlOptionsConfig = postgreSqlOptions =>
            {
                postgreSqlOptions.DbContextType = typeof(TContext);
                postgreSqlOptions.Schema        = eFOptions.Schema;
                using var scope = config.Services.BuildServiceProvider().CreateScope();
                var provider = scope.ServiceProvider;
                using var dbContext = (DbContext)provider.GetRequiredService(typeof(TContext));
                postgreSqlOptions.ConnectionString = dbContext.Database.GetDbConnection().ConnectionString;
            };

            config.Services.Configure(postgreSqlOptionsConfig);

            config.Services.AddScoped <IDbTransactionAdapter, PostgreSqlDbTransactionAdapter>();
            config.Services.AddSingleton <IEventStorage, PostgreSqlEventStorage>();
            config.Services.AddSingleton <IEventStorageInitializer, PostgreSqlEventStorageInitializer>();
            return(config);
        }
예제 #2
0
        /// <summary>
        /// mssql的连接信息
        /// </summary>
        /// <param name="eFOptions"></param>
        /// <returns></returns>
        private List <SlaveDbConnection> SqlServerSlaveDbConnection(EFOptions eFOptions)
        {
            //实例化连接信息
            List <SlaveDbConnection> slaveDbConnections = new List <SlaveDbConnection>();

            //遍历从库连接
            eFOptions.ReadOnlyConnectionString.ToList().ForEach(connectionString =>
            {
                var items = connectionString.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                //获取服务器
                var datasource = items.Where(a => a.Contains("data source")).FirstOrDefault()?.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
                if (datasource == null)
                {
                    datasource = items.Where(a => a.Contains("server")).FirstOrDefault()?.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
                }
                //获取ip和port
                var ipPort = datasource?[1].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                slaveDbConnections.Add(new SlaveDbConnection()
                {
                    ConnectionString = connectionString,
                    IsAvailable      = true,
                    HostName         = ipPort?[0],
                    Port             = Convert.ToInt32(ipPort?[1])
                });
            });
            return(slaveDbConnections);
        }
예제 #3
0
        /// <summary>
        /// 注入上下文的实例类型
        /// </summary>
        /// <returns></returns>
        public static IServiceCollection AddEFOption(this IServiceCollection services, Action <EFOptions> action)
        {
            EFOptions eFOptions = new EFOptions();

            action?.Invoke(eFOptions);
            if (eFOptions == null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            //注入上下文服务扩展
            Extension[eFOptions.DbContextType](services);

            //验证
            if (eFOptions.IsOpenMasterSlave && (eFOptions.ReadOnlyConnectionString == null || eFOptions.ReadOnlyConnectionString.Count() <= 0))
            {
                throw new ArgumentException("检测到开启了读写分离但是未指定只读的连接字符串!");
            }
            //写入连接字符串的线程安全集合
            if (eFOptions.IsOpenMasterSlave)
            {
                var slaveDbConnectionFactory = services.BuildServiceProvider().GetRequiredService <ISlaveDbConnectionFactory>();
                SlavePools.slaveConnec.TryAdd(eFOptions.DbContextType, slaveDbConnectionFactory.Get(eFOptions));
            }
            //注入配置服务
            services.Add(new ServiceDescriptor(MergeNamedType.Merge(eFOptions.DbContextType.Name, typeof(EFOptions)), serviceProvider => eFOptions, ServiceLifetime.Singleton));
            return(services);
        }
예제 #4
0
        public static IServiceCollection AddEFRepository(this IServiceCollection services, Action <EFOptions, IServiceProvider> configure,
                                                         params Assembly[] scanAssemblies)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            services.TryAddSingleton <IPluralize, Pluralizer>();

            services.AddSingleton(p =>
            {
                var options = new EFOptions();

                configure(options, p);

                if (options.OnConfiguring == null)
                {
                    throw new ArgumentException($"{nameof(EFOptions)}.{options.OnConfiguring} must be set.", nameof(configure));
                }

                return(options);
            });

            services.AddTransient <DbContext, EFContext>();

            services.TryAddScoped(p => new TransactionScope(TransactionScopeOption.RequiresNew,
                                                            new TransactionOptions
            {
                IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
            },
                                                            TransactionScopeAsyncFlowOption.Enabled));

            services.AddScoped <ITransaction, EFTransaction>();

            var builders = (scanAssemblies.Any() ?
                            scanAssemblies :
                            Assembly.GetEntryAssembly()?.GetReferencedAssemblies().Select(Assembly.Load)
                            .Union(new[] { Assembly.GetEntryAssembly() }))
                           .SelectMany(a => a.GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any(it => it == typeof(IEFModelBuilder))))
                           .ToArray();

            foreach (var builder in builders)
            {
                services.AddSingleton(typeof(IEFModelBuilder), builder);
            }

            return(services);
        }
예제 #5
0
        /// <summary>
        /// 注入EFCOre 上下文
        /// </summary>
        /// <typeparam name="TDbContext"></typeparam>
        /// <param name="eFOptions"></param>
        /// <param name="isDbContextPool">是否设置上下文池</param>
        /// <param name="pollSize">连接池数量</param>
        public static void UseEntityFramework <TDbContext, TSlaveDbContext>(this EFOptions eFOptions, bool isDbContextPool = true, int pollSize = 128) where TDbContext : DbContext where TSlaveDbContext : DbContext
        {
            if (eFOptions == null)
            {
                throw new ArgumentNullException("值不能为空!");
            }
            //获取上下文的实例
            if (eFOptions.DbContextType == null)
            {
                eFOptions.DbContextType = typeof(TDbContext);
            }
            void DbContextExtension(IServiceCollection serviceDescriptors)
            {
                //添加master 主库的上下文
                if (isDbContextPool)
                {
                    serviceDescriptors.AddDbContextPool <TDbContext>(eFOptions.ConfigureDbContext, pollSize);
                }
                else
                {
                    serviceDescriptors.AddDbContext <TDbContext>(eFOptions.ConfigureDbContext);
                }

                //验证是否开启读写分离
                if (eFOptions.IsOpenMasterSlave)
                {
                    if (typeof(TDbContext) == typeof(TSlaveDbContext))
                    {
                        throw new ArgumentException($"{nameof(TSlaveDbContext)}参数配置错误");
                    }
                    //添加slave 从库的上下文
                    if (isDbContextPool)
                    {
                        serviceDescriptors.AddDbContextPool <TSlaveDbContext>(eFOptions.ConfigureDbContext, pollSize);
                    }
                    else
                    {
                        serviceDescriptors.AddDbContext <TSlaveDbContext>(eFOptions.ConfigureDbContext);
                    }

                    eFOptions.SlaveDbContextType = typeof(TSlaveDbContext);
                }
                using (var server = serviceDescriptors.BuildServiceProvider().CreateScope())
                {
                    //获取master主库的连接字符串
                    var dbContent = server.ServiceProvider.GetRequiredService <TDbContext>();
                    eFOptions.WriteReadConnectionString = dbContent.Database.GetDbConnection().ConnectionString;
                }
            }

            Extension.Add(eFOptions.DbContextType, DbContextExtension);
        }
예제 #6
0
 /// <summary>
 /// 获取连接信息
 /// </summary>
 /// <param name="eFOptions"></param>
 /// <returns></returns>
 public List <SlaveDbConnection> Get(EFOptions eFOptions)
 {
     using var services  = serviceProvider.CreateScope();
     using var dbcontent = services.ServiceProvider.GetRequiredService(eFOptions.DbContextType) as DbContext;
     if (dbcontent.Database.ProviderName.EndsWith("MySql"))
     {
         return(MySqlSlaveDbConnection(eFOptions));
     }
     else if (dbcontent.Database.ProviderName.EndsWith("SqlServer"))
     {
         return(SqlServerSlaveDbConnection(eFOptions));
     }
     throw new ApplicationException("不支持的数据库类型");
 }
예제 #7
0
 public EFMQPublisher(MQTransOptions options
                      , IServiceProvider serviceProvider
                      , EFOptions mySqlEFOptions
                      , IMQGenerateMsgBody mQGenerateMsgBody
                      , IMQTransRepository repository
                      , IMQOperate mQOperate)
 {
     this.options           = options;
     this.serviceProvider   = serviceProvider;
     this.mySqlEFOptions    = mySqlEFOptions;
     this.mQGenerateMsgBody = mQGenerateMsgBody;
     this.repository        = repository;
     this.mQOperate         = mQOperate;
 }
예제 #8
0
        public static CapOptions UseEntityFramework <TContext>(this CapOptions options, Action <EFOptions> configure)
            where TContext : DbContext
        {
            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            var efOptions = new EFOptions {
                DbContextType = typeof(TContext)
            };

            configure(efOptions);

            options.RegisterExtension(new PostgreSqlCapOptionsExtension(configure));

            return(options);
        }
예제 #9
0
        /// <summary>
        /// mysql的连接信息
        /// </summary>
        /// <param name="eFOptions"></param>
        /// <returns></returns>
        private List <SlaveDbConnection> MySqlSlaveDbConnection(EFOptions eFOptions)
        {
            //实例化连接信息
            List <SlaveDbConnection> slaveDbConnections = new List <SlaveDbConnection>();

            //遍历从库连接
            eFOptions.ReadOnlyConnectionString.ToList().ForEach(connectionString =>
            {
                var items = connectionString.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);

                slaveDbConnections.Add(new SlaveDbConnection()
                {
                    ConnectionString = connectionString,
                    IsAvailable      = true,
                    HostName         = items.Where(a => a.Contains("datasource")).FirstOrDefault()?.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries)?[1],
                    Port             = Convert.ToInt32(items.Where(a => a.Contains("port")).FirstOrDefault()?.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries)?[1])
                });
            });
            return(slaveDbConnections);
        }
 public SqlServerMonitoringApi(IOptions <EFOptions> options, IDbContextProvider <TDbContext> dbContextProvider, IStorageInitializer initializer) : base(dbContextProvider)
 {
     _options = options.Value ?? throw new ArgumentNullException(nameof(options));
     _pubName = initializer.GetPublishedTableName();
     _recName = initializer.GetReceivedTableName();
 }
예제 #11
0
 public RepositoryInfrastructureBase(RepositoryOptions <TDbContext> _unitOfWorkOptions, IEFOptionsFactory eFOptionsFactory)
 {
     unitOfWorkOptions = _unitOfWorkOptions;
     options           = eFOptionsFactory.Get <TDbContext>();
 }
예제 #12
0
 /// <summary>
 /// 使用EF存储。也可用Dapper等框架,但需要开发
 /// </summary>
 /// <typeparam name="TDbContext"></typeparam>
 /// <param name="options"></param>
 /// <param name="mysqption"></param>
 public static void UseEF <TDbContext>(this MQTransOptions options, EFOptions mysqption)
 {
     mysqption.MQDbContext = typeof(TDbContext);
     options.Regist(new EFRegister <TDbContext>(mysqption));
 }
예제 #13
0
 /// <summary>
 /// 注入EFCOre 上下文
 /// </summary>
 /// <typeparam name="TDbContext"></typeparam>
 /// <param name="eFOptions"></param>
 /// <param name="isDbContextPool">是否设置上下文池</param>
 /// <param name="pollSize">连接池数量</param>
 public static void UseEntityFramework <TDbContext>(this EFOptions eFOptions, bool isDbContextPool = true, int pollSize = 128) where TDbContext : DbContext
 {
     eFOptions.UseEntityFramework <TDbContext, TDbContext>(isDbContextPool, pollSize);
 }
예제 #14
0
 public EFRegister(EFOptions mysqption)
 {
     this.mysqption = mysqption;
     this.mysqption.CheckNull();
 }