【发布时间】:2020-09-18 05:11:10
【问题描述】:
所以我正在尝试创建一些流畅的代码来执行网络请求。我希望它看起来像这样......
// Result should be of type MyClass
var result = await _webRequests.Get("Api/Route/Here")
.Returns<MyClass>()
.HasToken("MY_TOKEN")
.ExecuteAsync();
// Result should be of type HttpResponseMessage
var result = await _webRequests.Get("Api/Route/Here")
.HasToken("MY_TOKEN")
.ExecuteAsync();
我的目标是如果没有指定 Returns 方法,则返回一个 HttpResponseMessage,如果指定了,则返回指定的类型。
_webRequests 是一个接口,里面有一些基本的 HttpMethod 调用
IUseRequired Get(string url);
IUseRequired Post(string url);
那么IUseRequired接口就有调用所需的方法了……
IUseOptionalOrExecute UsesApi(string apiName);
UsesApi 方法所做的只是告诉在使用 IHttpClientFactory 时要使用哪个 HTTPClient。
现在 IUseOptionalOrExecute 接口是问题开始的地方...
IUseOptionalOrExecute Returns<TReturn>();
IUseOptionalOrExecute HasToken(string token);
Task<TReturn> ExecuteAsync();
我希望它看起来像这样,因此传入 Returns 方法的任何内容都将用作 ExecuteAsync 方法的返回值。当然这不起作用,因为 ExecuteAsync 不知道 TReturn 是什么。我曾考虑在调用 Returns 方法时将类型存储为变量,但我无法将 Execute 的返回类型设置为变量类型。或者我可以吗? 任何人都知道我可以解决这个问题的方法吗?谢谢!
【问题讨论】:
-
正如 mcc 指出的那样,有一种方法,但这意味着您必须创建一个全新的泛型类型,并且一旦您处理了所有可能性(例如,您是否试图阻止人们第二次使用不同类型的电话拨打
Returns?)。请仔细注意更改原因,并确保您的耦合选择反映了这些原因。您真的希望必须为每个方法调用单独提供令牌,而不是使用自动将给定令牌添加到每个请求的服务吗?你为什么要编写自己的库? -
我们正在尝试使用我们公司中其他人可以调用的库,这样他们就可以使用几行代码,而不是每次都编写大量代码。这样的设置更好,所以我们不会让每个人都使用自己的方式访问 API,并且代码开始看起来相似并且更容易为每个人调试。我确实同意自动设置令牌会更好,尽管这对于通用库来说既困难又混乱。此外,可能存在需要令牌的端点,而其他端点则不需要,因此无论如何都需要动态更改它。
-
我绝对推荐查看为相同目的编写的其他库。例如,如果您使用 RestSharp,您就不必花时间创建流畅的 API 来构建请求,您可以更专注于构建工厂和包装器,专注于您的应用的特定内容。
标签: c# generics interface httpclient fluent