2

我必须使用我无法控制的特定 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 标记界面上的 TRequest 类型?

我还担心与标记接口相关的额外成本,然后在实际的库调用中直接从中转换。

任何意见,将不胜感激。

4

1 回答 1

3

实现这一点的最简单方法就是为Send每种TRequest类型添加一个抽象:

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

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

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

于 2016-07-04T07:46:54.727 回答