2

HTTP Get リクエストを送信した場合:

/api/Company/1

の内容を確認し、jsonOwinMiddlewareを使用している場所があります。contextpathIAsyncRequest<T>

どの非同期リクエストを使用するかを知るために、パスのマッピングがありTypeますIAsyncRequest<T>

var mappings = new Dictionary<string, Type> { ["api/Company/{id}"] = typeof(GetCompanyRequest) }

Type request;
var result = mappings.TryGetValue(context.Requst.Path.Value, out request);

を使用しJObjectて のインスタンスを作成しますGetCompanyRequest

var get = new JObject { ["id"] = "1" /* obtained from the url */ }
var instantiatedRequest = JObject.ToObject(request);

私が使用する理由JObjectは、PUT および POST 要求の場合、JSON 本体を直接要求に逆シリアル化するためです。

object instantiatedRequestパズルの最後のピースは、メディエーター パイプラインを介してこれを送信しています。明らかTask<T> SendAsync<T>(IAsyncRequest<T> request)にうまくいきません。

興味深いことに、ユーザーにTポストバックするために常にシリアル化するため、知る必要はありません。string

では、これに対応するために署名Task<object> SendAsync(object request)を現在のメディエーター フレームワークに組み込むことはできますか? (求めているのではなく、可能ですか?)

ソースコードを見る

私はこれを見つけましたmediator.cs

    private TWrapper GetHandler<TWrapper, TResponse>(object request, Type handlerType, Type wrapperType)
    {
        var requestType = request.GetType();

        var genericHandlerType = _genericHandlerCache.GetOrAdd(requestType, handlerType, (type, root) => root.MakeGenericType(type, typeof(TResponse)));
        var genericWrapperType = _wrapperHandlerCache.GetOrAdd(requestType, wrapperType, (type, root) => root.MakeGenericType(type, typeof(TResponse)));

        var handler = GetHandler(request, genericHandlerType);

        return (TWrapper) Activator.CreateInstance(genericWrapperType, handler);
    }

    private object GetHandler(object request, Type handlerType)
    {
        try
        {
            return _singleInstanceFactory(handlerType);
        }
        catch (Exception e)
        {
            throw BuildException(request, e);
        }
    }

その 2 番目GetHandlerには必要なパラメーターがあり、最初のパラメーターは によって呼び出されるSendAsyncものです。何かを貼り付けても問題はありません。

それを行うことに懸念はありますか?

4

2 に答える 2

1

これが、RabbitMqRequestHandler から MediatR を呼び出す方法です。基本的に、キュー メッセージを使用して任意のコマンド タイプを起動したいと考えていました。この概念実証は、別の機能を作成するのに役立ちました。

重要: これは (MediatR 7.0.0) で 動作します。バージョン 9 にアップグレードすると、機能が動作しなくなりました。

どうぞ:

private async Task HandleMessage(SmartConfigQueueMessage message)
{
    try
    {
        var type = AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .FirstOrDefault(t => t.Name == message.OperationName);

        var resultType = type.GetInterfaces()
            .Where(r => r.FullName.Contains("SmartConfig"))? //MY ASSEMBLY MAIN NAMESPACE
            .FirstOrDefault().GenericTypeArguments
            .FirstOrDefault();

        dynamic command = message.Variables.ToObject(type);

        var method = _mediator.GetType().GetMethod("Send");
        var generic = method.MakeGenericMethod(resultType);
        var response = generic.InvokeAsync(_mediator, new object[] {command, new CancellationToken()});
    }
    catch (Exception ex)
    {
        _logger.LogInformation($"Consumer handler error: {ex.Message}");
    }

    // We just print this message   
    _logger.LogInformation($"Consumer message received: {message.OperationName}");
}

MediatR は、すべてのクエリとコマンドを非同期的に処理します。したがって、次の拡張機能が必要です。

public static class GenericMethodExtensions
{
    public static async Task<object> InvokeAsync(this MethodInfo @this, object obj, params object[] parameters)
    {
        var task = (Task)@this.Invoke(obj, parameters);
        await task.ConfigureAwait(false);
        var resultProperty = task.GetType().GetProperty("Result");
        return resultProperty?.GetValue(task);
    }
} 
于 2020-08-25T12:08:12.687 に答える