diff --git a/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IServiceProviderAccessor.cs b/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IServiceProviderAccessor.cs index af290f2768..701b301084 100644 --- a/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IServiceProviderAccessor.cs +++ b/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IServiceProviderAccessor.cs @@ -1,11 +1,9 @@ using System; -using JetBrains.Annotations; namespace Volo.Abp.DependencyInjection { public interface IServiceProviderAccessor { - [NotNull] IServiceProvider ServiceProvider { get; } } } \ No newline at end of file diff --git a/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs b/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs index 4b3f30937e..00143d3553 100644 --- a/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/CommonDbContextRegistrationOptions.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; -using Volo.Abp.Reflection; namespace Volo.Abp.DependencyInjection { @@ -13,6 +13,8 @@ namespace Volo.Abp.DependencyInjection { public Type OriginalDbContextType { get; } + public IServiceCollection Services { get; } + public List ReplacedDbContextTypes { get; } public Type DefaultRepositoryDbContextType { get; protected set; } @@ -29,9 +31,10 @@ namespace Volo.Abp.DependencyInjection public bool SpecifiedDefaultRepositoryTypes => DefaultRepositoryImplementationType != null && DefaultRepositoryImplementationTypeWithouTKey != null; - protected CommonDbContextRegistrationOptions(Type originalDbContextType) + protected CommonDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) { OriginalDbContextType = originalDbContextType; + Services = services; DefaultRepositoryDbContextType = originalDbContextType; CustomRepositories = new Dictionary(); ReplacedDbContextTypes = new List(); diff --git a/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs index 837f7bc110..db715533f1 100644 --- a/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/ICommonDbContextRegistrationOptionsBuilder.cs @@ -1,10 +1,13 @@ using System; using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection { public interface ICommonDbContextRegistrationOptionsBuilder { + IServiceCollection Services { get; } + /// /// Registers default repositories for this DbContext. /// diff --git a/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs b/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs index 2af9307f5b..e1962fb416 100644 --- a/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs +++ b/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs @@ -1,13 +1,17 @@ -using System.Threading; +using System; +using System.Threading; using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; using Volo.Abp.Threading; namespace Volo.Abp.Domain.Repositories { - public abstract class BasicRepositoryBase : IBasicRepository + public abstract class BasicRepositoryBase : IBasicRepository, IServiceProviderAccessor where TEntity : class, IEntity { + public IServiceProvider ServiceProvider { get; set; } + public ICancellationTokenProvider CancellationTokenProvider { get; set; } protected BasicRepositoryBase() diff --git a/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs b/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs index 9c7cda7f71..5451ab977f 100644 --- a/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs +++ b/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryRegistrarBase.cs @@ -16,20 +16,20 @@ namespace Volo.Abp.Domain.Repositories Options = options; } - public virtual void AddRepositories(IServiceCollection services) + public virtual void AddRepositories() { foreach (var customRepository in Options.CustomRepositories) { - services.AddDefaultRepository(customRepository.Key, customRepository.Value); + Options.Services.AddDefaultRepository(customRepository.Key, customRepository.Value); } if (Options.RegisterDefaultRepositories) { - RegisterDefaultRepositories(services); + RegisterDefaultRepositories(); } } - protected virtual void RegisterDefaultRepositories(IServiceCollection services) + protected virtual void RegisterDefaultRepositories() { foreach (var entityType in GetEntityTypes(Options.OriginalDbContextType)) { @@ -38,13 +38,13 @@ namespace Volo.Abp.Domain.Repositories continue; } - RegisterDefaultRepository(services, entityType); + RegisterDefaultRepository(entityType); } } - protected virtual void RegisterDefaultRepository(IServiceCollection services, Type entityType) + protected virtual void RegisterDefaultRepository(Type entityType) { - services.AddDefaultRepository( + Options.Services.AddDefaultRepository( entityType, GetDefaultRepositoryImplementationType(entityType) ); diff --git a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs index 80cb4e22a6..d39c5db121 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Microsoft/Extensions/DependencyInjection/AbpEfCoreServiceCollectionExtensions.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.DependencyInjection { services.AddMemoryCache(); - var options = new AbpDbContextRegistrationOptions(typeof(TDbContext)); + var options = new AbpDbContextRegistrationOptions(typeof(TDbContext), services); optionsBuilder?.Invoke(options); services.TryAddTransient(DbContextOptionsFactory.Create); @@ -24,8 +24,7 @@ namespace Microsoft.Extensions.DependencyInjection services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TDbContext))); } - new EfCoreRepositoryRegistrar(options) - .AddRepositories(services); + new EfCoreRepositoryRegistrar(options).AddRepositories(); return services; } diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs index d7d8c375c0..edcdb5570d 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs @@ -5,8 +5,11 @@ using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.Domain.Entities; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.DependencyInjection; namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore { @@ -20,11 +23,21 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext(); + protected virtual EntityOptions EntityOptions => _entityOptionsLazy.Value; + private readonly IDbContextProvider _dbContextProvider; + private readonly Lazy> _entityOptionsLazy; public EfCoreRepository(IDbContextProvider dbContextProvider) { _dbContextProvider = dbContextProvider; + + _entityOptionsLazy = new Lazy>( + () => ServiceProvider + .GetRequiredService>() + .Value + .GetOrNull() ?? EntityOptions.Empty + ); } public override TEntity Insert(TEntity entity, bool autoSave = false) @@ -145,6 +158,16 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore { await DbContext.Entry(entity).Reference(propertyExpression).LoadAsync(GetCancellationToken(cancellationToken)); } + + protected override IQueryable IncludeDetails(IQueryable queryable) + { + if (EntityOptions.IncludeDetailsFunc == null) + { + return base.IncludeDetails(queryable); + } + + return EntityOptions.IncludeDetailsFunc(queryable); + } } public class EfCoreRepository : EfCoreRepository, diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs index 484ceaa3ba..be5f504ffd 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/AbpDbContextRegistrationOptions.cs @@ -1,14 +1,27 @@ using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; namespace Volo.Abp.EntityFrameworkCore.DependencyInjection { public class AbpDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IAbpDbContextRegistrationOptionsBuilder { - public AbpDbContextRegistrationOptions(Type originalDbContextType) - : base(originalDbContextType) + public Dictionary EntityOptions { get; } + + public AbpDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) + : base(originalDbContextType, services) { + EntityOptions = new Dictionary(); + } + public void Entity(Action> optionsAction) where TEntity : IEntity + { + Services.Configure(options => + { + options.Entity(optionsAction); + }); } } } \ No newline at end of file diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/EntityOptions.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/EntityOptions.cs new file mode 100644 index 0000000000..f592f96a0e --- /dev/null +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/EntityOptions.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.EntityFrameworkCore.DependencyInjection +{ + public class EntityOptions + where TEntity : IEntity + { + public static EntityOptions Empty { get; } = new EntityOptions(); + + public Func, IQueryable> IncludeDetailsFunc { get; set; } + } + + public class EntityOptions + { + private readonly IDictionary _options; + + public EntityOptions() + { + _options = new Dictionary(); + } + + public EntityOptions GetOrNull() + where TEntity : IEntity + { + return _options.GetOrDefault(typeof(TEntity)) as EntityOptions; + } + + public void Entity([NotNull] Action> optionsAction) + where TEntity : IEntity + { + Check.NotNull(optionsAction, nameof(optionsAction)); + + optionsAction( + _options.GetOrAdd( + typeof(TEntity), + () => new EntityOptions() + ) as EntityOptions + ); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs index 0d812fb3cd..d72bbe414f 100644 --- a/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs +++ b/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/IAbpDbContextRegistrationOptionsBuilder.cs @@ -1,8 +1,13 @@ +using System; +using JetBrains.Annotations; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities; namespace Volo.Abp.EntityFrameworkCore.DependencyInjection { public interface IAbpDbContextRegistrationOptionsBuilder : ICommonDbContextRegistrationOptionsBuilder { + void Entity([NotNull] Action> optionsAction) + where TEntity : IEntity; } } \ No newline at end of file diff --git a/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs index 2753a0bddd..621f20ed25 100644 --- a/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs +++ b/src/Volo.Abp.MemoryDb/Microsoft/Extensions/DependencyInjection/AbpMemoryDbServiceCollectionExtensions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection AddMemoryDbContext(this IServiceCollection services, Action optionsBuilder = null) where TMemoryDbContext : MemoryDbContext { - var options = new MemoryDbContextRegistrationOptions(typeof(TMemoryDbContext)); + var options = new MemoryDbContextRegistrationOptions(typeof(TMemoryDbContext), services); optionsBuilder?.Invoke(options); if (options.DefaultRepositoryDbContextType != typeof(TMemoryDbContext)) @@ -23,8 +23,7 @@ namespace Microsoft.Extensions.DependencyInjection services.Replace(ServiceDescriptor.Singleton(dbContextType, sp => sp.GetRequiredService())); } - new MemoryDbRepositoryRegistrar(options) - .AddRepositories(services); + new MemoryDbRepositoryRegistrar(options).AddRepositories(); return services; } diff --git a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs index 2d305ed0ee..d3380ffc41 100644 --- a/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/DependencyInjection/MemoryDbContextRegistrationOptions.cs @@ -1,12 +1,13 @@ using System; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MemoryDb.DependencyInjection { public class MemoryDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMemoryDbContextRegistrationOptionsBuilder { - public MemoryDbContextRegistrationOptions(Type originalDbContextType) - : base(originalDbContextType) + public MemoryDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) + : base(originalDbContextType, services) { } } diff --git a/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs b/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs index 101b41af3c..f498fd5e1d 100644 --- a/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs +++ b/src/Volo.Abp.MongoDB/Microsoft/Extensions/DependencyInjection/AbpMongoDbServiceCollectionExtensions.cs @@ -10,7 +10,7 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection AddMongoDbContext(this IServiceCollection services, Action optionsBuilder = null) //Created overload instead of default parameter where TMongoDbContext : AbpMongoDbContext { - var options = new MongoDbContextRegistrationOptions(typeof(TMongoDbContext)); + var options = new MongoDbContextRegistrationOptions(typeof(TMongoDbContext), services); optionsBuilder?.Invoke(options); foreach (var dbContextType in options.ReplacedDbContextTypes) @@ -18,8 +18,7 @@ namespace Microsoft.Extensions.DependencyInjection services.Replace(ServiceDescriptor.Transient(dbContextType, typeof(TMongoDbContext))); } - new MongoDbRepositoryRegistrar(options) - .AddRepositories(services); + new MongoDbRepositoryRegistrar(options).AddRepositories(); return services; } diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 2acee959e5..d5b2d85039 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -77,7 +77,19 @@ namespace Volo.Abp.Domain.Repositories.MongoDB public override TEntity Update(TEntity entity, bool autoSave = false) { - ApplyAbpConceptsForUpdatedEntity(entity); + SetModificationAuditProperties(entity); + + if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted) + { + SetDeletionAuditProperties(entity); + TriggerEntityDeleteEvents(entity); + } + else + { + TriggerEntityUpdateEvents(entity); + } + + TriggerDomainEvents(entity); Collection.ReplaceOne( CreateEntityFilter(entity), @@ -92,7 +104,19 @@ namespace Volo.Abp.Domain.Repositories.MongoDB bool autoSave = false, CancellationToken cancellationToken = default) { - ApplyAbpConceptsForUpdatedEntity(entity); + SetModificationAuditProperties(entity); + + if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted) + { + SetDeletionAuditProperties(entity); + TriggerEntityDeleteEvents(entity); + } + else + { + TriggerEntityUpdateEvents(entity); + } + + TriggerDomainEvents(entity); await Collection.ReplaceOneAsync( CreateEntityFilter(entity), @@ -200,25 +224,33 @@ namespace Volo.Abp.Domain.Repositories.MongoDB { CheckAndSetId(entity); SetCreationAuditProperties(entity); + TriggerEntityCreateEvents(entity); + TriggerDomainEvents(entity); + } + + private void TriggerEntityCreateEvents(TEntity entity) + { EntityChangeEventHelper.TriggerEntityCreatedEventOnUowCompleted(entity); EntityChangeEventHelper.TriggerEntityCreatingEvent(entity); - TriggerDomainEvents(entity); } - protected virtual void ApplyAbpConceptsForUpdatedEntity(TEntity entity) + protected virtual void TriggerEntityUpdateEvents(TEntity entity) { - SetModificationAuditProperties(entity); EntityChangeEventHelper.TriggerEntityUpdatedEventOnUowCompleted(entity); EntityChangeEventHelper.TriggerEntityUpdatingEvent(entity); - TriggerDomainEvents(entity); } - private void ApplyAbpConceptsForDeletedEntity(TEntity entity) + protected virtual void ApplyAbpConceptsForDeletedEntity(TEntity entity) { SetDeletionAuditProperties(entity); + TriggerEntityDeleteEvents(entity); + TriggerDomainEvents(entity); + } + + protected virtual void TriggerEntityDeleteEvents(TEntity entity) + { EntityChangeEventHelper.TriggerEntityDeletedEventOnUowCompleted(entity); EntityChangeEventHelper.TriggerEntityDeletingEvent(entity); - TriggerDomainEvents(entity); } protected virtual void CheckAndSetId(TEntity entity) diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs index 6712f1e1ab..bc748e12e9 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DependencyInjection/MongoDbContextRegistrationOptions.cs @@ -1,12 +1,13 @@ using System; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; namespace Volo.Abp.MongoDB.DependencyInjection { public class MongoDbContextRegistrationOptions : CommonDbContextRegistrationOptions, IMongoDbContextRegistrationOptionsBuilder { - public MongoDbContextRegistrationOptions(Type originalDbContextType) - : base(originalDbContextType) + public MongoDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) + : base(originalDbContextType, services) { } } diff --git a/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs b/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs index 662ae579f7..8412414108 100644 --- a/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs +++ b/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs @@ -19,12 +19,12 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services); options.AddDefaultRepositories(); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services); + new MyTestRepositoryRegistrar(options).AddRepositories(); //Assert @@ -57,12 +57,12 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services); options.AddDefaultRepositories(true); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services); + new MyTestRepositoryRegistrar(options).AddRepositories(); //Assert @@ -96,14 +96,14 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services); options .AddDefaultRepositories(true) .AddRepository(); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services); + new MyTestRepositoryRegistrar(options).AddRepositories(); //Assert @@ -137,14 +137,14 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services); options .AddDefaultRepositories(true) .AddRepository(); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services); + new MyTestRepositoryRegistrar(options).AddRepositories(); //Assert @@ -161,14 +161,14 @@ namespace Volo.Abp.Domain.Repositories var services = new ServiceCollection(); - var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext)); + var options = new TestDbContextRegistrationOptions(typeof(MyFakeDbContext), services); options .AddDefaultRepositories(true) .SetDefaultRepositoryClasses(typeof(MyTestCustomBaseRepository<,>), typeof(MyTestCustomBaseRepository<>)); //Act - new MyTestRepositoryRegistrar(options).AddRepositories(services); + new MyTestRepositoryRegistrar(options).AddRepositories(); //Assert @@ -319,8 +319,8 @@ namespace Volo.Abp.Domain.Repositories public class TestDbContextRegistrationOptions : CommonDbContextRegistrationOptions { - public TestDbContextRegistrationOptions(Type originalDbContextType) - : base(originalDbContextType) + public TestDbContextRegistrationOptions(Type originalDbContextType, IServiceCollection services) + : base(originalDbContextType, services) { } } diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index 6df4ec40b0..c5a4bca732 100644 --- a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -8,6 +8,7 @@ using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext; using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext; using Volo.Abp.Modularity; using Volo.Abp.TestApp; +using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.EntityFrameworkCore; namespace Volo.Abp.EntityFrameworkCore @@ -26,6 +27,11 @@ namespace Volo.Abp.EntityFrameworkCore { options.AddDefaultRepositories(true); options.ReplaceDbContext(); + + options.Entity(opt => + { + opt.IncludeDetailsFunc = q => q.Include(p => p.Phones); + }); }); var sqliteConnection = CreateDatabaseAndGetConnection(); diff --git a/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DataFiltering/SoftDelete_Tests.cs b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DataFiltering/SoftDelete_Tests.cs new file mode 100644 index 0000000000..7d92ed3a87 --- /dev/null +++ b/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DataFiltering/SoftDelete_Tests.cs @@ -0,0 +1,9 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.EntityFrameworkCore.DataFiltering +{ + public class SoftDelete_Tests : SoftDelete_Tests + { + + } +} diff --git a/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs b/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs new file mode 100644 index 0000000000..fdd8ec1a5e --- /dev/null +++ b/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/DataFiltering/SoftDelete_Tests.cs @@ -0,0 +1,9 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.MongoDB.DataFiltering +{ + public class SoftDelete_Tests : SoftDelete_Tests + { + + } +} diff --git a/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs b/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs index 6be5fb265a..72774be545 100644 --- a/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs +++ b/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs @@ -11,14 +11,6 @@ namespace Volo.Abp.MongoDB.Repositories { public class Repository_Basic_Tests : Repository_Basic_Tests { - [Fact] - public async Task GetAsync() - { - var person = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); - person.Name.ShouldBe("Douglas"); - person.Phones.Count.ShouldBe(2); - } - [Fact] public void Linq_Queries() { diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Auditing_Tests.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Auditing_Tests.cs index 13aaf69ca9..4e3224cd5c 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Auditing_Tests.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Auditing_Tests.cs @@ -81,8 +81,7 @@ namespace Volo.Abp.TestApp.Testing douglas.LastModificationTime.Value.ShouldBeLessThanOrEqualTo(Clock.Now); douglas.LastModifierId.ShouldBe(CurrentUserId); } - - + [Theory] [InlineData(null)] [InlineData("4b2790fc-3f51-43d5-88a1-a92d96a9e6ea")] diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs index d298620504..07e6211c09 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs @@ -20,6 +20,14 @@ namespace Volo.Abp.TestApp.Testing CityRepository = GetRequiredService(); } + [Fact] + public async Task GetAsync() + { + var person = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); + person.Name.ShouldBe("Douglas"); + person.Phones.Count.ShouldBe(2); + } + [Fact] public async Task FindAsync_Should_Return_Null_For_Not_Found_Entity() { diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/SoftDelete_Tests.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/SoftDelete_Tests.cs new file mode 100644 index 0000000000..0059a39a11 --- /dev/null +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/SoftDelete_Tests.cs @@ -0,0 +1,64 @@ +using System; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Data; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.Domain; +using Xunit; + +namespace Volo.Abp.TestApp.Testing +{ + public abstract class SoftDelete_Tests : TestAppTestBase + where TStartupModule : IAbpModule + { + protected readonly IRepository PersonRepository; + protected readonly IDataFilter DataFilter; + + protected SoftDelete_Tests() + { + PersonRepository = GetRequiredService>(); + DataFilter = GetRequiredService(); + } + + [Fact] + public async Task Should_Cancel_Deletion_For_Soft_Delete_Entities() + { + var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); + await PersonRepository.DeleteAsync(douglas); + + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldNotBeNull(); + douglas.IsDeleted.ShouldBeTrue(); + douglas.DeletionTime.ShouldNotBeNull(); + } + } + + [Fact] + public async Task Should_Handle_Deletion_On_Update_For_Soft_Delete_Entities() + { + var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); + douglas.Age = 42; + douglas.IsDeleted = true; + + await PersonRepository.UpdateAsync(douglas); + + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldNotBeNull(); + douglas.IsDeleted.ShouldBeTrue(); + douglas.DeletionTime.ShouldNotBeNull(); + douglas.Age.ShouldBe(42); + } + } + } +}