Browse Source

Merge branch 'dev' into maliming/identity-pro-features-settings

pull/7719/head
maliming 6 years ago
parent
commit
4174cdb3ad
  1. 38
      framework/src/Volo.Abp.Ddd.Domain/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs
  2. 3
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/AbpRepositoryConventionalRegistrar.cs
  3. 2
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs
  4. 12
      framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs
  5. 2
      framework/src/Volo.Abp.EntityFrameworkCore/Properties/AssemblyInfo.cs
  6. 33
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs
  7. 7
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/EfCoreDatabaseApi.cs
  8. 22
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
  9. 1
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/AbpMemoryDbModule.cs
  10. 15
      framework/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs
  11. 2
      framework/src/Volo.Abp.MongoDB/Properties/AssemblyInfo.cs
  12. 39
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbContextOptions.cs
  13. 10
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/MongoDbDatabaseApi.cs
  14. 20
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
  15. 26
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs
  16. 2
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/TestAppMongoDbContext.cs
  17. 2
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs
  18. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs
  19. 24
      modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs
  20. 7
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs
  21. 3
      modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs
  22. 4
      modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs
  23. 29
      modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs

38
framework/src/Volo.Abp.Ddd.Domain/Microsoft/Extensions/DependencyInjection/ServiceCollectionRepositoryExtensions.cs

