jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
11k stars 1.16k forks source link

How to control the container used by RequestHandler in the pipeline #869

Closed soul-soft closed 1 year ago

soul-soft commented 1 year ago
  1. I hope these two requests use different IServiceScope to parse AppDbContext, so that they can execute in different DbContext
  2. Can I control the IServiceScope used by the RequestHandler in the pipeline
  3. Make these two requests execute in parallel in different transactions
    
    public class NewTransaction<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : notnull
    {
    private readonly IServiceProvider _services;
    public NewTransaction(IServiceProvider services)
    {
        _services = services;
    }
    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        using (var scope = _services.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
            using (var transaction = context.Database.BeginTransaction())
            {
                var response = await next();
                await transaction.CommitAsync(cancellationToken);
                return response;
            }
        }
    }
    }
    public class DeleteStudentReuqest : IRequest 
    {
    public int Id { get; set; }
    public DeleteStudentReuqest(int id)
    {
        Id = id;
    }
    }
    public class DeleteStudentReuqestHandler
    : IRequestHandler<DeleteStudentReuqest>
    {
    private readonly AppDbContext _context;
    public DeleteStudentReuqestHandler(AppDbContext context)
    {
        _context = context;
    }
    public Task Handle(DeleteStudentReuqest request, CancellationToken cancellationToken)
    {
        //logic _context
        return Task.CompletedTask;
    }
    }
    public static class MediatorExtensions
    {
    public static void SendBatch<TRequest>(this IMediator mediator,IEnumerable<TRequest> requests)
        where TRequest : IRequest
    {
        var tasks = new List<Task>();   
        foreach (var request in requests)
        {
            var task = mediator.Send(request);
            tasks.Add(task);
        }
        Task.WaitAll(tasks.ToArray());
    }
    }

class Program { static async Task Main(string[] args) { var services = new ServiceCollection(); services.AddDbContext(); services.AddMediatR(c => { c.RegisterServicesFromAssemblyContaining(); c.AddBehavior(typeof(IPipelineBehavior<,>), typeof(NewTransaction<,>)); }); var sp = services.BuildServiceProvider(); var mediator = sp.GetRequiredService(); mediator.SendBatch(new IRequest[] { new DeleteStudentReuqest(1), new DeleteStudentReuqest(2), }); } }

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

github-actions[bot] commented 1 year ago

This issue was closed because it has been stalled for 14 days with no activity.