Модификация команд Mediatr с помощью IRequestPreProcessor или IPipelineBehavior? - PullRequest
0 голосов
/ 12 декабря 2018

Я работаю над реализацией авторизации на моем конвейере Mediatr и столкнулся с небольшим количеством проблем.Я уже реализовал пользовательский интерфейс, который IRequest объекты могут реализовать, чтобы сообщить поведению конвейера, что данный объект нуждается в авторизации против аутентифицированного пользователя и ClientId, которые они передают со своим запросом.Этот слой авторизации работает отлично.Однако я хочу немного расширить это поведение и реализовать IReqestPreProcessor, который может изменять основную команду.

В большинстве моих случаев использования аутентифицированный пользователь будет иметь претензии только к 1 клиенту.Я пытаюсь изменить конвейер для автоматического выбора идентификатора клиента пользователя из системы.Мне удалось установить логику для получения информации о клиенте пользователя, но я не могу повлиять на фактический запрос до конца его прохождения через конвейер.Теперь я не совсем уверен, как я мог бы реализовать это поведение.

Вот мой соответствующий интерфейс:

public interface IClientAuthorizationCommand
{
    Guid? ClientId { get; set; }
}

И мой препроцессор запросов выглядит примерно так:

public class UserClientPreprocessor<TRequest> : IRequestPreProcessor<TRequest>
{
    private readonly DbContext _context;
    private readonly ICurrentUserAccessor _currentUserAccessor;

    public UserClientPreprocessor(DispenseMeDbContext context, ICurrentUserAccessor currentUserAccessor)
    {
        _context = context;
        _currentUserAccessor = currentUserAccessor;
    }

    public async Task Process(TRequest request, CancellationToken cancellationToken)
    {
        if (request is IClientAuthorizationCommand req)
        {
            if (req.ClientId.HasValue) return;
            var user = await new UserFetcher(_context).FetchByUsername(_currentUserAccessor.GetCurrentUsername());
            var clientUsers = _context.ClientUsers.Where(n =>
                !n.DeletedDate.HasValue && n.UserId == user.UserId);

            if (!await clientUsers.AnyAsync(cancellationToken))
                throw new NoUserClientsExceptions(user.Username);

            if (await clientUsers.CountAsync(cancellationToken) > 1)
                throw new MultipleUserClientsException(user.Username);

            ((IClientAuthorizationCommand)request).ClientId = clientUsers.First()?.Client?.ClientIdentifier;
        }
    }
}

Если я пройдусь по приведенному выше коду, все в этом классе вызывается и работает как положено.Однако команда, которая передается другим IPipelineBehaviors, не затрагивается.

...