我正在尝试(已经浪费了一天时间)实现我自己的 Mediator 设计模式的轻量级版本,并且我遇到了从 DI(依赖注入)容器调用服务的问题,出现“未注册服务”异常。
这里的主要目标是有一个调解器服务,它使用响应类型向他们的处理程序发送请求定义在请求本身
(为了更清晰的代码)。首先,我创建了三个必要的接口:
IRequest
接口,它定义了响应类型
TResponse
(这是任务/问题中最重要的部分)。该接口将附加到每个请求实现,以定义请求本身和它的返回类型。interface IRequest<out TResponse> { }
IRequestHandler
其中
TRequest
相当于上面
IRequest
接口的实现)。interface IRequestHandler<in TRequest, out TResponse> where TRequest : IRequest<TResponse>
{
TResponse Handle(TRequest request);
}
Mediator
ISender
接口,它只是发送一个
Request
到它的
RequestHandler
并返回一些
Response
.interface ISender
{
TResponse Send<TResponse>(IRequest<TResponse> request);
}
其次,我实现了上面的接口。
一个无参数的
Request
,它以字符串作为返回类型(或任何其他类型)来实现
IRequest
。class Request : IRequest<string> { }
RequstHandler
实现其
IRequestHandler
.class RequestHandler : IRequestHandler<Request, string>
{
public string Handle(Request request)
{
return "OK";
}
}
Sender
实现
ISender
接口。class Sender : ISender
{
private readonly IServiceProvider _serviceProvider;
public Sender(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public TResponse Send<TResponse>(IRequest<TResponse> request)
{
// HERE IS THE ERROR
var handler = _serviceProvider.GetRequiredService<IRequestHandler<IRequest<TResponse>,
TResponse>>();
return handler.Handle(request);
}
}
最后,我将服务注册为:
IServiceCollection services = new ServiceCollection();
services.AddScoped<ISender, Sender>();
services.AddScoped<IRequestHandler<Request, string>, RequestHandler>();
当我执行以下语句时:
_sender.Send(new Request());
错误:没有注册类型为 ConsoleApp1.IRequestHandler`2[ConsoleApp1.IRequest`1[System.String],System.String]' 的服务。 (我正在使用控制台应用程序只是为了测试)
错误本身非常简单,因为我没有实现
IRequest
而是
Request
,所以像
TRequest
这样的东西可能更有意义。然而,the 对我来说最重要的是能够发送一个Request
,其返回类型的格式为:
_sender.Send(new Request()); // return type is known based on IRequest interface
并且基于
IRequest
接口立即识别返回类型而无需显式指定它,例如:
_sender.Send<Request, string>(new Request());
非常感谢任何建议。