Soft Delete & Common Test Done

pull/4453/head
Ismail Yilmaz 5 years ago
parent 68ef8587c5
commit 363fc9c865

@ -4,7 +4,12 @@ using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Guids;
using Volo.Abp.MemoryDb;
namespace Volo.Abp.Domain.Repositories.MemoryDb
@ -20,62 +25,224 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
public virtual IMemoryDatabase Database => DatabaseProvider.GetDatabase();
protected IMemoryDatabaseProvider<TMemoryDbContext> DatabaseProvider { get; }
public ILocalEventBus LocalEventBus { get; set; }
public IDistributedEventBus DistributedEventBus { get; set; }
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; }
public IAuditPropertySetter AuditPropertySetter { get; set; }
public IGuidGenerator GuidGenerator { get; set; }
public MemoryDbRepository(IMemoryDatabaseProvider<TMemoryDbContext> databaseProvider)
{
DatabaseProvider = databaseProvider;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
}
protected override IQueryable<TEntity> GetQueryable()
{
return ApplyDataFilters(Collection.AsQueryable());
}
protected virtual async Task TriggerDomainEventsAsync(object entity)
{
var generatesDomainEventsEntity = entity as IGeneratesDomainEvents;
if (generatesDomainEventsEntity == null)
{
return;
}
var localEvents = generatesDomainEventsEntity.GetLocalEvents()?.ToArray();
if (localEvents != null && localEvents.Any())
{
foreach (var localEvent in localEvents)
{
await LocalEventBus.PublishAsync(localEvent.GetType(), localEvent);
}
generatesDomainEventsEntity.ClearLocalEvents();
}
var distributedEvents = generatesDomainEventsEntity.GetDistributedEvents()?.ToArray();
if (distributedEvents != null && distributedEvents.Any())
{
foreach (var distributedEvent in distributedEvents)
{
await DistributedEventBus.PublishAsync(distributedEvent.GetType(), distributedEvent);
}
generatesDomainEventsEntity.ClearDistributedEvents();
}
}
protected virtual bool IsHardDeleted(TEntity entity)
{
if (!(UnitOfWorkManager?.Current?.Items.GetOrDefault(UnitOfWorkItemNames.HardDeletedEntities) is HashSet<IEntity> hardDeletedEntities))
{
return false;
}
return hardDeletedEntities.Contains(entity);
}
protected virtual void CheckAndSetId(TEntity entity)
{
if (entity is IEntity<Guid> entityWithGuidId)
{
TrySetGuidId(entityWithGuidId);
}
}
protected virtual void TrySetGuidId(IEntity<Guid> entity)
{
if (entity.Id != default)
{
return;
}
EntityHelper.TrySetId(
entity,
() => GuidGenerator.Create(),
true
);
}
protected virtual void SetCreationAuditProperties(TEntity entity)
{
AuditPropertySetter.SetCreationProperties(entity);
}
protected virtual void SetModificationAuditProperties(TEntity entity)
{
AuditPropertySetter.SetModificationProperties(entity);
}
protected virtual void SetDeletionAuditProperties(TEntity entity)
{
AuditPropertySetter.SetDeletionProperties(entity);
}
protected virtual async Task TriggerEntityCreateEvents(TEntity entity)
{
await EntityChangeEventHelper.TriggerEntityCreatedEventOnUowCompletedAsync(entity);
await EntityChangeEventHelper.TriggerEntityCreatingEventAsync(entity);
}
protected virtual async Task TriggerEntityUpdateEventsAsync(TEntity entity)
{
await EntityChangeEventHelper.TriggerEntityUpdatedEventOnUowCompletedAsync(entity);
await EntityChangeEventHelper.TriggerEntityUpdatingEventAsync(entity);
}
protected virtual async Task TriggerEntityDeleteEventsAsync(TEntity entity)
{
await EntityChangeEventHelper.TriggerEntityDeletedEventOnUowCompletedAsync(entity);
await EntityChangeEventHelper.TriggerEntityDeletingEventAsync(entity);
}
protected virtual async Task ApplyAbpConceptsForAddedEntityAsync(TEntity entity)
{
CheckAndSetId(entity);
SetCreationAuditProperties(entity);
await TriggerEntityCreateEvents(entity);
await TriggerDomainEventsAsync(entity);
}
protected virtual async Task ApplyAbpConceptsForDeletedEntityAsync(TEntity entity)
{
SetDeletionAuditProperties(entity);
await TriggerEntityDeleteEventsAsync(entity);
await TriggerDomainEventsAsync(entity);
}
public override Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return Task.FromResult(Collection.AsQueryable().Where(predicate).SingleOrDefault());
return Task.FromResult(GetQueryable().Where(predicate).SingleOrDefault());
}
public override Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task DeleteAsync(
Expression<Func<TEntity, bool>> predicate,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
var entities = Collection.AsQueryable().Where(predicate).ToList();
var entities = GetQueryable().Where(predicate).ToList();
foreach (var entity in entities)
{
Collection.Remove(entity);
await DeleteAsync(entity, autoSave, cancellationToken);
}
return Task.CompletedTask;
}
public override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> InsertAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
await ApplyAbpConceptsForAddedEntityAsync(entity);
Collection.Add(entity);
return Task.FromResult(entity);
return entity;
}
public override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> UpdateAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
SetModificationAuditProperties(entity);
if (entity is ISoftDelete softDeleteEntity && softDeleteEntity.IsDeleted)
{
SetDeletionAuditProperties(entity);
await TriggerEntityDeleteEventsAsync(entity);
}
else
{
await TriggerEntityUpdateEventsAsync(entity);
}
await TriggerDomainEventsAsync(entity);
Collection.Update(entity);
return Task.FromResult(entity);
}
public override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
return entity;
}
public override async Task DeleteAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
Collection.Remove(entity);
return Task.CompletedTask;
await ApplyAbpConceptsForDeletedEntityAsync(entity);
if (entity is ISoftDelete softDeleteEntity && !IsHardDeleted(entity))
{
softDeleteEntity.IsDeleted = true;
Collection.Update(entity);
}
else
{
Collection.Remove(entity);
}
}
public override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(Collection.ToList());
return Task.FromResult(GetQueryable().ToList());
}
public override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(Collection.LongCount());
return Task.FromResult(GetQueryable().LongCount());
}
}
@ -126,13 +293,7 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entity = await FindAsync(id, cancellationToken: cancellationToken);
if (entity == null)
{
return;
}
await DeleteAsync(entity, autoSave, cancellationToken);
await DeleteAsync(x => x.Id.Equals(id), autoSave, cancellationToken);
}
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MemoryDb.Auditing
{
public class Auditing_Tests : Auditing_Tests<AbpMemoryDbTestModule>
{
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MemoryDb.DataFilters
{
public class SoftDelete_Tests : SoftDelete_Tests<AbpMemoryDbTestModule>
{
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MemoryDb.DomainEvents
{
public class DomainEvents_Tests : DomainEvents_Tests<AbpMemoryDbTestModule>
{
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MemoryDb.DomainEvents
{
public class EntityChangeEvents_Tests : EntityChangeEvents_Tests<AbpMemoryDbTestModule>
{
}
}
Loading…
Cancel
Save