领域事件添加到测试环境-测试
continuous-integration/drone/push Build is passing Details

IRC_NewDev
hang 2024-08-20 13:14:06 +08:00
parent a70f661e86
commit 995bdee1f6
5 changed files with 81 additions and 70 deletions

View File

@ -146,6 +146,11 @@ builder.Services.AddMediator(cfg =>
cfg.AddConsumer<ConsistencyCheckConsumer>(); cfg.AddConsumer<ConsistencyCheckConsumer>();
}); });
builder.Services.AddMassTransit(cfg =>
{
cfg.UsingInMemory();
});
// EasyCaching 缓存 // EasyCaching 缓存
builder.Services.AddEasyCachingSetup(_configuration); builder.Services.AddEasyCachingSetup(_configuration);

View File

@ -1,5 +1,6 @@
using AutoMapper.EquivalencyExpression; using AutoMapper.EquivalencyExpression;
using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Domain.Models;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.API namespace IRaCIS.Core.API
@ -14,11 +15,15 @@ namespace IRaCIS.Core.API
//AutoMapper.Collection.EntityFrameworkCore //AutoMapper.Collection.EntityFrameworkCore
automapper.AddCollectionMappers(); automapper.AddCollectionMappers();
// 全局忽略 DomainEvents 属性
automapper.AddGlobalIgnore(nameof(Entity.DomainEvents));
#region 会使 IncludeMembers 失效 不能全局使用 #region 会使 IncludeMembers 失效 不能全局使用
//mapping an EntityFramework Core DbContext-object. //mapping an EntityFramework Core DbContext-object.
//automapper.UseEntityFrameworkCoreModel<IRaCISDBContext>(services); //automapper.UseEntityFrameworkCoreModel<IRaCISDBContext>(services);
//automapper.ForAllMaps((a, b) => b.ForAllMembers(opt => opt.Condition((src, dest, srcMember, desMenber) => //automapper.ForAllMaps((a, b) => b.ForAllMembers(opt => opt.Condition((src, dest, srcMember, desMenber) =>
//{ //{
// //// Can test When Guid? -> Guid if source is null will change to Guid.Empty // //// Can test When Guid? -> Guid if source is null will change to Guid.Empty
@ -27,7 +32,7 @@ namespace IRaCIS.Core.API
// // not want to map a null Guid? value to db Guid value // // not want to map a null Guid? value to db Guid value
//}))); //})));
#endregion #endregion
}, typeof(QCConfig).Assembly); }, typeof(QCConfig).Assembly);

View File

@ -4,6 +4,7 @@ using Hangfire.SqlServer;
using IRaCIS.Core.Application.Triggers; using IRaCIS.Core.Application.Triggers;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infra.EFCore.Interceptor;
using Medallion.Threading; using Medallion.Threading;
using Medallion.Threading.SqlServer; using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -23,6 +24,7 @@ namespace IRaCIS.Core.API
services.AddHttpContextAccessor(); services.AddHttpContextAccessor();
services.AddScoped<IUserInfo, UserInfo>(); services.AddScoped<IUserInfo, UserInfo>();
services.AddScoped<ISaveChangesInterceptor, AuditEntityInterceptor>(); services.AddScoped<ISaveChangesInterceptor, AuditEntityInterceptor>();
services.AddScoped<ISaveChangesInterceptor, DispatchDomainEventsInterceptor>();
// First, register a pooling context factory as a Singleton service, as usual: // First, register a pooling context factory as a Singleton service, as usual:

View File

@ -26,27 +26,26 @@ namespace IRaCIS.Core.Domain.Models
#region 领域事件 仅仅允许通过提供的方法进行操作 #region 领域事件 仅仅允许通过提供的方法进行操作
//[NotMapped] private readonly List<DomainEvent> _domainEvents = [];
//private readonly List<DomainEvent> _domainEvents = [];
//[NotMapped] [NotMapped]
//public IReadOnlyCollection<DomainEvent> DomainEvents => _domainEvents.AsReadOnly(); public IReadOnlyCollection<DomainEvent> DomainEvents => _domainEvents.AsReadOnly();
//public void AddDomainEvent(DomainEvent domainEvent) public void AddDomainEvent(DomainEvent domainEvent)
//{ {
// _domainEvents.Add(domainEvent); _domainEvents.Add(domainEvent);
//} }
//public void RemoveDomainEvent(DomainEvent domainEvent) public void RemoveDomainEvent(DomainEvent domainEvent)
//{ {
// _domainEvents.Remove(domainEvent); _domainEvents.Remove(domainEvent);
//} }
//public void ClearDomainEvents() public void ClearDomainEvents()
//{ {
// _domainEvents.Clear(); _domainEvents.Clear();
//} }
#endregion #endregion

View File

@ -1,59 +1,59 @@
//using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics;
//using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Text; using System.Text;
//using System.Threading; using System.Threading;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Models;
//using MassTransit; using MassTransit;
//namespace IRaCIS.Core.Infra.EFCore.Interceptor namespace IRaCIS.Core.Infra.EFCore.Interceptor
//{ {
// public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor
// { {
// //领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态 //领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态
// /// <summary> /// <summary>
// /// 在事务提交之后分发事件 /// 在事务提交之后分发事件
// /// </summary> /// </summary>
// /// <param name="eventData"></param> /// <param name="eventData"></param>
// /// <param name="result"></param> /// <param name="result"></param>
// /// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
// /// <returns></returns> /// <returns></returns>
// public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result, public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,
// CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
// { {
// await DispatchDomainEvents(eventData.Context); await DispatchDomainEvents(eventData.Context);
// return await base.SavedChangesAsync(eventData, result, cancellationToken); return await base.SavedChangesAsync(eventData, result, cancellationToken);
// } }
// public override int SavedChanges(SaveChangesCompletedEventData eventData, int result) public override int SavedChanges(SaveChangesCompletedEventData eventData, int result)
// { {
// DispatchDomainEvents(eventData.Context).GetAwaiter().GetResult(); DispatchDomainEvents(eventData.Context).GetAwaiter().GetResult();
// return base.SavedChanges(eventData, result); return base.SavedChanges(eventData, result);
// } }
// private async Task DispatchDomainEvents(DbContext? context) private async Task DispatchDomainEvents(DbContext? context)
// { {
// if (context == null) return; if (context == null) return;
// var entities = context.ChangeTracker var entities = context.ChangeTracker
// .Entries<Entity>() .Entries<Entity>()
// .Where(e => e.Entity.DomainEvents.Any()) .Where(e => e.Entity.DomainEvents.Any())
// .Select(e => e.Entity) .Select(e => e.Entity)
// .ToList(); .ToList();
// var domainEvents = entities var domainEvents = entities
// .SelectMany(e => e.DomainEvents) .SelectMany(e => e.DomainEvents)
// .ToList(); .ToList();
// entities.ForEach(e => e.ClearDomainEvents()); entities.ForEach(e => e.ClearDomainEvents());
// foreach (var domainEvent in domainEvents) foreach (var domainEvent in domainEvents)
// { {
// await publishEndpoint.Publish(domainEvent); await publishEndpoint.Publish(domainEvent);
// } }
// } }
// } }
//} }