c#泛型命令类型推断

本文关键字:类型 命令 泛型 | 更新日期: 2023-09-27 17:54:57

我必须使用我无法控制的特定API:

TResponse Request<TRequest, TResponse>(TRequest request) 
    where TRequest : class 
    where TResponse : class;

这是一个来自EasyNetQ库的RabbitMq RPC包装器

我想有一些方法来定义TRequest到TResponse关系,这样我就不必像这样手动匹配它们:

this._client.Request<CancelPaymentByMerchantRequest, CancelPaymentByMerchantResponse>(request);

我想到的解决方案是:

public interface ICommand<TRequest, TResponse> { }
public class StartCommand : ICommand<StartCommand, StartResponse>
{
    public int Id { get; set; }
    public string Args { get; set; }
}
public class StartResponse
{
    public bool Success { get; set; }
    public string Error { get; set; }
}

和它的消费者:

 public TResponse Send<TRequest, TResponse>(ICommand<TRequest, TResponse> payload)
            where TRequest : class
            where TResponse : class
        {
            var result = client.Request<TRequest, TResponse>((TRequest)payload);
            return result;
        }

是否可以在ICommand标记界面上摆脱请求类型?

我还担心拥有标记接口的额外成本,然后在实际的库调用中直接从它进行强制转换。

c#泛型命令类型推断

实现这一目标的最简单方法是为每个TRequest类型添加一次围绕Send的抽象:

public SpecificResponse Send(SpecificRequest payload)
{
    return Send<SpecificRequest, SpecificResponse>(payload);
}

您必须为每个TRequest, TResponse对定义Send的重载,但是您的应用程序的其余部分可以使用这些"强类型"版本,以避免在任何地方重述关系。

如何编排这取决于你,但我更喜欢每个请求/响应类型的接口/类作为通用层的中介(或者一个带有一堆契约的大接口也可以工作)。