在 Simple Injector 中通过名称获取已知注册
Getting known registration by name in Simple Injector
我正在尝试获取中介请求的实例,我认为使用 IoC 是可行的。
鉴于以下注册:
container.Register(typeof(IRequest<>), assemblies);
container.Register(typeof(IRequestHandler<,>), assemblies);
以及以下class
public class SubtractRequest: IRequest<int>
{
public int Left { get; set; }
public int Right{ get; set; }
public SubtractRequest() { }
internal class Handler : IRequestHandler<SubtractRequest, int>
{
public Handler() {}
public string Handle(SubtractRequest request)
{
return request.Left - request.Right;
}
}
}
按名称解析实例的最佳方法是什么 "SubtractRequest"
。
我的意图是获取一个 JSON-RPC 对象,如下所示:{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
,提取方法,然后通过该方法名称获取该中介请求的实例。
var request = JsonConvert.DeserializeObject<JsonRpcRequest>(jsonRpcRequest);
var mediatorRequest = GetRequestByName($"{request.Method}Request"); //Via IoC?
//SetParams(mediatorRequest) [todo]
var result = mediator.Send(mediatorRequest).Result;
基本上我正在尝试找出如何最好地实现我的 GetRequestByName() 方法以获得正确的调解器请求。
这是一个非常宽泛的问题,答案取决于您使用的框架以及这些数据的输入方式,但总的来说,您必须:
- 将传入请求与特定
IRequest<TResponse>
消息相关联。
- 从该请求消息类型中提取
TResponse
类型。
- 将传入请求反序列化为请求类型。
- 根据请求类型和
TResponse
类型创建一个封闭的通用 IRequestHandler<TRequest, TResponse>
版本。
- 解决从
Container
. 关闭 IRequestHandler<TRequest, TResponse>
- 调用处理程序的
Handle
方法。
Github 上有一个参考架构应用程序,在 Web API 项目中称为 SOLID Services that contains examples on how to do this. Especially take a look at the QueryDelegatingHandler 实现,因为它基本上可以满足您的需要。您可能想下载完整的项目并试用它,但请注意接口的名称略有不同。在您调用 IRequest<TResponse>
和 IRequestHandler<TRequest, TResponse>
的地方,示例项目调用此 IQuery<TResult>
和 IQueryHandler<TQuery, TResult>
。不过思路是一样的。
最后提醒一下,请删除以下注册:
container.Register(typeof(IRequest<>), assemblies);
IRequest<TResponse>
是消息的定义。一条消息是一个 DTO,创建它们与您的 DI 容器无关。将它们注册到您的容器中可能会阻止您成功验证容器的配置。您唯一应该注册的是 IRequestHandler<,>
.
更新:
您的代码基本上应该是这样的:
Type requestType = GetRequestTypeByName($"{request.Method}Request");
dynamic request = JsonConvert.DeserializeObject(requestType, jsonRpcRequest);
object result = ((dynamic)mediator).Send(request).Result;
您将必须实施 GetRequestTypeByName
。这是 而不是 DI 容器可以帮助您的东西。只需使用反射检查程序集中的类型并找到名为 {request.Method}Request
.
的类型
我正在尝试获取中介请求的实例,我认为使用 IoC 是可行的。
鉴于以下注册:
container.Register(typeof(IRequest<>), assemblies);
container.Register(typeof(IRequestHandler<,>), assemblies);
以及以下class
public class SubtractRequest: IRequest<int>
{
public int Left { get; set; }
public int Right{ get; set; }
public SubtractRequest() { }
internal class Handler : IRequestHandler<SubtractRequest, int>
{
public Handler() {}
public string Handle(SubtractRequest request)
{
return request.Left - request.Right;
}
}
}
按名称解析实例的最佳方法是什么 "SubtractRequest"
。
我的意图是获取一个 JSON-RPC 对象,如下所示:{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
,提取方法,然后通过该方法名称获取该中介请求的实例。
var request = JsonConvert.DeserializeObject<JsonRpcRequest>(jsonRpcRequest);
var mediatorRequest = GetRequestByName($"{request.Method}Request"); //Via IoC?
//SetParams(mediatorRequest) [todo]
var result = mediator.Send(mediatorRequest).Result;
基本上我正在尝试找出如何最好地实现我的 GetRequestByName() 方法以获得正确的调解器请求。
这是一个非常宽泛的问题,答案取决于您使用的框架以及这些数据的输入方式,但总的来说,您必须:
- 将传入请求与特定
IRequest<TResponse>
消息相关联。 - 从该请求消息类型中提取
TResponse
类型。 - 将传入请求反序列化为请求类型。
- 根据请求类型和
TResponse
类型创建一个封闭的通用IRequestHandler<TRequest, TResponse>
版本。 - 解决从
Container
. 关闭 - 调用处理程序的
Handle
方法。
IRequestHandler<TRequest, TResponse>
Github 上有一个参考架构应用程序,在 Web API 项目中称为 SOLID Services that contains examples on how to do this. Especially take a look at the QueryDelegatingHandler 实现,因为它基本上可以满足您的需要。您可能想下载完整的项目并试用它,但请注意接口的名称略有不同。在您调用 IRequest<TResponse>
和 IRequestHandler<TRequest, TResponse>
的地方,示例项目调用此 IQuery<TResult>
和 IQueryHandler<TQuery, TResult>
。不过思路是一样的。
最后提醒一下,请删除以下注册:
container.Register(typeof(IRequest<>), assemblies);
IRequest<TResponse>
是消息的定义。一条消息是一个 DTO,创建它们与您的 DI 容器无关。将它们注册到您的容器中可能会阻止您成功验证容器的配置。您唯一应该注册的是 IRequestHandler<,>
.
更新:
您的代码基本上应该是这样的:
Type requestType = GetRequestTypeByName($"{request.Method}Request");
dynamic request = JsonConvert.DeserializeObject(requestType, jsonRpcRequest);
object result = ((dynamic)mediator).Send(request).Result;
您将必须实施 GetRequestTypeByName
。这是 而不是 DI 容器可以帮助您的东西。只需使用反射检查程序集中的类型并找到名为 {request.Method}Request
.