diff --git a/IRC.Core.SCP/Program.cs b/IRC.Core.SCP/Program.cs index dfa4bb17e..7ac6b53e7 100644 --- a/IRC.Core.SCP/Program.cs +++ b/IRC.Core.SCP/Program.cs @@ -73,7 +73,6 @@ builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resourc // 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim() builder.Services.AddControllers(options => { - //options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); diff --git a/IRC.Core.SCP/Properties/launchSettings.json b/IRC.Core.SCP/Properties/launchSettings.json index 11587df61..98baafbab 100644 --- a/IRC.Core.SCP/Properties/launchSettings.json +++ b/IRC.Core.SCP/Properties/launchSettings.json @@ -10,5 +10,16 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Test_IRC_SCP" } + }, + "Uat_IRC_SCP": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:6200", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Uat_IRC_SCP" + } } + } } diff --git a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json index e293c065a..b2a640967 100644 --- a/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json +++ b/IRC.Core.SCP/appsettings.Uat_IRC_SCP.json @@ -7,7 +7,7 @@ } }, "ObjectStoreService": { - "ObjectStoreUse": "MinIO", + "ObjectStoreUse": "AliyunOSS", "AliyunOSS": { "regionId": "cn-shanghai", "internalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com", diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 6ca55a98b..7ea14af41 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -146,6 +146,11 @@ builder.Services.AddMediator(cfg => cfg.AddConsumer(); }); +builder.Services.AddMassTransit(cfg => +{ + cfg.UsingInMemory(); +}); + // EasyCaching 缓存 builder.Services.AddEasyCachingSetup(_configuration); diff --git a/IRaCIS.Core.API/_ServiceExtensions/AutoMapperSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/AutoMapperSetup.cs index 5797d8902..70ef3e5d5 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/AutoMapperSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/AutoMapperSetup.cs @@ -1,5 +1,6 @@ using AutoMapper.EquivalencyExpression; using IRaCIS.Core.Application.Service; +using IRaCIS.Core.Domain.Models; using Microsoft.Extensions.DependencyInjection; namespace IRaCIS.Core.API @@ -14,11 +15,15 @@ namespace IRaCIS.Core.API //AutoMapper.Collection.EntityFrameworkCore automapper.AddCollectionMappers(); + + // 全局忽略 DomainEvents 属性 + automapper.AddGlobalIgnore(nameof(Entity.DomainEvents)); + #region 会使 IncludeMembers 失效 不能全局使用 //mapping an EntityFramework Core DbContext-object. //automapper.UseEntityFrameworkCoreModel(services); - + //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 @@ -27,7 +32,7 @@ namespace IRaCIS.Core.API // // not want to map a null Guid? value to db Guid value //}))); #endregion - + }, typeof(QCConfig).Assembly); diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index ae82e3027..3713359d6 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -4,6 +4,7 @@ using Hangfire.SqlServer; using IRaCIS.Core.Application.Triggers; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore; +using IRaCIS.Core.Infra.EFCore.Interceptor; using Medallion.Threading; using Medallion.Threading.SqlServer; using Microsoft.EntityFrameworkCore; @@ -23,6 +24,7 @@ namespace IRaCIS.Core.API services.AddHttpContextAccessor(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); // First, register a pooling context factory as a Singleton service, as usual: diff --git a/IRaCIS.Core.Domain/BaseModel/Entity.cs b/IRaCIS.Core.Domain/BaseModel/Entity.cs index af38e8fd2..4c2c23be8 100644 --- a/IRaCIS.Core.Domain/BaseModel/Entity.cs +++ b/IRaCIS.Core.Domain/BaseModel/Entity.cs @@ -26,27 +26,26 @@ namespace IRaCIS.Core.Domain.Models #region 领域事件 仅仅允许通过提供的方法进行操作 - //[NotMapped] - //private readonly List _domainEvents = []; + private readonly List _domainEvents = []; - //[NotMapped] - //public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); + [NotMapped] + public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); - //public void AddDomainEvent(DomainEvent domainEvent) - //{ - // _domainEvents.Add(domainEvent); - //} + public void AddDomainEvent(DomainEvent domainEvent) + { + _domainEvents.Add(domainEvent); + } - //public void RemoveDomainEvent(DomainEvent domainEvent) - //{ - // _domainEvents.Remove(domainEvent); - //} + public void RemoveDomainEvent(DomainEvent domainEvent) + { + _domainEvents.Remove(domainEvent); + } - //public void ClearDomainEvents() - //{ - // _domainEvents.Clear(); - //} + public void ClearDomainEvents() + { + _domainEvents.Clear(); + } #endregion diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs index 87ce315a5..e12a02704 100644 --- a/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs +++ b/IRaCIS.Core.Infra.EFCore/Interceptor/DispatchDomainEventsInterceptor.cs @@ -1,59 +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; +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 -// { +namespace IRaCIS.Core.Infra.EFCore.Interceptor +{ + public class DispatchDomainEventsInterceptor(IPublishEndpoint publishEndpoint) : SaveChangesInterceptor + { -// //领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态 + //领域事件通常与数据变更密切相关。如果在 SaveChanges 之前发布事件,有可能事件发布时的数据状态还没有被持久化到数据库。这可能导致事件消费者看到的是一个不一致的状态 -// /// -// /// 在事务提交之后分发事件 -// /// -// /// -// /// -// /// -// /// -// public override async ValueTask 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; + /// + /// 在事务提交之后分发事件 + /// + /// + /// + /// + /// + public override async ValueTask 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() -// .Where(e => e.Entity.DomainEvents.Any()) -// .Select(e => e.Entity) -// .ToList(); + var entities = context.ChangeTracker + .Entries() + .Where(e => e.Entity.DomainEvents.Any()) + .Select(e => e.Entity) + .ToList(); -// var domainEvents = entities -// .SelectMany(e => e.DomainEvents) -// .ToList(); + var domainEvents = entities + .SelectMany(e => e.DomainEvents) + .ToList(); -// entities.ForEach(e => e.ClearDomainEvents()); + entities.ForEach(e => e.ClearDomainEvents()); -// foreach (var domainEvent in domainEvents) -// { -// await publishEndpoint.Publish(domainEvent); -// } -// } -// } -//} + foreach (var domainEvent in domainEvents) + { + await publishEndpoint.Publish(domainEvent); + } + } + } +}