在Simple Injector中按名称进行已知注册

时间:2017-11-30 08:14:44

标签: c# inversion-of-control simple-injector mediator

我试图抓住一个Mediator请求的实例,我认为使用IoC可能是可行的。

鉴于以下注册:

assembly.dll

以下课程

container.Register(typeof(IRequest<>), assemblies);
container.Register(typeof(IRequestHandler<,>), assemblies);

按名称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; } } } 解析实例的最佳方法是什么。

我的目的是获取一个JSON-RPC对象,如下所示:"SubtractRequest",解压缩该方法,然后通过该方法名称获取该中介请求的实例。

{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}

基本上我正在尝试找出如何最好地实现我的GetRequestByName()方法来获取正确的中介请求。

1 个答案:

答案 0 :(得分:2)

这是一个非常广泛的问题,答案取决于您使用的框架以及这些数据的来源,但总的来说,您必须:

  • 将传入的请求与特定的IRequest<TResponse>消息相关联。
  • 从该请求消息类型中提取TResponse类型。
  • 将传入的请求反序列化为请求类型。
  • 根据请求类型和IRequestHandler<TRequest, TResponse>类型创建封闭式通用TResponse版本。
  • IRequestHandler<TRequest, TResponse>
  • 解析关闭的Container
  • 调用处理程序的Handle方法。

Github上有一个名为SOLID Services的参考架构应用程序,其中包含有关如何执行此操作的示例。特别是看看Web API项目中的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 Container可以帮助您的东西。只需使用反射遍历程序集中的类型,然后找到名为{request.Method}Request的类型。