C# 创建fluent api问题
我正在尝试创建一个流畅的api。对于我的学习,我将要删除一个简单的rest客户机 到目前为止,我得到的是:C# 创建fluent api问题,c#,C#,我正在尝试创建一个流畅的api。对于我的学习,我将要删除一个简单的rest客户机 到目前为止,我得到的是: public interface IOAuthAuthentication { void AddParameter(string name, string value); } public interface IRestClient { IRestClient WithBasicAuthentication(string username, string password
public interface IOAuthAuthentication
{
void AddParameter(string name, string value);
}
public interface IRestClient
{
IRestClient WithBasicAuthentication(string username, string password);
IRestClient WithNetworkAuthentication(string username, string password);
IOAuthAuthentication WithOAuthAuthentication(Uri authorizationUrl, string clientId, string clientSecret);
}
public class RestClient : IRestClient
{
public RestClient(Uri root)
{
}
public IRestClient WithBasicAuthentication(string username, string password)
{
return this;
}
public IRestClient WithNetworkAuthentication(string username, string password)
{
return this;
}
public IOAuthAuthentication WithOAuthAuthentication(Uri authorizationUrl, string clientId, string clientSecret)
{
return null;
}
}
我想象过这样使用它:
IRestClient restClient = new RestClient(new Uri(""))
.WithBasicAuthentication("", "")
.WithNetworkAuthentication("", "")
.WithOAuthAuthentication(new Uri(""), "", "")
.AddParameter("", "");
restClient.WithOAuthAuthentication(
oauth =>
{
oauth.SetEndpoint("https://www.example.com")
.AddParameter("Param1", "CoolValue")
.AddParameter("Param2", "CoolValue2")
.Authenticate();
}
)
.YourNextFluentAction();
现在,很明显,您不会有3种不同的身份验证方法,但我想这将在方法本身中处理
对于OAuth身份验证,用户可能需要添加一个自定义参数,因此我定义了一个不同的返回类型。。。但是,这有一个副作用,即您不能使用with OAuthauthentication()
或.AddParameter()
结束链
用流利的语言处理这个问题的正确方法是什么?我看过一些.net核心的东西,可能在想:
WithOAuthAuthentication("", "", "", x => x.AddParameter("", ""))
并让带有OAuthauthentication()的返回IRestClient
那会更“流畅”吗
但是如果您必须添加一组参数,那么代码看起来就不那么酷了:
.WithOAuthAuthentication("", "", "", x =>
{
x.AddParameter("", "")
.AddParameter("", "")
});
这是一个相当主观的问题,因为有很多风格的fluentapi。有些甚至可以对this
上下文进行变异,在这种情况下,您可以为OAuth使用开始/结束模式,并且在这两个方法调用之间将是自定义OAuth提供程序this
的变异版本
如果是我,我会将您的基本方法签名修改为:
public IRestClient WithOAuthAuthentication(Action<IOAuthAuthentication> oauthHandler)
{
oauthHandler?.Invoke(new OAuthAuthentication(this));
return this;
}
这是一个相当主观的问题,因为有很多风格的fluentapi。有些甚至可以对this
上下文进行变异,在这种情况下,您可以为OAuth使用开始/结束模式,并且在这两个方法调用之间将是自定义OAuth提供程序this
的变异版本
如果是我,我会将您的基本方法签名修改为:
public IRestClient WithOAuthAuthentication(Action<IOAuthAuthentication> oauthHandler)
{
oauthHandler?.Invoke(new OAuthAuthentication(this));
return this;
}
对于OAuth身份验证,用户可能需要添加一个自定义参数,因此我定义了一个不同的返回类型
——我不明白您的意思。对于Fluent接口,方法的返回类型总是this
。“你必须在这个限制范围内工作。”罗伯塔维——我的意思是。。使用OAuth身份验证,用户可能需要添加特定于该身份验证方法的内容。。。AddParameter()不适用于其他类型。。。那么把它放在RestClient中有意义吗?然后用户就可以盲目地调用该方法,甚至没有任何意义。那么,您可能希望它成为流畅调用中某个地方的新OAuth(某物)
。您可以像ASP.NET Core Identity那样做。它返回一个ISomething
,它不是.NET核心应用程序使用的IServiceCollection
Interface@RobertHarvey看看一些.net核心代码,似乎他们做了我的最后一个示例,他们只是让外部对象返回这个,并包含一个Action/Func lambda,如果您需要设置特定于它的东西。。。对于OAuth身份验证,用户可能需要添加一个自定义参数,因此我定义了一个不同的返回类型——我不明白您的意思。对于Fluent接口,方法的返回类型总是this
。“你必须在这个限制范围内工作。”罗伯塔维——我的意思是。。使用OAuth身份验证,用户可能需要添加特定于该身份验证方法的内容。。。AddParameter()不适用于其他类型。。。那么把它放在RestClient中有意义吗?然后用户就可以盲目地调用该方法,甚至没有任何意义。那么,您可能希望它成为流畅调用中某个地方的新OAuth(某物)。您可以像ASP.NET Core Identity那样做。它返回一个ISomething
,它不是.NET核心应用程序使用的IServiceCollection
Interface@RobertHarvey看看一些.net核心代码,似乎他们做了我的最后一个示例,他们只是让外部对象返回这个,并包含一个Action/Func lambda,如果您需要设置特定于它的东西。。。这是流畅的还是更像.net核心的东西?这也被称为“Hadouken”风格,因为像这样链接它们非常类似于Lisp编码风格和它们的金字塔函数=)谢谢。。。我可能会选择操作路线,因为它在.net核心中似乎无处不在,但可能会保留uri、用户名、密码作为参数,并为可选操作添加重载,因为这可能是一种边缘情况。这也被称为“Hadouken”样式,因为像这样链接它们与Lisp编码风格非常相似,它们的金字塔函数=)谢谢。。。我可能会选择操作路径,因为它在.net核心中似乎无处不在,但可能会保留uri、用户名和密码作为参数,并为可选操作添加重载,因为这可能是一个边缘情况。