TestMasstransitMeditor
continuous-integration/drone/push Build is passing

This commit is contained in:
hang
2024-10-04 17:54:55 +08:00
parent fea009bf0c
commit 874c8718b1
9 changed files with 176 additions and 17 deletions
@@ -71,7 +71,6 @@
<PackageReference Include="RestSharp" Version="112.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
<PackageReference Include="MassTransit.AspNetCore" Version="7.3.1" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.3.0" />
</ItemGroup>
@@ -12676,6 +12676,11 @@
<param name="_trialRepository"></param>
<param name="_mapper"></param>
</member>
<member name="T:IRaCIS.Core.Application.MassTransit.Consumer.MediatorHttpContextScopeFilterExtensions">
<summary>
参考链接:https://github.com/MassTransit/MassTransit/discussions/2498
</summary>
</member>
<member name="T:IRaCIS.Core.Application.ViewModel.TaskAllocationRuleView">
<summary> TaskAllocationRuleView 列表视图模型 </summary>
</member>
@@ -3,10 +3,15 @@
using AutoMapper;
using IRaCIS.Core.Domain;
using MassTransit;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.Application.MassTransit.Consumer;
/// <summary>
/// 添加Subject 触发添加访视 不能代替 Trigger,稽查BatchId 不一致
/// 因为消费者这里的数据库上下文 和消息发送者上下文不是同一个,相当于两个独立的事务
@@ -25,7 +30,7 @@ public class AddSubjectTriggerConsumer(IRepository<SubjectVisit> _subjectVisitRe
{
var addSubjectEvent = context.Message;
{
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
@@ -53,3 +58,44 @@ public class AddSubjectTriggerConsumer(IRepository<SubjectVisit> _subjectVisitRe
await _subjectVisitRepository.AddRangeAsync(svList);
}
}
public class AddSubjectTriggerConsumer2(IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<VisitStage> _visitStageRepository,
IRepository<Trial> _trialRepository,
IMapper _mapper) : IConsumer<AddSubjectTriggerCommand2>
{
public async Task Consume(ConsumeContext<AddSubjectTriggerCommand2> context)
{
var addSubjectEvent = context.Message;
{
Console.WriteLine(_visitStageRepository._dbContext.GetHashCode());
Console.WriteLine("两个 DbContext 不是同一个实例");
}
//添加受试者的时候,获取访视计划列表,添加到受试者访视表。
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == addSubjectEvent.TrialId && t.IsConfirmed).ToListAsync();
var svList = _mapper.Map<List<SubjectVisit>>(visitPlanList);
var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == addSubjectEvent.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync();
svList.ForEach(t =>
{
t.SubjectId = addSubjectEvent.SubjectId;
t.TrialId = addSubjectEvent.TrialId;
t.TrialSiteId = addSubjectEvent.TrialSiteId;
t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false;
t.Id = NewId.NextGuid();
});
await _subjectVisitRepository.AddRangeAsync(svList);
}
}
@@ -0,0 +1,83 @@
using IRaCIS.Core.Application.MassTransit.Consumer;
using MassTransit;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace IRaCIS.Core.Application.MassTransit.Consumer;
/// <summary>
/// 参考链接:https://github.com/MassTransit/MassTransit/discussions/2498
/// </summary>
public static class MediatorHttpContextScopeFilterExtensions
{
public static void UseHttpContextScopeFilter(this IMediatorConfigurator configurator, IServiceProvider serviceProvider)
{
var filter = new HttpContextScopeFilter(serviceProvider.GetRequiredService<IHttpContextAccessor>());
configurator.ConfigurePublish(x => x.UseFilter(filter));
configurator.ConfigureSend(x => x.UseFilter(filter));
configurator.UseFilter(filter);
}
}
public class HttpContextScopeFilter :
IFilter<PublishContext>,
IFilter<SendContext>,
IFilter<ConsumeContext>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextScopeFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
private void AddPayload(PipeContext context)
{
if (_httpContextAccessor.HttpContext == null)
return;
var serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
context.GetOrAddPayload(() => serviceProvider);
context.GetOrAddPayload<IServiceScope>(() => new NoopScope(serviceProvider));
}
public Task Send(PublishContext context, IPipe<PublishContext> next)
{
AddPayload(context);
return next.Send(context);
}
public Task Send(SendContext context, IPipe<SendContext> next)
{
AddPayload(context);
return next.Send(context);
}
public Task Send(ConsumeContext context, IPipe<ConsumeContext> next)
{
AddPayload(context);
return next.Send(context);
}
public void Probe(ProbeContext context)
{
}
private class NoopScope :
IServiceScope
{
public NoopScope(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public void Dispose()
{
}
public IServiceProvider ServiceProvider { get; }
}
}
+9 -3
View File
@@ -16,6 +16,7 @@ using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
@@ -126,7 +127,11 @@ namespace IRaCIS.Core.Application.Service
}
//My project is a monolithic project,And the efcore context repository is scoped registered.
public async Task<IResponseOutput> TestMasstransitMeditor([FromServices] IScopedMediator _mediator, [FromServices] IRepository<TestLength> _testLengthRepository)
public async Task<IResponseOutput> TestMasstransitMeditor(
[FromServices] IScopedMediator _mediatorScoped,
[FromServices] IMediator _mediator,
[FromServices] IRepository<TestLength> _testLengthRepository
)
{
var dbContext = _testLengthRepository._dbContext;
@@ -143,12 +148,13 @@ namespace IRaCIS.Core.Application.Service
}
// add 1 recored
await _testLengthRepository.AddAsync(new TestLength() { Name = "xxxx" });
// The consumer method will inject the repository and add 3 pieces of data, but the savechanges method of the repository will not be called
await _mediator.Send(new AddSubjectTriggerCommand { SubjectId = Guid.Empty });
await _mediatorScoped.Send(new AddSubjectTriggerCommand { SubjectId = Guid.Empty });
await _mediator.Send(new AddSubjectTriggerCommand2 { SubjectId = Guid.Empty });
// this will save 1 record not 4 record ,Why is the dbcontext different? Can it be in the same transaction?
await _testLengthRepository.SaveChangesAsync();