Added entity events for eventbus.

pull/216/head
Halil İbrahim Kalkan 8 years ago
parent 68a3f9ccb5
commit f81e87fed6

@ -16,6 +16,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" />
<ProjectReference Include="..\Volo.Abp.EventBus\Volo.Abp.EventBus.csproj" />
<ProjectReference Include="..\Volo.Abp.Guids\Volo.Abp.Guids.csproj" />
<ProjectReference Include="..\Volo.Abp.Http.Abstractions\Volo.Abp.Http.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />

@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application.Services;
using Volo.Abp.Data;
using Volo.Abp.EventBus;
using Volo.Abp.Guids;
using Volo.Abp.Http;
using Volo.Abp.Http.Modeling;
@ -19,6 +20,7 @@ namespace Volo.Abp
[DependsOn(typeof(AbpObjectMappingModule))]
[DependsOn(typeof(AbpMultiTenancyAbstractionsModule))]
[DependsOn(typeof(AbpThreadingModule))]
[DependsOn(typeof(AbpEventBusModule))]
[DependsOn(typeof(AbpValidationModule))]
[DependsOn(typeof(AbpHttpAbstractionsModule))]
public class AbpDddModule : AbpModule

@ -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…
Cancel
Save