mirror of https://github.com/abpframework/abp
parent
68a3f9ccb5
commit
f81e87fed6
@ -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