增加领域事件定义,增加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;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace IRaCIS.Core.Domain.Models
|
namespace IRaCIS.Core.Domain.Models
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public interface IAggregateRoot;
|
||||||
|
public interface IEntity<TKey>
|
||||||
|
{
|
||||||
|
abstract TKey Id { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class Entity : IEntity<Guid>
|
public abstract class Entity : IEntity<Guid>
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[Required]
|
[Required]
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.None)]
|
[DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||||
public Guid Id { get; set; }
|
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 减少实体属性,增加基类
|
#region 减少实体属性,增加基类
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.0.0" />
|
<PackageReference Include="EntityFrameworkCore.Exceptions.SqlServer" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" 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="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||||
<PackageReference Include="NewId" Version="4.0.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -12,13 +12,14 @@ namespace IRaCIS.Core.Infra.EFCore;
|
||||||
|
|
||||||
public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesInterceptor
|
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,
|
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData,
|
||||||
InterceptionResult<int> result, CancellationToken cancellationToken = default)
|
InterceptionResult<int> result, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
@ -26,7 +27,12 @@ public class AuditEntityInterceptor(IUserInfo _userInfo) : SaveChangesIntercepto
|
||||||
|
|
||||||
return base.SavingChangesAsync(eventData, result, cancellationToken);
|
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)
|
public void AuditEntities(DbContext? context)
|
||||||
{
|
{
|
||||||
if (context == null) return;
|
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>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||||
<PackageReference Include="AutoMapper.Collection.EntityFrameworkCore" Version="10.0.0" />
|
<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.Configuration" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
|
Loading…
Reference in New Issue