gpt4 book ai didi

c# - MediatR 无需键入即可发送对象

转载 作者:行者123 更新时间:2023-12-05 06:42:12 25 4
gpt4 key购买 nike

如果我发送 HTTP Get 请求:

/api/Company/1

我有一个 OwinMiddleware我在哪里使用 context确定pathIAsyncRequest<T> 的 json 内容.

要知道要使用哪个异步请求,我有一个到 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 主体直接反序列化为请求。

拼图的最后一 block 现在正在发送这个 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);
}
}

那一秒GetHandler有我需要的参数,第一个是SendAsync调用的,我看不出有什么问题。

这样做有什么顾虑吗?

最佳答案

这就是我从 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);
}
}

关于c# - MediatR 无需键入即可发送对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38064079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com