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