@ -7,32 +7,36 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionRepositoryExtensions
{
public static IServiceCollection AddDefaultRepository(this IServiceCollection services, Type entityType, Type repositoryImplementationType)
public static IServiceCollection AddDefaultRepository(
this IServiceCollection services,
Type entityType,
Type repositoryImplementationType,
bool replaceExisting = false)
{
//IReadOnlyBasicRepository<TEntity>
var readOnlyBasicRepositoryInterface = typeof(IReadOnlyBasicRepository<>).MakeGenericType(entityType);
if (readOnlyBasicRepositoryInterface.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(readOnlyBasicRepositoryInterface, repositoryImplementationType);
RegisterService(services, readOnlyBasicRepositoryInterface, repositoryImplementationType, replaceExisting);
//IReadOnlyRepository<TEntity>
var readOnlyRepositoryInterface = typeof(IReadOnlyRepository<>).MakeGenericType(entityType);
if (readOnlyRepositoryInterface.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(readOnlyRepositoryInterface, repositoryImplementationType);
RegisterService(services, readOnlyRepositoryInterface, repositoryImplementationType, replaceExisting);
}
//IBasicRepository<TEntity>
var basicRepositoryInterface = typeof(IBasicRepository<>).MakeGenericType(entityType);
if (basicRepositoryInterface.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(basicRepositoryInterface, repositoryImplementationType);
RegisterService(services, basicRepositoryInterface, repositoryImplementationType, replaceExisting);
//IRepository<TEntity>
var repositoryInterface = typeof(IRepository<>).MakeGenericType(entityType);
if (repositoryInterface.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(repositoryInterface, repositoryImplementationType);
RegisterService(services, repositoryInterface, repositoryImplementationType, replaceExisting);
}
}
}
@ -44,26 +48,26 @@ namespace Microsoft.Extensions.DependencyInjection
var readOnlyBasicRepositoryInterfaceWithPk = typeof(IReadOnlyBasicRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (readOnlyBasicRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(readOnlyBasicRepositoryInterfaceWithPk, repositoryImplementationType);
RegisterService(services, readOnlyBasicRepositoryInterfaceWithPk, repositoryImplementationType, replaceExisting);
//IReadOnlyRepository<TEntity, TKey>
var readOnlyRepositoryInterfaceWithPk = typeof(IReadOnlyRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (readOnlyRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(readOnlyRepositoryInterfaceWithPk, repositoryImplementationType);
RegisterService(services, readOnlyRepositoryInterfaceWithPk, repositoryImplementationType, replaceExisting);
}
//IBasicRepository<TEntity, TKey>
var basicRepositoryInterfaceWithPk = typeof(IBasicRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (basicRepositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(basicRepositoryInterfaceWithPk, repositoryImplementationType);
RegisterService(services, basicRepositoryInterfaceWithPk, repositoryImplementationType, replaceExisting);
//IRepository<TEntity, TKey>
var repositoryInterfaceWithPk = typeof(IRepository<,>).MakeGenericType(entityType, primaryKeyType);
if (repositoryInterfaceWithPk.IsAssignableFrom(repositoryImplementationType))
{
services.TryAddTransient(repositoryInterfaceWithPk, repositoryImplementationType);
RegisterService(services, repositoryInterfaceWithPk, repositoryImplementationType, replaceExisting);
}
}
}
@ -71,5 +75,21 @@ namespace Microsoft.Extensions.DependencyInjection
return services;
}
private static void RegisterService(
IServiceCollection services,
Type serviceType,
Type implementationType,
bool replaceExisting)
{
if (replaceExisting)
{
services.Replace(ServiceDescriptor.Transient(serviceType, implementationType));
}
else
{
services.TryAddTransient(serviceType, implementationType);
}
}
}
}

3
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/AbpRepositoryConventionalRegistrar.cs

@ -6,6 +6,9 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Domain.Repositories
{
/* Repositories are not injected by class by default.
* This class specializes repository registration to apply this rule.
*/
public class AbpRepositoryConventionalRegistrar : DefaultConventionalRegistrar
{
public static bool ExposeRepositoryClasses { get; set; }

2
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.Domain.Repositories
{
foreach (var customRepository in Options.CustomRepositories)
{
Options.Services.AddDefaultRepository(customRepository.Key, customRepository.Value);
Options.Services.AddDefaultRepository(customRepository.Key, customRepository.Value, replaceExisting: true);
}
if (Options.RegisterDefaultRepositories)

12
framework/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs

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

2
framework/src/Volo.Abp.EntityFrameworkCore/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.EntityFrameworkCore")]
[assembly: AssemblyTrademark("")]
[assembly: InternalsVisibleTo("Volo.Abp.EntityFrameworkCore.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

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

@ -7,19 +7,22 @@ namespace Volo.Abp.EntityFrameworkCore
{
public class AbpDbContextOptions
{
internal List<Action<AbpDbContextConfigurationContext>> DefaultPreConfigureActions { get; set; }
internal List<Action<AbpDbContextConfigurationContext>> DefaultPreConfigureActions { get; }
internal Action<AbpDbContextConfigurationContext> DefaultConfigureAction { get; set; }
internal Dictionary<Type, List<object>> PreConfigureActions { get; set; }
internal Dictionary<Type, List<object>> PreConfigureActions { get; }
internal Dictionary<Type, object> ConfigureActions { get; set; }
internal Dictionary<Type, object> ConfigureActions { get; }
internal Dictionary<Type, Type> DbContextReplacements { get; }
public AbpDbContextOptions()
{
DefaultPreConfigureActions = new List<Action<AbpDbContextConfigurationContext>>();
PreConfigureActions = new Dictionary<Type, List<object>>();
ConfigureActions = new Dictionary<Type, object>();
DbContextReplacements = new Dictionary<Type, Type>();
}
public void PreConfigure([NotNull] Action<AbpDbContextConfigurationContext> action)
@ -57,5 +60,29 @@ namespace Volo.Abp.EntityFrameworkCore
ConfigureActions[typeof(TDbContext)] = action;
}
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;
}
}
}
}
}

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

@ -4,12 +4,11 @@ using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.Uow.EntityFrameworkCore
{
public class EfCoreDatabaseApi<TDbContext> : IDatabaseApi, ISupportsSavingChanges
where TDbContext : IEfCoreDbContext
public class EfCoreDatabaseApi : IDatabaseApi, ISupportsSavingChanges
{
public TDbContext DbContext { get; }
public IEfCoreDbContext DbContext { get; }
public EfCoreDatabaseApi(TDbContext dbContext)
public EfCoreDatabaseApi(IEfCoreDbContext dbContext)
{
DbContext = dbContext;
}

22
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
@ -14,8 +15,6 @@ using Volo.Abp.Threading;
namespace Volo.Abp.Uow.EntityFrameworkCore
{
//TODO: Implement logic in DefaultDbContextResolver.Resolve in old ABP.
public class UnitOfWorkDbContextProvider<TDbContext> : IDbContextProvider<TDbContext>
where TDbContext : IEfCoreDbContext
{
@ -25,17 +24,20 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
private readonly ICurrentTenant _currentTenant;
private readonly AbpDbContextOptions _options;
public UnitOfWorkDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
ICancellationTokenProvider cancellationTokenProvider,
ICurrentTenant currentTenant)
ICurrentTenant currentTenant,
IOptions<AbpDbContextOptions> options)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
_currentTenant = currentTenant;
_options = options.Value;
Logger = NullLogger<UnitOfWorkDbContextProvider<TDbContext>>.Instance;
}
@ -63,15 +65,16 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName<TDbContext>();
var connectionString = ResolveConnectionString(connectionStringName);
var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TDbContext));
var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}";
var databaseApi = unitOfWork.GetOrAddDatabaseApi(
dbContextKey,
() => new EfCoreDatabaseApi<TDbContext>(
() => new EfCoreDatabaseApi(
CreateDbContext(unitOfWork, connectionStringName, connectionString)
));
return ((EfCoreDatabaseApi<TDbContext>)databaseApi).DbContext;
return (TDbContext)((EfCoreDatabaseApi)databaseApi).DbContext;
}
public async Task<TDbContext> GetDbContextAsync()
@ -85,20 +88,21 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName<TDbContext>();
var connectionString = await ResolveConnectionStringAsync(connectionStringName);
var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
var targetDbContextType = _options.GetReplacedTypeOrSelf(typeof(TDbContext));
var dbContextKey = $"{targetDbContextType.FullName}_{connectionString}";
var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
if (databaseApi == null)
{
databaseApi = new EfCoreDatabaseApi<TDbContext>(
databaseApi = new EfCoreDatabaseApi(
await CreateDbContextAsync(unitOfWork, connectionStringName, connectionString)
);
unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
}
return ((EfCoreDatabaseApi<TDbContext>)databaseApi).DbContext;
return (TDbContext)((EfCoreDatabaseApi)databaseApi).DbContext;
}
private TDbContext CreateDbContext(IUnitOfWork unitOfWork, string connectionStringName, string connectionString)

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")]

26
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs

@ -1,9 +1,11 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Shouldly;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.TestApp.EntityFrameworkCore;
using Volo.Abp.Uow;
using Xunit;
@ -13,24 +15,40 @@ namespace Volo.Abp.EntityFrameworkCore
public class DbContext_Replace_Tests : EntityFrameworkCoreTestBase
{
private readonly IBasicRepository<ThirdDbContextDummyEntity, Guid> _dummyRepository;
private readonly IPersonRepository _personRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly AbpDbContextOptions _options;
public DbContext_Replace_Tests()
{
_dummyRepository = ServiceProvider.GetRequiredService<IBasicRepository<ThirdDbContextDummyEntity, Guid>>();
_unitOfWorkManager = ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
_dummyRepository = GetRequiredService<IBasicRepository<ThirdDbContextDummyEntity, Guid>>();
_personRepository = GetRequiredService<IPersonRepository>();
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>();
_options = GetRequiredService<IOptions<AbpDbContextOptions>>().Value;
}
[Fact]
public async Task Should_Replace_DbContext()
{
_options.GetReplacedTypeOrSelf(typeof(IThirdDbContext)).ShouldBe(typeof(TestAppDbContext));
(ServiceProvider.GetRequiredService<IThirdDbContext>() is TestAppDbContext).ShouldBeTrue();
using (var uow = _unitOfWorkManager.Begin())
{
((await _dummyRepository.GetDbContextAsync()) is IThirdDbContext).ShouldBeTrue();
((await _dummyRepository.GetDbContextAsync()) is TestAppDbContext).ShouldBeTrue();
var instance1 = await _dummyRepository.GetDbContextAsync();
(instance1 is IThirdDbContext).ShouldBeTrue();
var instance2 = await _dummyRepository.GetDbContextAsync();
(instance2 is TestAppDbContext).ShouldBeTrue();
var instance3 = await _personRepository.GetDbContextAsync();
(instance3 is TestAppDbContext).ShouldBeTrue();
// All instances should be the same!
instance3.ShouldBe(instance1);
instance3.ShouldBe(instance2);
await uow.CompleteAsync();
}
}

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);

2
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs → modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateBlogPostDto.cs

@ -5,7 +5,7 @@ using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs
{
public class CreateUpdateBlogPostDto
public class CreateBlogPostDto
{
[Required]
public Guid BlogId { get; set; }

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs

@ -11,7 +11,8 @@ namespace Volo.CmsKit.Admin.Blogs
BlogPostDto,
Guid,
PagedAndSortedResultRequestDto,
CreateUpdateBlogPostDto>
CreateBlogPostDto,
UpdateBlogPostDto>
{
Task<BlogPostDto> GetBySlugAsync(string blogSlug, string slug);

24
modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/UpdateBlogPostDto.cs

@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
using Volo.CmsKit.Blogs;
namespace Volo.CmsKit.Admin.Blogs
{
public class UpdateBlogPostDto
{
[Required]
[DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))]
public string Title { get; set; }
[Required]
[DynamicStringLength(
typeof(BlogPostConsts),
nameof(BlogPostConsts.MaxSlugLength),
nameof(BlogPostConsts.MinSlugLength))]
public string Slug { get; set; }
[DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))]
public string ShortDescription { get; set; }
}
}

