mirror of https://github.com/abpframework/abp.git
18 changed files with 504 additions and 0 deletions
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class DomainEventEntry |
||||
|
{ |
||||
|
public object SourceEntity { get; } |
||||
|
|
||||
|
public object EventData { get; } |
||||
|
|
||||
|
public DomainEventEntry(object sourceEntity, object eventData) |
||||
|
{ |
||||
|
SourceEntity = sourceEntity; |
||||
|
EventData = eventData; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class EntityChangeEntry |
||||
|
{ |
||||
|
public object Entity { get; set; } |
||||
|
|
||||
|
public EntityChangeType ChangeType { get; set; } |
||||
|
|
||||
|
public EntityChangeEntry(object entity, EntityChangeType changeType) |
||||
|
{ |
||||
|
Entity = entity; |
||||
|
ChangeType = changeType; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,131 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.EventBus; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to trigger entity change events.
|
||||
|
/// </summary>
|
||||
|
public class EntityChangeEventHelper : IEntityChangeEventHelper, ITransientDependency |
||||
|
{ |
||||
|
public IEventBus EventBus { get; set; } |
||||
|
|
||||
|
private readonly IUnitOfWorkManager _unitOfWorkManager; |
||||
|
|
||||
|
public EntityChangeEventHelper(IUnitOfWorkManager unitOfWorkManager) |
||||
|
{ |
||||
|
_unitOfWorkManager = unitOfWorkManager; |
||||
|
EventBus = NullEventBus.Instance; |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEvents(EntityChangeReport changeReport) |
||||
|
{ |
||||
|
TriggerEventsInternal(changeReport); |
||||
|
|
||||
|
if (changeReport.IsEmpty() || _unitOfWorkManager.Current == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_unitOfWorkManager.Current.SaveChanges(); |
||||
|
} |
||||
|
|
||||
|
public Task TriggerEventsAsync(EntityChangeReport changeReport) //TODO: Trigger events really async!
|
||||
|
{ |
||||
|
TriggerEventsInternal(changeReport); |
||||
|
|
||||
|
if (changeReport.IsEmpty() || _unitOfWorkManager.Current == null) |
||||
|
{ |
||||
|
return Task.FromResult(0); |
||||
|
} |
||||
|
|
||||
|
return _unitOfWorkManager.Current.SaveChangesAsync(); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityCreatingEvent(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityCreatingEventData<>), entity, true); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityCreatedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityCreatedEventData<>), entity, false); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityUpdatingEvent(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityUpdatingEventData<>), entity, true); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityUpdatedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityUpdatedEventData<>), entity, false); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityDeletingEvent(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityDeletingEventData<>), entity, true); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEntityDeletedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
TriggerEventWithEntity(typeof(EntityDeletedEventData<>), entity, false); |
||||
|
} |
||||
|
|
||||
|
public virtual void TriggerEventsInternal(EntityChangeReport changeReport) |
||||
|
{ |
||||
|
TriggerEntityChangeEvents(changeReport.ChangedEntities); |
||||
|
TriggerDomainEvents(changeReport.DomainEvents); |
||||
|
} |
||||
|
|
||||
|
protected virtual void TriggerEntityChangeEvents(List<EntityChangeEntry> changedEntities) |
||||
|
{ |
||||
|
foreach (var changedEntity in changedEntities) |
||||
|
{ |
||||
|
switch (changedEntity.ChangeType) |
||||
|
{ |
||||
|
case EntityChangeType.Created: |
||||
|
TriggerEntityCreatingEvent(changedEntity.Entity); |
||||
|
TriggerEntityCreatedEventOnUowCompleted(changedEntity.Entity); |
||||
|
break; |
||||
|
case EntityChangeType.Updated: |
||||
|
TriggerEntityUpdatingEvent(changedEntity.Entity); |
||||
|
TriggerEntityUpdatedEventOnUowCompleted(changedEntity.Entity); |
||||
|
break; |
||||
|
case EntityChangeType.Deleted: |
||||
|
TriggerEntityDeletingEvent(changedEntity.Entity); |
||||
|
TriggerEntityDeletedEventOnUowCompleted(changedEntity.Entity); |
||||
|
break; |
||||
|
default: |
||||
|
throw new AbpException("Unknown EntityChangeType: " + changedEntity.ChangeType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual void TriggerDomainEvents(List<DomainEventEntry> domainEvents) |
||||
|
{ |
||||
|
foreach (var domainEvent in domainEvents) |
||||
|
{ |
||||
|
EventBus.Trigger(domainEvent.EventData.GetType(), domainEvent.EventData); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual void TriggerEventWithEntity(Type genericEventType, object entity, bool triggerInCurrentUnitOfWork) |
||||
|
{ |
||||
|
var entityType = entity.GetType(); |
||||
|
var eventType = genericEventType.MakeGenericType(entityType); |
||||
|
|
||||
|
if (triggerInCurrentUnitOfWork || _unitOfWorkManager.Current == null) |
||||
|
{ |
||||
|
EventBus.Trigger(eventType, Activator.CreateInstance(eventType, entity)); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_unitOfWorkManager.Current.Completed += (sender, args) => EventBus.Trigger(eventType, Activator.CreateInstance(eventType, entity)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
public class EntityChangeReport |
||||
|
{ |
||||
|
public List<EntityChangeEntry> ChangedEntities { get; } |
||||
|
|
||||
|
public List<DomainEventEntry> DomainEvents { get; } |
||||
|
|
||||
|
public EntityChangeReport() |
||||
|
{ |
||||
|
ChangedEntities = new List<EntityChangeEntry>(); |
||||
|
DomainEvents = new List<DomainEventEntry>(); |
||||
|
} |
||||
|
|
||||
|
public bool IsEmpty() |
||||
|
{ |
||||
|
return ChangedEntities.Count <= 0 && DomainEvents.Count <= 0; |
||||
|
} |
||||
|
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"[EntityChangeReport] ChangedEntities: {ChangedEntities.Count}, DomainEvents: {DomainEvents.Count}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
public enum EntityChangeType : byte |
||||
|
{ |
||||
|
Created = 0, |
||||
|
|
||||
|
Updated = 1, |
||||
|
|
||||
|
Deleted = 2 |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to pass data for an event when an entity (<see cref="IEntity"/>) is changed (created, updated or deleted).
|
||||
|
/// See <see cref="EntityCreatedEventData{TEntity}"/>, <see cref="EntityDeletedEventData{TEntity}"/> and <see cref="EntityUpdatedEventData{TEntity}"/> classes.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityChangedEventData<TEntity> : EntityEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">Changed entity in this event</param>
|
||||
|
public EntityChangedEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to pass data for an event when an entity (<see cref="IEntity"/>) is being changed (creating, updating or deleting).
|
||||
|
/// See <see cref="EntityCreatingEventData{TEntity}"/>, <see cref="EntityDeletingEventData{TEntity}"/> and <see cref="EntityUpdatingEventData{TEntity}"/> classes.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityChangingEventData<TEntity> : EntityEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">Changing entity in this event</param>
|
||||
|
public EntityChangingEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event can be used to notify just after creation of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityCreatedEventData<TEntity> : EntityChangedEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is created</param>
|
||||
|
public EntityCreatedEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event is used to notify just before creation of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityCreatingEventData<TEntity> : EntityChangingEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is being created</param>
|
||||
|
public EntityCreatingEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event can be used to notify just after deletion of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityDeletedEventData<TEntity> : EntityChangedEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is deleted</param>
|
||||
|
public EntityDeletedEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event is used to notify just before deletion of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityDeletingEventData<TEntity> : EntityChangingEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is being deleted</param>
|
||||
|
public EntityDeletingEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.EventBus; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to pass data for an event that is related to with an <see cref="IEntity"/> object.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityEventData<TEntity> : IEventDataWithInheritableGenericArgument |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Related entity with this event.
|
||||
|
/// </summary>
|
||||
|
public TEntity Entity { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">Related entity with this event</param>
|
||||
|
public EntityEventData(TEntity entity) |
||||
|
{ |
||||
|
Entity = entity; |
||||
|
} |
||||
|
|
||||
|
public virtual object[] GetConstructorArgs() |
||||
|
{ |
||||
|
return new object[] { Entity }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event can be used to notify just after update of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityUpdatedEventData<TEntity> : EntityChangedEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is updated</param>
|
||||
|
public EntityUpdatedEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// This type of event is used to notify just before update of an Entity.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TEntity">Entity type</typeparam>
|
||||
|
[Serializable] |
||||
|
public class EntityUpdatingEventData<TEntity> : EntityChangingEventData<TEntity> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="entity">The entity which is being updated</param>
|
||||
|
public EntityUpdatingEventData(TEntity entity) |
||||
|
: base(entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Used to trigger entity change events.
|
||||
|
/// </summary>
|
||||
|
public interface IEntityChangeEventHelper |
||||
|
{ |
||||
|
void TriggerEvents(EntityChangeReport changeReport); |
||||
|
|
||||
|
Task TriggerEventsAsync(EntityChangeReport changeReport); |
||||
|
|
||||
|
void TriggerEntityCreatingEvent(object entity); |
||||
|
|
||||
|
void TriggerEntityCreatedEventOnUowCompleted(object entity); |
||||
|
|
||||
|
void TriggerEntityUpdatingEvent(object entity); |
||||
|
|
||||
|
void TriggerEntityUpdatedEventOnUowCompleted(object entity); |
||||
|
|
||||
|
void TriggerEntityDeletingEvent(object entity); |
||||
|
|
||||
|
void TriggerEntityDeletedEventOnUowCompleted(object entity); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Domain.Entities.Events |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Null-object implementation of <see cref="IEntityChangeEventHelper"/>.
|
||||
|
/// </summary>
|
||||
|
public class NullEntityChangeEventHelper : IEntityChangeEventHelper |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets single instance of <see cref="NullEntityChangeEventHelper"/> class.
|
||||
|
/// </summary>
|
||||
|
public static NullEntityChangeEventHelper Instance { get; } = new NullEntityChangeEventHelper(); |
||||
|
|
||||
|
private NullEntityChangeEventHelper() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityCreatingEvent(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityCreatedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityUpdatingEvent(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityUpdatedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityDeletingEvent(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEntityDeletedEventOnUowCompleted(object entity) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void TriggerEvents(EntityChangeReport changeReport) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public Task TriggerEventsAsync(EntityChangeReport changeReport) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue