using System; using System.Collections.Generic; using System.Threading.Tasks; using Abp.Dependency; using Abp.Domain.Uow; namespace Abp.Events.Bus.Entities { /// /// Used to trigger entity change events. /// public class EntityChangeEventHelper : ITransientDependency, IEntityChangeEventHelper { 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) { 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 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 domainEvents) { foreach (var domainEvent in domainEvents) { EventBus.Trigger(domainEvent.EventData.GetType(), domainEvent.SourceEntity, 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, (IEventData)Activator.CreateInstance(eventType, new[] { entity })); return; } _unitOfWorkManager.Current.Completed += (sender, args) => EventBus.Trigger(eventType, (IEventData)Activator.CreateInstance(eventType, new[] { entity })); } } }