Implemented data filters for mongodb. Revised IGeneratesDomainEvents

pull/272/head
Halil İbrahim Kalkan 8 years ago
parent f9caa9d365
commit b136f483fc

@ -1,26 +1,34 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations.Schema;
namespace Volo.Abp.Domain.Entities
{
[Serializable]
public abstract class AggregateRoot : Entity, IAggregateRoot
{
[NotMapped] //TODO: Better to handle in EF Core layer, or just use get/set methods instead of a property?
public virtual ICollection<object> DomainEvents => _domainEvents ?? (_domainEvents = new Collection<object>());
private readonly ICollection<object> _domainEvents = new Collection<object>();
private ICollection<object> _domainEvents;
protected virtual void AddDomainEvent(object eventData)
{
_domainEvents.Add(eventData);
}
public virtual IEnumerable<object> GetDomainEvents()
{
return _domainEvents;
}
public virtual void ClearDomainEvents()
{
_domainEvents.Clear();
}
}
[Serializable]
public abstract class AggregateRoot<TKey> : Entity<TKey>, IAggregateRoot<TKey>
{
[NotMapped] //TODO: Better to handle in EF Core layer, or just use get/set methods instead of a property??
public virtual ICollection<object> DomainEvents => _domainEvents ?? (_domainEvents = new Collection<object>());
private ICollection<object> _domainEvents;
private readonly ICollection<object> _domainEvents = new Collection<object>();
protected AggregateRoot()
{
@ -32,5 +40,20 @@ namespace Volo.Abp.Domain.Entities
{
}
protected virtual void AddDomainEvent(object eventData)
{
_domainEvents.Add(eventData);
}
public virtual IEnumerable<object> GetDomainEvents()
{
return _domainEvents;
}
public virtual void ClearDomainEvents()
{
_domainEvents.Clear();
}
}
}

@ -76,7 +76,7 @@ namespace Volo.Abp.Domain.Entities
{
var lambdaParam = Expression.Parameter(typeof(TEntity));
var lambdaBody = Expression.Equal(
Expression.PropertyOrField(lambdaParam, "Id"),
Expression.PropertyOrField(lambdaParam, nameof(Entity<TKey>.Id)),
Expression.Constant(id, typeof(TKey))
);

@ -2,8 +2,12 @@
namespace Volo.Abp.Domain.Entities
{
//TODO: Re-consider this interface
public interface IGeneratesDomainEvents
{
ICollection<object> DomainEvents { get; }
IEnumerable<object> GetDomainEvents();
void ClearDomainEvents();
}
}

@ -50,17 +50,18 @@ namespace Volo.Abp.Domain.Repositories
return Task.CompletedTask;
}
protected virtual IQueryable<TEntity> ApplyDataFilters(IQueryable<TEntity> query)
protected virtual TQueryable ApplyDataFilters<TQueryable>(TQueryable query)
where TQueryable : IQueryable<TEntity>
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
query = query.WhereIf(DataFilter.IsEnabled<ISoftDelete>(), e => ((ISoftDelete)e).IsDeleted == false);
query = (TQueryable)query.WhereIf(DataFilter.IsEnabled<ISoftDelete>(), e => ((ISoftDelete)e).IsDeleted == false);
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
{
var tenantId = CurrentTenant.Id;
query = query.WhereIf(DataFilter.IsEnabled<IMultiTenant>(), e => ((IMultiTenant)e).TenantId == tenantId);
query = (TQueryable)query.WhereIf(DataFilter.IsEnabled<IMultiTenant>(), e => ((IMultiTenant)e).TenantId == tenantId);
}
return query;

@ -189,13 +189,14 @@ namespace Volo.Abp.EntityFrameworkCore
return;
}
if (generatesDomainEventsEntity.DomainEvents.IsNullOrEmpty())
var entityEvents = generatesDomainEventsEntity.GetDomainEvents().ToArray();
if (entityEvents.IsNullOrEmpty())
{
return;
}
domainEvents.AddRange(generatesDomainEventsEntity.DomainEvents.Select(eventData => new DomainEventEntry(entityAsObj, eventData)));
generatesDomainEventsEntity.DomainEvents.Clear();
domainEvents.AddRange(entityEvents.Select(eventData => new DomainEventEntry(entityAsObj, eventData)));
generatesDomainEventsEntity.ClearDomainEvents();
}
protected virtual void HandleConcurrencyStamp(EntityEntry entry)

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
@ -6,6 +7,7 @@ using System.Threading.Tasks;
using MongoDB.Driver;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MongoDB;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Domain.Repositories.MongoDB
{
@ -74,7 +76,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
protected override IQueryable<TEntity> GetQueryable()
{
return Collection.AsQueryable();
return ApplyDataFilters(Collection.AsQueryable());
}
protected virtual FilterDefinition<TEntity> CreateEntityFilter(TEntity entity)
@ -117,24 +119,24 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return entity;
}
public virtual void Delete(TKey id, bool autoSave = false)
public virtual async Task<TEntity> FindAsync(TKey id, CancellationToken cancellationToken = default)
{
Collection.DeleteOne(CreateEntityFilter(id));
return await Collection.Find(CreateEntityFilter(id, true)).FirstOrDefaultAsync(cancellationToken);
}
public virtual Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
public virtual TEntity Find(TKey id)
{
return Collection.DeleteOneAsync(CreateEntityFilter(id), cancellationToken);
return Collection.Find(CreateEntityFilter(id, true)).FirstOrDefault();
}
public virtual async Task<TEntity> FindAsync(TKey id, CancellationToken cancellationToken = default)
public virtual void Delete(TKey id, bool autoSave = false)
{
return await Collection.Find(CreateEntityFilter(id)).FirstOrDefaultAsync(cancellationToken);
Collection.DeleteOne(CreateEntityFilter(id));
}
public virtual TEntity Find(TKey id)
public virtual Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
{
return Collection.Find(CreateEntityFilter(id)).FirstOrDefault();
return Collection.DeleteOneAsync(CreateEntityFilter(id), cancellationToken);
}
protected override FilterDefinition<TEntity> CreateEntityFilter(TEntity entity)
@ -142,9 +144,33 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return Builders<TEntity>.Filter.Eq(e => e.Id, entity.Id);
}
protected virtual FilterDefinition<TEntity> CreateEntityFilter(TKey id)
protected virtual FilterDefinition<TEntity> CreateEntityFilter(TKey id, bool applyFilters = false)
{
return Builders<TEntity>.Filter.Eq(e => e.Id, id);
var filters = new List<FilterDefinition<TEntity>>
{
Builders<TEntity>.Filter.Eq(e => e.Id, id)
};
if (applyFilters)
{
AddGlobalFilters(filters);
}
return Builders<TEntity>.Filter.And(filters);
}
protected virtual void AddGlobalFilters(List<FilterDefinition<TEntity>> filters)
{
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && DataFilter.IsEnabled<ISoftDelete>())
{
filters.Add(Builders<TEntity>.Filter.Eq(e => ((ISoftDelete) e).IsDeleted, false));
}
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
{
var tenantId = CurrentTenant.Id;
filters.Add(Builders<TEntity>.Filter.Eq(e => ((IMultiTenant) e).TenantId, tenantId));
}
}
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MongoDB
{
public class MultiTenant_Filter_Tests : MultiTenant_Filter_Tests<AbpMongoDbTestModule>
{
}
}

