diff --git a/src/ShardingCore/Bootstrapers/EntityMetadataInitializer.cs b/src/ShardingCore/Bootstrapers/EntityMetadataInitializer.cs index f0869b9f..05b4ace9 100644 --- a/src/ShardingCore/Bootstrapers/EntityMetadataInitializer.cs +++ b/src/ShardingCore/Bootstrapers/EntityMetadataInitializer.cs @@ -37,7 +37,7 @@ namespace ShardingCore.Bootstrapers { private readonly IEntityType _entityType; private readonly string _virtualTableName; - private readonly IShardingConfigOption _shardingConfigOption; + private readonly IShardingConfigOption _shardingConfigOption; private readonly ITrackerManager _trackerManager; private readonly IVirtualDataSource _virtualDataSource; private readonly IVirtualTableManager _virtualTableManager; @@ -45,7 +45,7 @@ namespace ShardingCore.Bootstrapers private readonly ILogger> _logger; public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams - , IEnumerable shardingConfigOptions, + , IShardingConfigOption shardingConfigOption, ITrackerManager trackerManager,IVirtualDataSource virtualDataSource,IVirtualTableManager virtualTableManager, IEntityMetadataManager entityMetadataManager, ILogger> logger @@ -53,7 +53,7 @@ namespace ShardingCore.Bootstrapers { _entityType = entityMetadataEnsureParams.EntityType; _virtualTableName = entityMetadataEnsureParams.VirtualTableName; - _shardingConfigOption = shardingConfigOptions.FirstOrDefault(o=>o.ShardingDbContextType==typeof(TShardingDbContext)); + _shardingConfigOption = shardingConfigOption; _trackerManager = trackerManager; _virtualDataSource = virtualDataSource; _virtualTableManager = virtualTableManager; diff --git a/src/ShardingCore/Bootstrapers/ShardingBootstrapper.cs b/src/ShardingCore/Bootstrapers/ShardingBootstrapper.cs index b99b53b9..3b7f4d79 100644 --- a/src/ShardingCore/Bootstrapers/ShardingBootstrapper.cs +++ b/src/ShardingCore/Bootstrapers/ShardingBootstrapper.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using ShardingCore.Extensions; using ShardingCore.Jobs; using ShardingCore.Jobs.Abstaractions; @@ -16,13 +17,13 @@ namespace ShardingCore.Bootstrapers */ public class ShardingBootstrapper : IShardingBootstrapper { - private readonly IEnumerable _shardingConfigOptions; + private readonly IEnumerable _dbContextTypeCollectors; private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce(); - public ShardingBootstrapper(IServiceProvider serviceProvider) + public ShardingBootstrapper(IServiceProvider serviceProvider,IEnumerable dbContextTypeCollectors) { + _dbContextTypeCollectors = dbContextTypeCollectors; ShardingContainer.SetServices(serviceProvider); - _shardingConfigOptions = ShardingContainer.GetServices(); } /// /// @@ -31,9 +32,9 @@ namespace ShardingCore.Bootstrapers { if (!_doOnlyOnce.IsUnDo()) return; - foreach (var shardingConfigOption in _shardingConfigOptions) + foreach (var dbContextTypeCollector in _dbContextTypeCollectors) { - var instance = (IShardingDbContextBootstrapper)Activator.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(shardingConfigOption.ShardingDbContextType), shardingConfigOption); + var instance = (IShardingDbContextBootstrapper)ShardingContainer.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(dbContextTypeCollector.ShardingDbContextType)); instance.Init(); } diff --git a/src/ShardingCore/Bootstrapers/ShardingDbContextBootstrapper.cs b/src/ShardingCore/Bootstrapers/ShardingDbContextBootstrapper.cs index bdfe92c0..738c13a4 100644 --- a/src/ShardingCore/Bootstrapers/ShardingDbContextBootstrapper.cs +++ b/src/ShardingCore/Bootstrapers/ShardingDbContextBootstrapper.cs @@ -54,27 +54,25 @@ namespace ShardingCore.Bootstrapers /// public class ShardingDbContextBootstrapper : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext { - private readonly IShardingConfigOption _shardingConfigOption; - private readonly IRouteTailFactory _routeTailFactory; - private readonly IVirtualTableManager _virtualTableManager; + private readonly IShardingConfigOption _shardingConfigOption; private readonly IVirtualDataSource _virtualDataSource; private readonly IEntityMetadataManager _entityMetadataManager; - private readonly IShardingTableCreator _tableCreator; private readonly IParallelTableManager _parallelTableManager; private readonly IDataSourceInitializer _dataSourceInitializer; - private readonly ILogger> _logger; + private readonly Type _shardingDbContextType; - public ShardingDbContextBootstrapper(IShardingConfigOption shardingConfigOption) + public ShardingDbContextBootstrapper(IShardingConfigOption shardingConfigOption, + IEntityMetadataManager entityMetadataManager, + IVirtualDataSource virtualDataSource, + IParallelTableManager parallelTableManager, + IDataSourceInitializer dataSourceInitializer) { _shardingConfigOption = shardingConfigOption; - _routeTailFactory = ShardingContainer.GetService(); - _virtualTableManager = ShardingContainer.GetService>(); - _entityMetadataManager = ShardingContainer.GetService>(); - _tableCreator = ShardingContainer.GetService>(); - _virtualDataSource= ShardingContainer.GetService>(); - _parallelTableManager = ShardingContainer.GetService>(); - _dataSourceInitializer = ShardingContainer.GetService>(); - _logger = ShardingContainer.GetService>>(); + _shardingDbContextType = typeof(TShardingDbContext); + _entityMetadataManager = entityMetadataManager; + _virtualDataSource= virtualDataSource; + _parallelTableManager = parallelTableManager; + _dataSourceInitializer = dataSourceInitializer; } /// /// 初始化 @@ -94,7 +92,7 @@ namespace ShardingCore.Bootstrapers { //var dataSourceName = _virtualDataSource.DefaultDataSourceName; using var context = - (DbContext)serviceScope.ServiceProvider.GetService(_shardingConfigOption.ShardingDbContextType); + (DbContext)serviceScope.ServiceProvider.GetService(_shardingDbContextType); foreach (var entity in context.Model.GetEntityTypes()) { @@ -103,21 +101,9 @@ namespace ShardingCore.Bootstrapers if (_shardingConfigOption.HasVirtualDataSourceRoute(entityType) || _shardingConfigOption.HasVirtualTableRoute(entityType)) { - var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(typeof(TShardingDbContext), entityType); - var constructors - = entityMetadataInitializerType.GetTypeInfo().DeclaredConstructors - .Where(c => !c.IsStatic && c.IsPublic) - .ToArray(); - var @params = constructors[0].GetParameters().Select((o, i) => - { - if (i == 0) - { - return new EntityMetadataEnsureParams( entity); - } - - return ShardingContainer.GetService(o.ParameterType); - }).ToArray(); - var entityMetadataInitializer = (IEntityMetadataInitializer)Activator.CreateInstance(entityMetadataInitializerType, @params); + var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType); + + var entityMetadataInitializer = (IEntityMetadataInitializer)ShardingContainer.CreateInstanceWithInputParams(entityMetadataInitializerType, new EntityMetadataEnsureParams(entity)); entityMetadataInitializer.Initialize(); } } diff --git a/src/ShardingCore/Core/TrackerManagers/TrackerManager.cs b/src/ShardingCore/Core/TrackerManagers/TrackerManager.cs index 3c4d7002..1afc4549 100644 --- a/src/ShardingCore/Core/TrackerManagers/TrackerManager.cs +++ b/src/ShardingCore/Core/TrackerManagers/TrackerManager.cs @@ -16,12 +16,12 @@ namespace ShardingCore.Core.TrackerManagers */ public class TrackerManager: ITrackerManager where TShardingDbContext : DbContext, IShardingDbContext { - private readonly IShardingConfigOption _shardingConfigOption; + private readonly IShardingConfigOption _shardingConfigOption; private readonly ISet _dbContextModels = new HashSet(); - public TrackerManager(IEnumerable shardingConfigOptions) + public TrackerManager(IShardingConfigOption shardingConfigOption) { - _shardingConfigOption = shardingConfigOptions.FirstOrDefault(o=>o.ShardingDbContextType==typeof(TShardingDbContext)); + _shardingConfigOption = shardingConfigOption; } public bool AddDbContextModel(Type entityType) { diff --git a/src/ShardingCore/DIExtensions/ShardingCoreConfigEndBuilder.cs b/src/ShardingCore/DIExtensions/ShardingCoreConfigEndBuilder.cs index 00adebf5..8f124f55 100644 --- a/src/ShardingCore/DIExtensions/ShardingCoreConfigEndBuilder.cs +++ b/src/ShardingCore/DIExtensions/ShardingCoreConfigEndBuilder.cs @@ -59,7 +59,8 @@ namespace ShardingCore.DIExtensions public IServiceCollection End() { var services = _shardingCoreConfigBuilder.Services; - services.AddSingleton>(sp => + services.AddSingleton(sp => new DbContextTypeCollector()); + services.AddSingleton, ShardingConfigOption>(sp => _shardingCoreConfigBuilder.ShardingConfigOption); diff --git a/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs b/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs index d7a0cf26..74db6e56 100644 --- a/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs +++ b/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs @@ -35,16 +35,15 @@ namespace ShardingCore.DynamicDataSources private readonly IEntityMetadataManager _entityMetadataManager; private readonly IShardingTableCreator _tableCreator; private readonly ILogger> _logger; - private readonly IShardingConfigOption _shardingConfigOption; - public DataSourceInitializer(IEnumerable shardingConfigOptions, + private readonly IShardingConfigOption _shardingConfigOption; + public DataSourceInitializer(IShardingConfigOption shardingConfigOption, IRouteTailFactory routeTailFactory, IVirtualTableManager virtualTableManager, IEntityMetadataManager entityMetadataManager, IShardingTableCreator shardingTableCreator, IVirtualDataSource virtualDataSource, ILogger> logger) { - _shardingConfigOption = - shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext)) ?? throw new ArgumentNullException($"{nameof(IShardingConfigOption)} cant been registered {typeof(TShardingDbContext)}"); + _shardingConfigOption = shardingConfigOption; _routeTailFactory = routeTailFactory; _virtualTableManager = virtualTableManager; _entityMetadataManager = entityMetadataManager; diff --git a/src/ShardingCore/Extensions/ShardingReadWriteExtension.cs b/src/ShardingCore/Extensions/ShardingReadWriteExtension.cs index 5f150318..eff8fca8 100644 --- a/src/ShardingCore/Extensions/ShardingReadWriteExtension.cs +++ b/src/ShardingCore/Extensions/ShardingReadWriteExtension.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.ReadWriteConfigurations; @@ -83,21 +84,27 @@ namespace ShardingCore.Extensions { if (shardingDbContext is ISupportShardingReadWrite shardingReadWrite) { - var shardingReadWriteManager = ShardingContainer.GetService(); - var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContext.GetType()); - if (shardingReadWriteContext != null) + var shardingDbContextType = shardingDbContext.GetType(); + var shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(shardingDbContextType); + var useReadWrite=shardingConfigOption?.UseReadWrite ?? false; + if (useReadWrite) { - if (shardingReadWriteContext.DefaultPriority > shardingReadWrite.ReadWriteSeparationPriority) + var shardingReadWriteManager = ShardingContainer.GetService(); + var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContextType); + if (shardingReadWriteContext != null) { - return shardingReadWriteContext.DefaultReadEnable; + if (shardingReadWriteContext.DefaultPriority > shardingReadWrite.ReadWriteSeparationPriority) + { + return shardingReadWriteContext.DefaultReadEnable; + } + else + { + return shardingReadWrite.ReadWriteSeparation; + } } - else - { - return shardingReadWrite.ReadWriteSeparation; - } - } - return shardingReadWrite.ReadWriteSeparation; + return shardingReadWrite.ReadWriteSeparation; + } } return false; diff --git a/src/ShardingCore/IDbContextTypeCollector.cs b/src/ShardingCore/IDbContextTypeCollector.cs new file mode 100644 index 00000000..192377e7 --- /dev/null +++ b/src/ShardingCore/IDbContextTypeCollector.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using ShardingCore.Sharding.Abstractions; + +namespace ShardingCore +{ + public interface IDbContextTypeCollector + { + Type ShardingDbContextType { get; } + } + + public class DbContextTypeCollector : IDbContextTypeCollector + where TShardingDbContext : DbContext, IShardingDbContext + { + public DbContextTypeCollector() + { + ShardingDbContextType = typeof(TShardingDbContext); + } + public Type ShardingDbContextType { get; } + } +} diff --git a/src/ShardingCore/IShardingConfigOption.cs b/src/ShardingCore/IShardingConfigOption.cs index 383c31aa..43b028e5 100644 --- a/src/ShardingCore/IShardingConfigOption.cs +++ b/src/ShardingCore/IShardingConfigOption.cs @@ -18,7 +18,6 @@ namespace ShardingCore */ public interface IShardingConfigOption { - Type ShardingDbContextType { get;} bool UseReadWrite { get; } bool HasVirtualTableRoute(Type entityType); diff --git a/src/ShardingCore/Sharding/ActualConnectionStringManager.cs b/src/ShardingCore/Sharding/ActualConnectionStringManager.cs index 77cec9c8..edef802c 100644 --- a/src/ShardingCore/Sharding/ActualConnectionStringManager.cs +++ b/src/ShardingCore/Sharding/ActualConnectionStringManager.cs @@ -31,13 +31,16 @@ namespace ShardingCore.Sharding { _virtualDataSource=ShardingContainer.GetService>(); _connectionStringManager = ShardingContainer.GetService>(); - _readWriteOptions = ShardingContainer.GetService>(); _shardingReadWriteManager = ShardingContainer.GetService(); _useReadWriteSeparation = _connectionStringManager is ReadWriteConnectionStringManager; - if (_readWriteOptions != null) + if (_useReadWriteSeparation) { - ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority; - ReadWriteSeparation = _readWriteOptions.ReadWriteSupport; + _readWriteOptions = ShardingContainer.GetService>(); + if (_readWriteOptions != null) + { + ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority; + ReadWriteSeparation = _readWriteOptions.ReadWriteSupport; + } } } diff --git a/src/ShardingCore/Sharding/ParallelTables/IParallelTableManager`1.cs b/src/ShardingCore/Sharding/ParallelTables/IParallelTableManager`1.cs index 2e868c82..f4b87a49 100644 --- a/src/ShardingCore/Sharding/ParallelTables/IParallelTableManager`1.cs +++ b/src/ShardingCore/Sharding/ParallelTables/IParallelTableManager`1.cs @@ -8,7 +8,7 @@ using ShardingCore.Sharding.Abstractions; namespace ShardingCore.Sharding.ParallelTables { - internal interface IParallelTableManager : IParallelTableManager + public interface IParallelTableManager : IParallelTableManager where TShardingDbContext : DbContext, IShardingDbContext { diff --git a/src/ShardingCore/Sharding/ParallelTables/ParallelTableManager.cs b/src/ShardingCore/Sharding/ParallelTables/ParallelTableManager.cs index 7c775a06..98da1a1c 100644 --- a/src/ShardingCore/Sharding/ParallelTables/ParallelTableManager.cs +++ b/src/ShardingCore/Sharding/ParallelTables/ParallelTableManager.cs @@ -9,7 +9,7 @@ using ShardingCore.Sharding.Abstractions; namespace ShardingCore.Sharding.ParallelTables { - internal sealed class ParallelTableManager : IParallelTableManager + public sealed class ParallelTableManager : IParallelTableManager where TShardingDbContext : DbContext, IShardingDbContext { private readonly ISet _parallelTableConfigs = new HashSet(); diff --git a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs index 664b9b7d..23440577 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs @@ -20,6 +20,10 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions Type GetShardingDbContextType(); QueryCompilerExecutor GetQueryCompilerExecutor(); bool IsEnumerableQuery(); - bool IsParallelQuery(); + /// + /// 当前是否读写分离走读库(包括是否启用读写分离和是否当前的dbcontext启用了读库查询) + /// + /// + bool CurrentQueryReadConnection(); } } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs index f886741f..fbae0290 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs @@ -92,9 +92,9 @@ namespace ShardingCore.Sharding.ShardingExecutors { return _queryCompilerContext.GetShardingDbContextType(); } - public bool IsParallelQuery() + public bool CurrentQueryReadConnection() { - return _queryCompilerContext.IsParallelQuery(); + return _queryCompilerContext.CurrentQueryReadConnection(); } public QueryCompilerExecutor GetQueryCompilerExecutor() @@ -105,7 +105,7 @@ namespace ShardingCore.Sharding.ShardingExecutors if (hasQueryCompilerExecutor.Value) { var routeTailFactory = ShardingContainer.GetService(); - var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), IsParallelQuery(), routeTailFactory.Create(_tableRouteResults.First())); + var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First())); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression()); } } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs index 8faec78d..f4dd383a 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs @@ -36,8 +36,7 @@ namespace ShardingCore.Sharding.ShardingExecutors _queryExpression = queryExpression; _entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType)); - _shardingConfigOption = ShardingContainer.GetServices() - .FirstOrDefault(o => o.ShardingDbContextType == _shardingDbContextType); + _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType); } public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression) @@ -70,7 +69,7 @@ namespace ShardingCore.Sharding.ShardingExecutors return _shardingDbContextType; } - public bool IsParallelQuery() + public bool CurrentQueryReadConnection() { return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation(); } @@ -84,7 +83,7 @@ namespace ShardingCore.Sharding.ShardingExecutors var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService( typeof(IVirtualDataSource<>).GetGenericType0(_shardingDbContextType)); var routeTailFactory = ShardingContainer.GetService(); - var dbContext = _shardingDbContext.GetDbContext(virtualDataSource.DefaultDataSourceName, IsParallelQuery(), routeTailFactory.Create(string.Empty)); + var dbContext = _shardingDbContext.GetDbContext(virtualDataSource.DefaultDataSourceName, CurrentQueryReadConnection(), routeTailFactory.Create(string.Empty)); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, _queryExpression); } } diff --git a/src/ShardingCore/Sharding/StreamMergeContext.cs b/src/ShardingCore/Sharding/StreamMergeContext.cs index 0782afc6..532d9928 100644 --- a/src/ShardingCore/Sharding/StreamMergeContext.cs +++ b/src/ShardingCore/Sharding/StreamMergeContext.cs @@ -100,26 +100,9 @@ namespace ShardingCore.Sharding typeof(ITrackerManager<>).GetGenericType0(mergeQueryCompilerContext.GetShardingDbContextType())); _shardingComparer = (IShardingComparer)ShardingContainer.GetService(typeof(IShardingComparer<>).GetGenericType0(_shardingDbContext.GetType())); - _shardingConfigOption = ShardingContainer.GetServices() - .FirstOrDefault(o => o.ShardingDbContextType == mergeQueryCompilerContext.GetShardingDbContextType()); + _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(mergeQueryCompilerContext.GetShardingDbContextType()); _parallelDbContexts = new ConcurrentDictionary(); - //RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source); } - //public StreamMergeContext(IQueryable source,IEnumerable routeResults, - // IShardingParallelDbContextFactory shardingParallelDbContextFactory,IShardingScopeFactory shardingScopeFactory) - //{ - // _shardingParallelDbContextFactory = shardingParallelDbContextFactory; - // _shardingScopeFactory = shardingScopeFactory; - // _source = source; - // RouteResults = routeResults; - // var reWriteResult = new ReWriteEngine(source).ReWrite(); - // Skip = reWriteResult.Skip; - // Take = reWriteResult.Take; - // Orders = reWriteResult.Orders ?? Enumerable.Empty(); - // SelectContext = reWriteResult.SelectContext; - // GroupByContext = reWriteResult.GroupByContext; - // _reWriteSource = reWriteResult.ReWriteQueryable; - //} public void ReSetOrders(IEnumerable orders) { Orders = orders; @@ -250,7 +233,7 @@ namespace ShardingCore.Sharding /// public bool IsParallelQuery() { - return !_shardingConfigOption.AutoTrackEntity || MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.IsParallelQuery(); + return !_shardingConfigOption.AutoTrackEntity || MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.CurrentQueryReadConnection(); } /// diff --git a/src/ShardingCore/ShardingConfigOption.cs b/src/ShardingCore/ShardingConfigOption.cs index a0ca3174..4cf075fe 100644 --- a/src/ShardingCore/ShardingConfigOption.cs +++ b/src/ShardingCore/ShardingConfigOption.cs @@ -107,9 +107,6 @@ namespace ShardingCore ReadConnStringGetStrategy = readConnStringGetStrategy; } - - public Type ShardingDbContextType => typeof(TShardingDbContext); - /// /// 添加分表路由 /// diff --git a/src/ShardingCore/ShardingContainer.cs b/src/ShardingCore/ShardingContainer.cs index 5a6a584f..7b273bd8 100644 --- a/src/ShardingCore/ShardingContainer.cs +++ b/src/ShardingCore/ShardingContainer.cs @@ -1,13 +1,12 @@ -using System; -using System.Collections.Generic; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; -using ShardingCore.Core.VirtualDatabase.VirtualTables; -using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine; -using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine; using ShardingCore.Exceptions; using ShardingCore.Extensions; using ShardingCore.Sharding.Abstractions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; namespace ShardingCore { @@ -51,6 +50,71 @@ namespace ShardingCore { return ServiceProvider.GetService(serviceType); } + /// + /// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取的 + /// + /// + /// + /// + public static object CreateInstance(Type serviceType) + { + var constructors + = serviceType.GetTypeInfo().DeclaredConstructors + .Where(c => !c.IsStatic && c.IsPublic) + .ToArray(); + if (constructors.Length != 1) + { + throw new ArgumentException( + $"type :[{serviceType}] found more than one declared constructor "); + } + var @params = constructors[0].GetParameters().Select(x => ServiceProvider.GetService(x.ParameterType)) + .ToArray(); + return Activator.CreateInstance(serviceType, @params); + } + /// + /// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取并且也存在自行传入的参数,优先判断自行传入的参数 + /// + /// + /// + /// + /// + public static object CreateInstanceWithInputParams(Type serviceType,params object[] args) + { + var constructors + = serviceType.GetTypeInfo().DeclaredConstructors + .Where(c => !c.IsStatic && c.IsPublic) + .ToArray(); + + if (constructors.Length != 1) + { + throw new ArgumentException( + $"type :[{serviceType}] found more than one declared constructor "); + } + + var argIsNotEmpty = args.IsNotEmpty(); + var @params = constructors[0].GetParameters().Select(x => + { + if (argIsNotEmpty) + { + var arg = args.FirstOrDefault(o => o.GetType() == x.ParameterType); + if (arg != null) + return arg; + } + return ServiceProvider.GetService(x.ParameterType); + }) + .ToArray(); + return Activator.CreateInstance(serviceType, @params); + } + + public static IShardingConfigOption GetRequiredShardingConfigOption() + where TShardingDbContext : DbContext, IShardingDbContext + { + return (IShardingConfigOption)GetRequiredShardingConfigOption(typeof(TShardingDbContext)); + } + public static IShardingConfigOption GetRequiredShardingConfigOption(Type shardingDbContextType) + { + return (IShardingConfigOption)ServiceProvider.GetService(typeof(IShardingConfigOption<>).GetGenericType0(shardingDbContextType)); + } } } \ No newline at end of file diff --git a/src/ShardingCore/TableCreator/ShardingTableCreator.cs b/src/ShardingCore/TableCreator/ShardingTableCreator.cs index b0314de8..3844b10f 100644 --- a/src/ShardingCore/TableCreator/ShardingTableCreator.cs +++ b/src/ShardingCore/TableCreator/ShardingTableCreator.cs @@ -28,15 +28,14 @@ namespace ShardingCore.TableCreator { private readonly ILogger> _logger; private readonly IServiceProvider _serviceProvider; - private readonly IShardingConfigOption _shardingConfigOption; + private readonly IShardingConfigOption _shardingConfigOption; private readonly IRouteTailFactory _routeTailFactory; - public ShardingTableCreator(ILogger> logger, IServiceProvider serviceProvider, IEnumerable shardingConfigOptions, IRouteTailFactory routeTailFactory) + public ShardingTableCreator(ILogger> logger, IServiceProvider serviceProvider, IShardingConfigOption shardingConfigOption, IRouteTailFactory routeTailFactory) { _logger = logger; _serviceProvider = serviceProvider; - _shardingConfigOption = shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext)) - ?? throw new ArgumentNullException(typeof(TShardingDbContext).FullName); + _shardingConfigOption = shardingConfigOption; _routeTailFactory = routeTailFactory; }