From b2fe5c344f39886bed6156332e2ad8cc55a49921 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 27 Aug 2020 14:53:02 +0800 Subject: [PATCH] Improved --- .../Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj | 2 +- .../Volo/Abp/MongoDB/AbpMongoDbContext.cs | 6 +++ .../Volo/Abp/MongoDB/AbpMongoDbModule.cs | 42 +++++++++++++++++-- .../AbpMongoDbConventionalRegistrar.cs | 27 ++++++++++++ .../UnitOfWorkMongoDbContextProvider.cs | 27 ++++++++++-- .../OrganizationUnitRepository_Tests.cs | 2 +- 6 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj index 8d2942c145..e2f589b399 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj +++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs index ab18d8cde6..e961fdf256 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContext.cs @@ -29,6 +29,12 @@ namespace Volo.Abp.MongoDB return Database.GetCollection(GetCollectionName()); } + public virtual void InitializeCollections(IMongoDatabase database) + { + Database = database; + ModelSource.GetModel(this); + } + protected virtual string GetCollectionName() { return GetEntityModel().CollectionName; diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs index e36e972954..bb35883f7c 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs @@ -1,7 +1,12 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using MongoDB.Driver; +using Volo.Abp.Data; using Volo.Abp.Domain; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Modularity; +using Volo.Abp.MongoDB.DependencyInjection; using Volo.Abp.Uow.MongoDB; namespace Volo.Abp.MongoDB @@ -9,22 +14,53 @@ namespace Volo.Abp.MongoDB [DependsOn(typeof(AbpDddDomainModule))] public class AbpMongoDbModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddConventionalRegistrar(new AbpMongoDbConventionalRegistrar()); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.TryAddTransient( typeof(IMongoDbContextProvider<>), typeof(UnitOfWorkMongoDbContextProvider<>) ); - + context.Services.TryAddTransient( typeof(IMongoDbRepositoryFilterer<>), typeof(MongoDbRepositoryFilterer<>) ); - + context.Services.TryAddTransient( typeof(IMongoDbRepositoryFilterer<,>), typeof(MongoDbRepositoryFilterer<,>) ); } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + InitializeAllCollections(context.ServiceProvider); + } + + private void InitializeAllCollections(IServiceProvider serviceProvider) + { + var dbContexts = serviceProvider.GetServices(); + var connectionStringResolver = serviceProvider.GetService(); + + foreach (var dbContext in dbContexts) + { + var connectionString = connectionStringResolver.Resolve(ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType())); + var mongoUrl = new MongoUrl(connectionString); + var databaseName = mongoUrl.DatabaseName; + var client = new MongoClient(mongoUrl); + + if (databaseName.IsNullOrWhiteSpace()) + { + databaseName = ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()); + } + + (dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName)); + } + } } } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs new file mode 100644 index 0000000000..cb1ed7ea54 --- /dev/null +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/AbpMongoDbConventionalRegistrar.cs @@ -0,0 +1,27 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.MongoDB.DependencyInjection +{ + public class AbpMongoDbConventionalRegistrar : DefaultConventionalRegistrar + { + public override void AddType(IServiceCollection services, Type type) + { + if (!typeof(IAbpMongoDbContext).IsAssignableFrom(type) || type == typeof(AbpMongoDbContext)) + { + return; + } + + var dependencyAttribute = GetDependencyAttributeOrNull(type); + var lifeTime = GetLifeTimeOrNull(type, dependencyAttribute); + + if (lifeTime == null) + { + return; + } + + services.Add(ServiceDescriptor.Describe(typeof(IAbpMongoDbContext), type, ServiceLifetime.Transient)); + } + } +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs index 893d80488d..0d9969ee51 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs @@ -43,7 +43,7 @@ namespace Volo.Abp.Uow.MongoDB //TODO: Create only single MongoDbClient per connection string in an application (extract MongoClientCache for example). var databaseApi = unitOfWork.GetOrAddDatabaseApi( dbContextKey, - () => new MongoDbDatabaseApi(CreateDbContext(unitOfWork,mongoUrl,databaseName))); + () => new MongoDbDatabaseApi(CreateDbContext(unitOfWork, mongoUrl, databaseName))); return ((MongoDbDatabaseApi) databaseApi).DbContext; } @@ -52,9 +52,29 @@ namespace Volo.Abp.Uow.MongoDB { var client = new MongoClient(mongoUrl); var database = client.GetDatabase(databaseName); - var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); if (unitOfWork.Options.IsTransactional) + { + return CreateDbContextWithTransaction(unitOfWork, mongoUrl, client, database); + } + + var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + dbContext.ToAbpMongoDbContext().InitializeDatabase(database, null); + + return dbContext; + } + + public TMongoDbContext CreateDbContextWithTransaction( + IUnitOfWork unitOfWork, + MongoUrl url, + MongoClient client, + IMongoDatabase database) + { + var transactionApiKey = $"MongoDb_{url}"; + var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi; + var dbContext = unitOfWork.ServiceProvider.GetRequiredService(); + + if (activeTransaction?.SessionHandle == null) { var session = client.StartSession(); @@ -65,7 +85,6 @@ namespace Volo.Abp.Uow.MongoDB session.StartTransaction(); - var transactionApiKey = $"MongoDb_{mongoUrl}"; unitOfWork.AddTransactionApi( transactionApiKey, new MongoDbTransactionApi(session) @@ -75,7 +94,7 @@ namespace Volo.Abp.Uow.MongoDB } else { - dbContext.ToAbpMongoDbContext().InitializeDatabase(database, null); + dbContext.ToAbpMongoDbContext().InitializeDatabase(database, activeTransaction.SessionHandle); } return dbContext; diff --git a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs index b017352f9e..dc134f9974 100644 --- a/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/OrganizationUnitRepository_Tests.cs @@ -5,7 +5,7 @@ using Xunit; namespace Volo.Abp.Identity.MongoDB { - [Collection(MongoTestCollection.Name)] + [Collection(MongoTestCollection.Name)] public class OrganizationUnitRepository_Tests : OrganizationUnitRepository_Tests { }