Implemented creating distributed events on aggregate roots.

pull/603/head
Halil ibrahim Kalkan 6 years ago
parent 127f389819
commit 4904b9ec03

@ -7,28 +7,45 @@ namespace Volo.Abp.Domain.Entities
[Serializable]
public abstract class AggregateRoot : Entity, IAggregateRoot, IGeneratesDomainEvents
{
private readonly ICollection<object> _domainEvents = new Collection<object>();
private readonly ICollection<object> _localEvents = new Collection<object>();
private readonly ICollection<object> _distributedEvents = new Collection<object>();
protected virtual void AddDomainEvent(object eventData)
protected virtual void AddLocalEvent(object eventData)
{
_domainEvents.Add(eventData);
_localEvents.Add(eventData);
}
public virtual IEnumerable<object> GetDomainEvents()
protected virtual void AddDistributedEvent(object eventData)
{
return _domainEvents;
_distributedEvents.Add(eventData);
}
public virtual void ClearDomainEvents()
public virtual IEnumerable<object> GetLocalEvents()
{
_domainEvents.Clear();
return _localEvents;
}
public IEnumerable<object> GetDistributedEvents()
{
return _distributedEvents;
}
public virtual void ClearLocalEvents()
{
_localEvents.Clear();
}
public void ClearDistributedEvents()
{
_distributedEvents.Clear();
}
}
[Serializable]
public abstract class AggregateRoot<TKey> : Entity<TKey>, IAggregateRoot<TKey>, IGeneratesDomainEvents
{
private readonly ICollection<object> _domainEvents = new Collection<object>();
private readonly ICollection<object> _localEvents = new Collection<object>();
private readonly ICollection<object> _distributedEvents = new Collection<object>();
protected AggregateRoot()
{
@ -41,19 +58,34 @@ namespace Volo.Abp.Domain.Entities
}
protected virtual void AddDomainEvent(object eventData)
protected virtual void AddLocalEvent(object eventData)
{
_localEvents.Add(eventData);
}
protected virtual void AddDistributedEvent(object eventData)
{
_distributedEvents.Add(eventData);
}
public virtual IEnumerable<object> GetLocalEvents()
{
return _localEvents;
}
public IEnumerable<object> GetDistributedEvents()
{
_domainEvents.Add(eventData);
return _distributedEvents;
}
public virtual IEnumerable<object> GetDomainEvents()
public virtual void ClearLocalEvents()
{
return _domainEvents;
_localEvents.Clear();
}
public virtual void ClearDomainEvents()
public void ClearDistributedEvents()
{
_domainEvents.Clear();
_distributedEvents.Clear();
}
}
}

@ -82,7 +82,8 @@ namespace Volo.Abp.Domain.Entities.Events
protected virtual async Task TriggerEventsInternalAsync(EntityChangeReport changeReport)
{
await TriggerEntityChangeEvents(changeReport.ChangedEntities);
await TriggerDomainEvents(changeReport.DomainEvents);
await TriggerLocalEvents(changeReport.DomainEvents);
await TriggerDistributedEvents(changeReport.DistributedEvents);
}
protected virtual async Task TriggerEntityChangeEvents(List<EntityChangeEntry> changedEntities)
@ -109,11 +110,19 @@ namespace Volo.Abp.Domain.Entities.Events
}
}
protected virtual async Task TriggerDomainEvents(List<DomainEventEntry> domainEvents)
protected virtual async Task TriggerLocalEvents(List<DomainEventEntry> localEvents)
{
foreach (var domainEvent in domainEvents)
foreach (var localEvent in localEvents)
{
await LocalEventBus.PublishAsync(domainEvent.EventData.GetType(), domainEvent.EventData);
await LocalEventBus.PublishAsync(localEvent.EventData.GetType(), localEvent.EventData);
}
}
protected virtual async Task TriggerDistributedEvents(List<DomainEventEntry> distributedEvents)
{
foreach (var distributedEvent in distributedEvents)
{
await DistributedEventBus.PublishAsync(distributedEvent.EventData.GetType(), distributedEvent.EventData);
}
}

@ -8,20 +8,25 @@ namespace Volo.Abp.Domain.Entities.Events
public List<DomainEventEntry> DomainEvents { get; }
public List<DomainEventEntry> DistributedEvents { get; }
public EntityChangeReport()
{
ChangedEntities = new List<EntityChangeEntry>();
DomainEvents = new List<DomainEventEntry>();
DistributedEvents = new List<DomainEventEntry>();
}
public bool IsEmpty()
{
return ChangedEntities.Count <= 0 && DomainEvents.Count <= 0;
return ChangedEntities.Count <= 0 &&
DomainEvents.Count <= 0 &&
DistributedEvents.Count <= 0;
}
public override string ToString()
{
return $"[EntityChangeReport] ChangedEntities: {ChangedEntities.Count}, DomainEvents: {DomainEvents.Count}";
return $"[EntityChangeReport] ChangedEntities: {ChangedEntities.Count}, DomainEvents: {DomainEvents.Count}, DistributedEvents: {DistributedEvents.Count}";
}
}
}

@ -6,8 +6,12 @@ namespace Volo.Abp.Domain.Entities
public interface IGeneratesDomainEvents
{
IEnumerable<object> GetDomainEvents();
IEnumerable<object> GetLocalEvents();
void ClearDomainEvents();
IEnumerable<object> GetDistributedEvents();
void ClearLocalEvents();
void ClearDistributedEvents();
}
}

