ASP NET Основное использование Asyn c Посредник с DbContext - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь получить доступ к dbContext через внедрение зависимостей. И это работает.

Я добавляю dbcontext при запуске

Services.AddDbContextPool<ApplicationDbContext>(options =>
            {
                options.UseMySql(Configuration["ConnectionStrings:DefaultConnection"],
                    b => b.MigrationsAssembly("Persistence"));
                options.UseOpenIddict();
            });

Я также добавляю все обработчики запросов в Mediator

services.AddMediatR(typeof(ChangePasswordRequestHandler).GetTypeInfo().Assembly);

Я вызываю запрос внутри в другой запрос в посреднике. Вот пример

    public class CreateComment : IRequestHandler<CreateCommentRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly IMediator _mediator;
        public CreateComment(ApplicationDbContext context, IMediator mediator)
        {
            _context = context;
            _mediator = mediator;
        }

        public async Task<ResponseViewModel> Handle(CreateCommentRequestModel request, CancellationToken cancellationToken)
        {
            _ = _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None);
            return new ResponseViewModel();
        }

Вот еще один обработчик запроса

    public class SendCommentNotification : IRequestHandler<SendCommentNotificationRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly IMediator _mediator;
        public SendCommentNotification(ApplicationDbContext context, IMediator mediator)
        {
            _context = context;
            _mediator = mediator;
        }

        public async Task<ResponseViewModel> Handle(SendCommentNotificationRequestModel request, CancellationToken cancellationToken)
        {
            await _mediator.Send(new SendNotificationToManyRequestModel(), CancellationToken.None);
            return new ResponseViewModel();
        }
    }

Вот мой третий обработчик

    public class SendNotificationToMany : IRequestHandler<SendNotificationToManyRequestModel, ResponseViewModel>
    {
        private readonly ApplicationDbContext _context;
        private readonly INotificationService _notificationService;
        public SendNotificationToMany(
            INotificationService notificationService, ApplicationDbContext context)
        {
            _notificationService = notificationService;
            _context = context;
        }

        public async Task<ResponseViewModel> Handle(SendNotificationToManyRequestModel request,
            CancellationToken cancellationToken)
        {
           //DbContext is disposed hence not usable when accessed here.

            return new ResponseViewModel();
        }
    }

Проблема в том, что DbContext удаляется, когда работает над третьим хендлером. Что я могу сделать, чтобы решить эту проблему?

Если я добавлю await в первый обработчик, тогда он будет работать как надо, но я не хочу ждать его, я хочу, чтобы он работал в фоновом режиме.

Я знаю, что исправление очень мало, но я не могу его выяснить.

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

Я предполагаю, что ошибка находится здесь:

public async Task<ResponseViewModel> Handle(CreateCommentRequestModel request, CancellationToken cancellationToken)
{
    _ = _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None);
    return new ResponseViewModel();
}

Вам не хватает ключевого слова await, хотя вы вызываете асин c метод.

Поэтому добавьте его в _ = await _mediator.Send(new SendCommentNotificationRequestModel(), CancellationToken.None); и ты должен быть золотым.

0 голосов
/ 24 марта 2020

Kestrel создает область обслуживания на время существования запроса. По окончании области действия все IDisposable службы удаляются.

Вам также нужно будет оставить время жизни запроса открытым, возможно, найдя способ ожидать вашу задачу после ответа было написано клиенту.

Или опубликуйте фоновое задание в фоновом сервисе, который откроет новую область для каждого запроса.

...