增加领域事件定义,增加MassTransit 发布事件
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
021b32587a
commit
00827e9975
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Domain.BaseModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 领域实体事件基类
|
||||
/// </summary>
|
||||
public abstract class DomainEvent
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class FailedDomainEvent
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string EventType { get; set; }
|
||||
public string EventData { get; set; }
|
||||
public DateTime FailedAt { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,21 +1,57 @@
|
|||
using System;
|
||||
using IRaCIS.Core.Domain.BaseModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace IRaCIS.Core.Domain.Models
|
||||
{
|
||||
|
||||
|
||||
public interface IAggregateRoot;
|
||||
public interface IEntity<TKey>
|
||||
{
|
||||
abstract TKey Id { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public abstract class Entity : IEntity<Guid>
|
||||
{
|
||||
[Key]
|
||||
[Required]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
#region 领域事件 仅仅允许通过提供的方法进行操作
|
||||
|
||||
private readonly List<DomainEvent> _domainEvents = [];
|
||||
|
||||
[NotMapped]
|
||||
public IReadOnlyCollection<DomainEvent> DomainEvents => _domainEvents.AsReadOnly();
|
||||
|
||||
|
||||
public void AddDomainEvent(DomainEvent domainEvent)
|
||||
{
|
||||
_domainEvents.Add(domainEvent);
|
||||
}
|
||||
|
||||
public void RemoveDomainEvent(DomainEvent domainEvent)
|
||||
{
|
||||
_domainEvents.Remove(domainEvent);
|
||||
}
|
||||
|
||||
public void ClearDomainEvents()
|
||||
{
|
||||
_domainEvents.Clear();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
public interface IEntity<TKey>
|
||||
{
|
||||
abstract TKey Id { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 减少实体属性,增加基类
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||
<PackageReference Include="NewId" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -12,13 +12,14 @@ namespace IRaCIS.Core.Infra.EFCore;
|
|||
|
||||
public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesInterceptor
|
||||
{
|
||||
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
|
||||
{
|
||||
AuditEntities(eventData.Context);
|
||||
|
||||
return base.SavingChanges(eventData, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在事务提交之前执行
|
||||
/// </summary>
|
||||
/// <param name="eventData"></param>
|
||||
/// <param name="result"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
|
||||
InterceptionResult<int> result, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -26,7 +27,12 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto
|
|||
|
||||
return base.SavingChangesAsync(eventData, result, cancellationToken);
|
||||
}
|
||||
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
|
||||
{
|
||||
AuditEntities(eventData.Context);
|
||||
|
||||
return base.SavingChanges(eventData, result);
|
||||
}
|
||||
public void AuditEntities(DbContext? context)
|
||||
{
|
||||
if (context == null) return;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using MassTransit;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Interceptor
|
||||
{
|
||||
public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor
|
||||
{
|
||||
|
||||
//领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态
|
||||
|
||||
/// <summary>
|
||||
/// 在事务提交之后分发事件
|
||||
/// </summary>
|
||||
/// <param name="eventData"></param>
|
||||
/// <param name="result"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
await DispatchDomainEvents(eventData.Context);
|
||||
return await base.SavedChangesAsync(eventData, result, cancellationToken);
|
||||
}
|
||||
public override int SavedChanges(SaveChangesCompletedEventData eventData, int result)
|
||||
{
|
||||
DispatchDomainEvents(eventData.Context).GetAwaiter().GetResult();
|
||||
return base.SavedChanges(eventData, result);
|
||||
}
|
||||
private async Task DispatchDomainEvents(DbContext? context)
|
||||
{
|
||||
if (context == null) return;
|
||||
|
||||
var entities = context.ChangeTracker
|
||||
.Entries<Entity>()
|
||||
.Where(e => e.Entity.DomainEvents.Any())
|
||||
.Select(e => e.Entity)
|
||||
.ToList();
|
||||
|
||||
var domainEvents = entities
|
||||
.SelectMany(e => e.DomainEvents)
|
||||
.ToList();
|
||||
|
||||
entities.ForEach(e => e.ClearDomainEvents());
|
||||
|
||||
foreach (var domainEvent in domainEvents)
|
||||
{
|
||||
await publishEndpoint.Publish(domainEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
|
||||
<PackageReference Include="MassTransit" Version="8.2.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
|
Loading…
Reference in New Issue