@ -203,7 +203,7 @@ namespace Volo.Abp.EntityFrameworkCore
break;
}
AddDomainEvents(changeReport.DomainEvents, entry.Entity);
AddDomainEvents(changeReport, entry.Entity);
}
protected virtual void ApplyAbpConceptsForAddedEntity(EntityEntry entry, EntityChangeReport changeReport)
@ -237,7 +237,7 @@ namespace Volo.Abp.EntityFrameworkCore
changeReport.ChangedEntities.Add(new EntityChangeEntry(entry.Entity, EntityChangeType.Deleted));
}
protected virtual void AddDomainEvents(List<DomainEventEntry> domainEvents, object entityAsObj)
protected virtual void AddDomainEvents(EntityChangeReport changeReport, object entityAsObj)
{
var generatesDomainEventsEntity = entityAsObj as IGeneratesDomainEvents;
if (generatesDomainEventsEntity == null)
@ -245,14 +245,19 @@ namespace Volo.Abp.EntityFrameworkCore
return;
}
var entityEvents = generatesDomainEventsEntity.GetDomainEvents().ToArray();
if (entityEvents.IsNullOrEmpty())
var localEvents = generatesDomainEventsEntity.GetLocalEvents().ToArray();
if (localEvents.Any())
{
return;
changeReport.DomainEvents.AddRange(localEvents.Select(eventData => new DomainEventEntry(entityAsObj, eventData)));
generatesDomainEventsEntity.ClearLocalEvents();
}
domainEvents.AddRange(entityEvents.Select(eventData => new DomainEventEntry(entityAsObj, eventData)));
generatesDomainEventsEntity.ClearDomainEvents();
var distributedEvents = generatesDomainEventsEntity.GetDistributedEvents().ToArray();
if (distributedEvents.Any())
{
changeReport.DistributedEvents.AddRange(distributedEvents.Select(eventData => new DomainEventEntry(entityAsObj, eventData)));
generatesDomainEventsEntity.ClearDistributedEvents();
}
}
protected virtual void HandleConcurrencyStamp(EntityEntry entry)

@ -10,6 +10,7 @@ using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Guids;
using Volo.Abp.MongoDB;
@ -34,6 +35,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
public ILocalEventBus LocalEventBus { get; set; }
public IDistributedEventBus DistributedEventBus { get; set; }
public IEntityChangeEventHelper EntityChangeEventHelper { get; set; }
public IGuidGenerator GuidGenerator { get; set; }
@ -45,6 +48,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
DbContextProvider = dbContextProvider;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
}
@ -306,18 +310,27 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return;
}
var entityEvents = generatesDomainEventsEntity.GetDomainEvents().ToArray();
if (entityEvents.IsNullOrEmpty())
var localEvents = generatesDomainEventsEntity.GetLocalEvents().ToArray();
if (localEvents.Any())
{
return;
foreach (var localEvent in localEvents)
{
await LocalEventBus.PublishAsync(localEvent.GetType(), localEvent);
}
generatesDomainEventsEntity.ClearLocalEvents();
}
foreach (var entityEvent in entityEvents)
var distributedEvents = generatesDomainEventsEntity.GetDistributedEvents().ToArray();
if (distributedEvents.Any())
{
await LocalEventBus.PublishAsync(entityEvent.GetType(), entityEvent);
}
foreach (var distributedEvent in distributedEvents)
{
await DistributedEventBus.PublishAsync(distributedEvent.GetType(), distributedEvent);
}
generatesDomainEventsEntity.ClearDomainEvents();
generatesDomainEventsEntity.ClearDistributedEvents();
}
}
}

@ -41,7 +41,24 @@ namespace Volo.Abp.TestApp.Domain
var oldName = Name;
Name = name;
AddDomainEvent(new PersonNameChangedEvent{Person = this, OldName = oldName});
AddLocalEvent(
new PersonNameChangedEvent
{
Person = this,
OldName = oldName
}
);
AddDistributedEvent(
new PersonNameChangedEto
{
Id = Id,
OldName = oldName,
NewName = Name,
TenantId = TenantId
}
);
}
}
}

@ -0,0 +1,15 @@
using System;
namespace Volo.Abp.TestApp.Domain
{
public class PersonNameChangedEto
{
public virtual Guid Id { get; set; }
public virtual Guid? TenantId { get; set; }
public string OldName { get; set; }
public string NewName { get; set; }
}
}

@ -3,7 +3,7 @@ using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain;
@ -16,11 +16,13 @@ namespace Volo.Abp.TestApp.Testing
{
protected readonly IRepository<Person, Guid> PersonRepository;
protected readonly ILocalEventBus LocalEventBus;
protected readonly IDistributedEventBus DistributedEventBus;
protected DomainEvents_Tests()
{
PersonRepository = GetRequiredService<IRepository<Person, Guid>>();
LocalEventBus = GetRequiredService<ILocalEventBus>();
DistributedEventBus = GetRequiredService<IDistributedEventBus>();
}
[Fact]
@ -28,13 +30,22 @@ namespace Volo.Abp.TestApp.Testing
{
//Arrange
var isTriggered = false;
var isLocalEventTriggered = false;
var isDistributedEventTriggered = false;
LocalEventBus.Subscribe<PersonNameChangedEvent>(data =>
{
data.OldName.ShouldBe("Douglas");
data.Person.Name.ShouldBe("Douglas-Changed");
isTriggered = true;
isLocalEventTriggered = true;
return Task.CompletedTask;
});
DistributedEventBus.Subscribe<PersonNameChangedEto>(data =>
{
data.OldName.ShouldBe("Douglas");
data.NewName.ShouldBe("Douglas-Changed");
isDistributedEventTriggered = true;
return Task.CompletedTask;
});
@ -49,7 +60,8 @@ namespace Volo.Abp.TestApp.Testing
//Assert
isTriggered.ShouldBeTrue();
isLocalEventTriggered.ShouldBeTrue();
isDistributedEventTriggered.ShouldBeTrue();
}
}
}
Loading…
Cancel
Save