7
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs

@ -23,7 +23,8 @@ namespace Volo.CmsKit.Admin.Blogs
BlogPostDto,
Guid,
PagedAndSortedResultRequestDto,
CreateUpdateBlogPostDto>
CreateBlogPostDto,
UpdateBlogPostDto>
, IBlogPostAdminAppService
{
protected readonly IBlogPostManager BlogPostManager;
@ -63,7 +64,7 @@ namespace Volo.CmsKit.Admin.Blogs
}
[Authorize(CmsKitAdminPermissions.BlogPosts.Create)]
public override async Task<BlogPostDto> CreateAsync(CreateUpdateBlogPostDto input)
public override async Task<BlogPostDto> CreateAsync(CreateBlogPostDto input)
{
_ = await UserLookupService.GetByIdAsync(CurrentUser.GetId());
@ -80,7 +81,7 @@ namespace Volo.CmsKit.Admin.Blogs
}
[Authorize(CmsKitAdminPermissions.BlogPosts.Update)]
public override async Task<BlogPostDto> UpdateAsync(Guid id, CreateUpdateBlogPostDto input)
public override async Task<BlogPostDto> UpdateAsync(Guid id, UpdateBlogPostDto input)
{
var blogPost = await BlogPostRepository.GetAsync(id);

3
modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs

@ -24,7 +24,8 @@ namespace Volo.CmsKit.Admin
CreateMap<ContentUpdateDto, Content>(MemberList.Source);
CreateMap<BlogPost, BlogPostDto>(MemberList.Destination);
CreateMap<CreateUpdateBlogPostDto, BlogPost>(MemberList.Source);
CreateMap<CreateBlogPostDto, BlogPost>(MemberList.Source);
CreateMap<UpdateBlogPostDto, BlogPost>(MemberList.Source);
CreateMap<Blog, BlogDto>(MemberList.Destination)
.ReverseMap();

4
modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs

@ -31,7 +31,7 @@ namespace Volo.CmsKit.Admin.Blogs
[HttpPost]
[Authorize(CmsKitAdminPermissions.BlogPosts.Create)]
public virtual Task<BlogPostDto> CreateAsync(CreateUpdateBlogPostDto input)
public virtual Task<BlogPostDto> CreateAsync(CreateBlogPostDto input)
{
return BlogPostAdminAppService.CreateAsync(input);
}
@ -107,7 +107,7 @@ namespace Volo.CmsKit.Admin.Blogs
[HttpPut]
[Route("{id}")]
[Authorize(CmsKitAdminPermissions.BlogPosts.Update)]
public virtual Task<BlogPostDto> UpdateAsync(Guid id, CreateUpdateBlogPostDto input)
public virtual Task<BlogPostDto> UpdateAsync(Guid id, UpdateBlogPostDto input)
{
return BlogPostAdminAppService.UpdateAsync(id, input);
}

29
modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs

@ -31,7 +31,7 @@ namespace Volo.CmsKit.Blogs
var slug = "my-awesome-new-post";
var shortDescription = "This blog is all about awesomeness 🤗!";
var created = await blogPostAdminAppService.CreateAsync(new CreateUpdateBlogPostDto
var created = await blogPostAdminAppService.CreateAsync(new CreateBlogPostDto
{
BlogId = cmsKitTestData.Blog_Id,
Title = title,
@ -55,7 +55,7 @@ namespace Volo.CmsKit.Blogs
var slug = "another-my-awesome-new-post";
var shortDescription = "This blog is all about awesomeness 🤗!";
var dto = new CreateUpdateBlogPostDto
var dto = new CreateBlogPostDto
{
// Non-existing Id
BlogId = Guid.NewGuid(),
@ -137,9 +137,8 @@ namespace Volo.CmsKit.Blogs
var title = "[Solved] Another Blog Post";
var slug = "another-short-blog-post";
await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, new CreateUpdateBlogPostDto
await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, new UpdateBlogPostDto
{
BlogId = cmsKitTestData.Blog_Id,
ShortDescription = shortDescription,
Title = title,
Slug = slug,
@ -152,31 +151,11 @@ namespace Volo.CmsKit.Blogs
blogPost.Slug.ShouldBe(slug);
}
[Fact]
public async Task UpdateAsync_ShouldThrowException_WhileChangingWithNonExistingBlogId()
{
var nonExistingId = Guid.NewGuid();
var dto = new CreateUpdateBlogPostDto
{
BlogId = nonExistingId,
Title = cmsKitTestData.Page_2_Title,
Slug = cmsKitTestData.BlogPost_2_Slug
};
var exception = await Should.ThrowAsync<EntityNotFoundException>(async () =>
await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, dto));
exception.EntityType.ShouldBe(typeof(Blog));
exception.Id.ShouldBe(nonExistingId);
}
[Fact]
public async Task UpdateAsync_ShouldThrowException_WhileUpdatingWithAlreadyExistingSlug()
{
var dto = new CreateUpdateBlogPostDto
var dto = new UpdateBlogPostDto
{
BlogId = cmsKitTestData.Blog_Id,
Title = "Some new title",
Slug = cmsKitTestData.BlogPost_1_Slug
};

Loading…
Cancel
Save