Browse Source

Implemented #7737 for MongoDB: Should return the same instance in th same UOW for replaced DbContexts.

pull/7742/head
Halil İbrahim Kalkan 6 years ago
parent
commit
819a4488ba
  1. 15
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs
  2. 1
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs
  3. 1
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs
  4. 15
      framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs
  5. 2
      framework/src/Volo.Abp.MongoDB/Properties/AssemblyInfo.cs
  6. 39
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContextOptions.cs
  7. 10
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbDatabaseApi.cs
  8. 20
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
  9. 2
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs

15
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs

@ -63,15 +63,24 @@ namespace Volo.Abp.EntityFrameworkCore
internal Type GetReplacedTypeOrSelf(Type dbContextType)
{
var replacementType = dbContextType;
while (true)
{
if (DbContextReplacements.TryGetValue(dbContextType, out var foundType))
if (DbContextReplacements.TryGetValue(replacementType, out var foundType))
{
dbContextType = foundType;
if (foundType == dbContextType)
{
throw new AbpException(
"Circular DbContext replacement found for " +
dbContextType.AssemblyQualifiedName
);
}
replacementType = foundType;
}
else
{
return dbContextType;
return replacementType;
}
}
}

1
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs

@ -1,6 +1,5 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.Uow.EntityFrameworkCore

1
framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs

@ -1,7 +1,6 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Domain;
using Volo.Abp.Domain.Repositories.MemoryDb;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
using Volo.Abp.Uow.MemoryDb;

15
framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs

@ -17,6 +17,21 @@ namespace Microsoft.Extensions.DependencyInjection
{
services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TMongoDbContext)));
}
foreach (var dbContextType in options.ReplacedDbContextTypes)
{
services.Replace(
ServiceDescriptor.Transient(
dbContextType,
sp => sp.GetRequiredService(typeof(TMongoDbContext))
)
);
services.Configure<AbpMongoDbContextOptions>(opts =>
{
opts.DbContextReplacements[dbContextType] = typeof(TMongoDbContext);
});
}
new MongoDbRepositoryRegistrar(options).AddRepositories();

2
framework/src/Volo.Abp.MongoDB/Properties/AssemblyInfo.cs

@ -1,4 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -8,6 +9,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Volo.Abp.MongoDB")]
[assembly: AssemblyTrademark("")]
[assembly: InternalsVisibleTo("Volo.Abp.MongoDB.Tests")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from

39
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContextOptions.cs

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.MongoDB
{
public class AbpMongoDbContextOptions
{
internal Dictionary<Type, Type> DbContextReplacements { get; }
public AbpMongoDbContextOptions()
{
DbContextReplacements = new Dictionary<Type, Type>();
}
internal Type GetReplacedTypeOrSelf(Type dbContextType)
{
var replacementType = dbContextType;
while (true)
{
if (DbContextReplacements.TryGetValue(replacementType, out var foundType))
{
if (foundType == dbContextType)
{
throw new AbpException(
"Circular DbContext replacement found for " +
dbContextType.AssemblyQualifiedName
);
}
replacementType = foundType;
}
else
{
return replacementType;
}
}
}
}
}

10
framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbDatabaseApi.cs

@ -1,10 +1,12 @@
namespace Volo.Abp.Uow.MongoDB
using Volo.Abp.MongoDB;
namespace Volo.Abp.Uow.MongoDB
{
public class MongoDbDatabaseApi<TMongoDbContext> : IDatabaseApi
public class MongoDbDatabaseApi : IDatabaseApi
{
public TMongoDbContext DbContext { get; }
public IAbpMongoDbContext DbContext { get; }
public MongoDbDatabaseApi(TMongoDbContext dbContext)
public MongoDbDatabaseApi(IAbpMongoDbContext dbContext)
{
DbContext = dbContext;
}

20
framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using Volo.Abp.Data;
@ -22,17 +23,20 @@ namespace Volo.Abp.Uow.MongoDB
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
private readonly ICurrentTenant _currentTenant;
private readonly AbpMongoDbContextOptions _options;
public UnitOfWorkMongoDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
ICancellationTokenProvider cancellationTokenProvider,
ICurrentTenant currentTenant)
ICurrentTenant currentTenant,
IOptions<AbpMongoDbContextOptions> options)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
_currentTenant = currentTenant;
_options = options.Value;
Logger = NullLogger<UnitOfWorkMongoDbContextProvider<TMongoDbContext>>.Instance;
}
@ -59,7 +63,8 @@ namespace Volo.Abp.Uow.MongoDB
}
var connectionString = ResolveConnectionString();
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TMongoDbContext));
var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}";
var mongoUrl = new MongoUrl(connectionString);
var databaseName = mongoUrl.DatabaseName;
@ -71,9 +76,9 @@ 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<TMongoDbContext>(CreateDbContext(unitOfWork, mongoUrl, databaseName)));
() => new MongoDbDatabaseApi(CreateDbContext(unitOfWork, mongoUrl, databaseName)));
return ((MongoDbDatabaseApi<TMongoDbContext>) databaseApi).DbContext;
return (TMongoDbContext)((MongoDbDatabaseApi) databaseApi).DbContext;
}
public async Task<TMongoDbContext> GetDbContextAsync(CancellationToken cancellationToken = default)
@ -86,7 +91,8 @@ namespace Volo.Abp.Uow.MongoDB
}
var connectionString = await ResolveConnectionStringAsync();
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TMongoDbContext));
var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}";
var mongoUrl = new MongoUrl(connectionString);
var databaseName = mongoUrl.DatabaseName;
@ -99,7 +105,7 @@ namespace Volo.Abp.Uow.MongoDB
var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
if (databaseApi == null)
{
databaseApi = new MongoDbDatabaseApi<TMongoDbContext>(
databaseApi = new MongoDbDatabaseApi(
await CreateDbContextAsync(
unitOfWork,
mongoUrl,
@ -111,7 +117,7 @@ namespace Volo.Abp.Uow.MongoDB
unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
}
return ((MongoDbDatabaseApi<TMongoDbContext>) databaseApi).DbContext;
return (TMongoDbContext)((MongoDbDatabaseApi) databaseApi).DbContext;
}
[Obsolete("Use CreateDbContextAsync")]

2
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs

@ -15,7 +15,7 @@ namespace Volo.Abp.TestApp.MongoDB
public IMongoCollection<City> Cities => Collection<City>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
protected internal override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);

Loading…
Cancel
Save