@ -9,7 +9,7 @@ using Xunit;
namespace Volo.Abp.MongoDB
{
public class MongoDb_Repository_Basic_Tests : Repository_Basic_Tests<AbpMongoDbTestModule>
public class Repository_Basic_Tests : Repository_Basic_Tests<AbpMongoDbTestModule>
{
[Fact]
public async Task GetAsync()

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MongoDB
{
public class Repository_Queryable_Tests : Repository_Queryable_Tests<AbpMongoDbTestModule>
{
}
}

@ -0,0 +1,9 @@
using Volo.Abp.TestApp.Testing;
namespace Volo.Abp.MongoDB
{
public class SoftDelete_Filter_Tests : SoftDelete_Filter_Tests<AbpMongoDbTestModule>
{
}
}

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
@ -41,7 +42,7 @@ namespace Volo.Abp.TestApp.Domain
var oldName = Name;
Name = name;
DomainEvents.Add(new PersonNameChangedEvent{Person = this, OldName = oldName});
AddDomainEvent(new PersonNameChangedEvent{Person = this, OldName = oldName});
}
}
}

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
@ -22,7 +23,27 @@ namespace Volo.Abp.TestApp.Testing
}
[Fact]
public void Should_Not_Get_Deleted_Entities_By_Default()
public void Should_Not_Get_Deleted_Entities_Linq()
{
WithUnitOfWork(() =>
{
var person = PersonRepository.FirstOrDefault(p => p.Name == "John-Deleted");
person.ShouldBeNull();
});
}
[Fact]
public async Task Should_Not_Get_Deleted_Entities_By_Id()
{
await WithUnitOfWorkAsync(async () =>
{
var person = await PersonRepository.FindAsync(TestDataBuilder.UserJohnDeletedId);
person.ShouldBeNull();
});
}
[Fact]
public void Should_Not_Get_Deleted_Entities_By_Default_ToList()
{
WithUnitOfWork(() =>
{

Loading…
Cancel
Save