因此,我有一个库的一部分,它处理Google+集成中的作用域,我对它的总体视图很好奇。
是的,在其中一个方法中输入了很多东西,这是因为这必须是COMpatible,它不支持枚举。
我(有意)省略了XML文档,因为大多数人认为我做得太过火了,我不想臃肿。
public bool COM_GetLoginStatus(ref GoogleIdentity identity, WebBrowserSettings settings, bool force, string scopes = "")
{
GooglePermissionScopes googlePermissionScopes = GooglePermissionScopes.None;
scopes = scopes.ToLower();
if (scopes == "")
{
scopes = "all";
}
foreach (string scope in scopes.Split(','))
{
switch (scope)
{
case "openid":
googlePermissionScopes |= GooglePermissionScopes.OpenID;
break;
case "email":
googlePermissionScopes |= GooglePermissionScopes.Email;
break;
case "plus.login":
case "pluslogin":
googlePermissionScopes |= GooglePermissionScopes.PlusLogin;
break;
case "all":
googlePermissionScopes |= GooglePermissionScopes.All;
break;
}
}
return GetLoginStatus(ref identity, settings, force, googlePermissionScopes) == LoginStatus.Success;
}下一个方法负责构建一个端点来联系API。
public string GetLoginUrl(GooglePermissionScopes googlePermissionScopes = GooglePermissionScopes.None, bool force = false, string state = "")
{
string endpoint = "https://accounts.google.com/o/oauth2/auth?";
if (googlePermissionScopes != GooglePermissionScopes.None)
{
endpoint += "scope=";
if ((googlePermissionScopes & GooglePermissionScopes.OpenID) == GooglePermissionScopes.OpenID)
{
endpoint += "openid";
}
if ((googlePermissionScopes & GooglePermissionScopes.Email) == GooglePermissionScopes.Email)
{
if (endpoint.Length > 6)
{
endpoint += "%20";
}
endpoint += "email";
}
if ((googlePermissionScopes & GooglePermissionScopes.PlusLogin) == GooglePermissionScopes.PlusLogin)
{
if (endpoint.Length > 6)
{
endpoint += "%20";
}
endpoint += "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login";
}
}
if (state != "")
{
endpoint = endpoint + "&state=" + state;
}
endpoint = endpoint + "&redirect_uri=" + CallbackUrl + "&response_type=code" + "&client_id=" + ClientId + "&access_type=offline";
if (force)
{
endpoint += "&approval_prompt=force";
}
return endpoint;
}我不确定是否应该在这里使用StringBuilder,因为它不是一个环字符串连接。
发布于 2015-10-09 06:27:49
COM_GetLoginStatus()这种方法对国际海事组织的影响很大,命名也不太好。它不返回LoginStatus,但它检查对GetLoginStatus()的调用是否返回LoginStatus.Success。因此,也许将此方法命名为COM_CheckLoginSuccess()更好。
海事组织,您应该将string scopes参数的解析提取为GooglePermissionScopes的一个单独的方法。
如果可选参数scopes意味着它总是应该表示all枚举值,并且不会传递""或string.Empty,那么最好将默认值设置为all。
通过这样做,以前的COM_GetLoginStatus()看起来应该是这样
public bool COM_CheckLoginSuccess(ref GoogleIdentity identity, WebBrowserSettings settings, bool force, string scopes = "all")
{
GooglePermissionScopes googlePermissionScopes = ParsePermissionScope(scopes);
return GetLoginStatus(ref identity, settings, force, googlePermissionScopes) == LoginStatus.Success;
} 要引入的方法ParsePermissionScope()随后应该利用Enum.TryParse()方法,如下所示
private GooglePermissionScopes ParsePermissionScope(string scopes)
{
GooglePermissionScopes googlePermissionScopes;
if (!Enum.TryParse(scopes, true, out googlePermissionScopes))
{
googlePermissionScopes = GooglePermissionScopes.None;
}
return googlePermissionScopes;
}GetLoginUrl()我第二次使用@janos的观点认为string endpoint = "https://accounts.google.com/o/oauth2/auth?";是一个常量,或者使类变得更可配置。如果这个url有一段时间会改变,那么使用一个属性是个好主意。
如果GooglePermissionScopes枚举具有[Flags]属性,则更明显的方法是使用HasFlags()方法来确定枚举中是否包含特定的枚举值。
这些检查if (endpoint.Length > 6)是没有意义的,可以删除,因为endpoint被初始化为Length > 6的字符串。
因为我们每天都在变老,而且我们的眼睛也没有变好,所以我不想和""比,而是和string.Empty比较。
关于StringBuilder或+,您可以说它不是循环,但在最坏的情况下,它的行为就像是从0到8的循环,因为在最坏的情况下,您要执行endpoint += someString 9次。
就我个人而言,我将使用StringBuilder,它将导致(假设Flags属性)到
public string LoginUrl { get; private set; } = "https://accounts.google.com/o/oauth2/auth?";
public string GetLoginUrl(GooglePermissionScopes googlePermissionScopes = GooglePermissionScopes.None, bool force = false, string state = "")
{
StringBuilder urlBuilder = new StringBuilder(LoginUrl, 1024);
if (googlePermissionScopes != GooglePermissionScopes.None)
{
urlBuilder.Append("scope=");
if ((googlePermissionScopes.HasFlag(GooglePermissionScopes.OpenID)))
{
urlBuilder.Append("openid");
}
if ((googlePermissionScopes.HasFlag(GooglePermissionScopes.Email)))
{
urlBuilder.Append("%20email");
}
if ((googlePermissionScopes.HasFlag(GooglePermissionScopes.PlusLogin)))
{
urlBuilder.Append("%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login");
}
}
if (state != string.Empty)
{
urlBuilder.Append("&state=")
.Append(state);
}
urlBuilder.Append("&redirect_uri=")
.Append(CallbackUrl)
.Append("&response_type=code&client_id=")
.Append(ClientId)
.Append("&access_type=offline");
if (force)
{
urlBuilder.Append("&approval_prompt=force");
}
return urlBuilder.ToString(); ;
}发布于 2015-10-09 08:31:08
除了其他人所说的,并注意到原始方法中的三个不同的代码块,我建议将GetLoginUrl拆分成不同的方法,并在可能的情况下使用string.Format (为了可读性,从性能的角度来看,它变化很小,当然,除非这个方法被称为很多次)。因此,原始方法如下所示(这是未经测试的):
public string GetLoginUrl(GooglePermissionScopes googlePermissionScopes = GooglePermissionScopes.None, bool force = false, string state = "")
{
// this should be defined somewhere else IMO
return string.Format("https://accounts.google.com/o/oauth2/auth?{0}{1}{2}",
GetPermissionScopesURIAddition(googlePermissionScopes),
GetStateURIAddition(state),
GetForceURIAddition(force))
}
private string GetPermissionScopesURIAddition(GooglePermissionScopes googlePermissionScopes)
{
string result = string.Empty;
if (googlePermissionScopes != GooglePermissionScopes.None)
{
result += "scope=";
if ((googlePermissionScopes & GooglePermissionScopes.OpenID) == GooglePermissionScopes.OpenID)
{
result += "openid";
}
if ((googlePermissionScopes & GooglePermissionScopes.Email) == GooglePermissionScopes.Email)
{
result += "%20";
result += "email";
}
if ((googlePermissionScopes & GooglePermissionScopes.PlusLogin) == GooglePermissionScopes.PlusLogin)
{
result += "%20";
result += "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login";
}
}
return result;
}
private string GetStateURIAddition(string state)
{
string result = string.Empty;
if (state != "")
{
result += "&state=" + state;
}
// format this using string.Format
return result + "&redirect_uri=" + CallbackUrl + "&response_type=code" + "&client_id=" + ClientId + "&access_type=offline";
}
private string GetForceURIAddition(bool force)
{
if (force)
{
return "&approval_prompt=force";
}
return string.Empty;
}顺便提一句:无论如何,我都会使用StringBuilder,即使性能在较小的数字上没有多大改善,但这可以看作是个人偏好。
https://codereview.stackexchange.com/questions/106987
复制相似问题