C# 创建一个";“一体式”;在C中使用DS的函数#
在我的web应用程序中,我使用来自同一提供商的多个asmx(web服务),它们有一个用于此目的,另一个用于此目的,但都需要具有身份验证的SOAP头 添加身份验证很简单:C# 创建一个";“一体式”;在C中使用DS的函数#,c#,asp.net,design-patterns,C#,Asp.net,Design Patterns,在我的web应用程序中,我使用来自同一提供商的多个asmx(web服务),它们有一个用于此目的,另一个用于此目的,但都需要具有身份验证的SOAP头 添加身份验证很简单: public static SoCredentialsHeader AttachCredentialHeader() { SoCredentialsHeader ch = new SoCredentialsHeader(); ch.AuthenticationType = SoAuthenticationType
public static SoCredentialsHeader AttachCredentialHeader()
{
SoCredentialsHeader ch = new SoCredentialsHeader();
ch.AuthenticationType = SoAuthenticationType.CRM5;
ch.UserId = "myUsername";
ch.Secret = apUtilities.CalculateCredentialsSecret(
SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
return ch;
}
问题是这个SoCredentialsHeader来自一个Web服务,我需要向其他Web服务添加相同的代码,如:
public static wsContact.SoCredentialsHeader AttachContactCredentialHeader()
{
wsContact.SoCredentialsHeader ch = new wsContact.SoCredentialsHeader();
ch.AuthenticationType = wsContact.SoAuthenticationType.CRM5;
ch.UserId = "myUsername";
ch.Secret = apUtilities.CalculateCredentialsSecret(
wsContact.SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
return ch;
}
public static wsDiary.SoCredentialsHeader AttachDiaryCredentialHeader()
{
wsDiary.SoCredentialsHeader ch = new wsDiary.SoCredentialsHeader();
ch.AuthenticationType = wsDiary.SoAuthenticationType.CRM5;
ch.UserId = "myUsername";
ch.Secret = apUtilities.CalculateCredentialsSecret(
wsDiary.SoAuthenticationType.CRM5, apUtilities.GetDays(), "myUsername", "myPassword");
return ch;
}
是否有一种实现设计模式的方法,以便只使用一个功能,但适合所有Web服务
有时我会看到T这封信,是这样吗?如果是,我怎样才能实现这样的功能
另外,我可以传递一个枚举并使用一个开关来检查枚举名称并应用正确的头,但是每次我需要添加一个新的Web服务,我需要添加枚举和代码,我都在寻找一种先进的技术
谢谢。
我不知道这是不是你想考虑的东西,因为它肯定有它的下边,但最终这些(ValoiSoCuthTealSead类)都是同一个类定义在不同命名空间中的副本,所以只要稍加重构就可以有一个类和一个方法。 将SoCredentialsHeader类定义复制到您自己的项目中,添加对它的引用,并从所有web服务的代理中删除该类定义。 在代理代码文件的顶部添加一个using语句,它不会显示出区别 基本上,您告诉它对所有web服务使用相同的类定义(您的)<> P>明显的缺点是,每当你更新和Web服务引用时,你必须重复这个练习(并且它假定所有的服务都使用相同的定义),但是我们在类似的场景中这样做,并且它对我们来说非常好。 < P>我不知道这是不是你想考虑的事情,它肯定有缺点,但最终这些(varoius SoCredentialsHeader类)都是不同名称空间中同一类定义的副本,因此只需进行一点重构,就可以拥有一个类和一个方法 将SoCredentialsHeader类定义复制到您自己的项目中,添加对它的引用,并从所有web服务的代理中删除该类定义。 在代理代码文件的顶部添加一个using语句,它不会显示出区别 基本上,您告诉它对所有web服务使用相同的类定义(您的)
明显的缺点是,无论何时更新和web服务引用,您都必须重复此练习(并且假设所有服务都使用相同的定义),但我们在类似的场景中一直在这样做,并且效果非常好。我将尝试使用通用方法,然后使用反射设置属性:
public static T AttachDiaryCredentialHeader<T>() where T: class
{
T ch = new T();
Type objType = ch.GetType();
PropertyInfo userId = objType.GetProperty("UserId");
authType.SetValue(ch, "myUsername", null)
//And so on for the other properties...
return ch;
}
public static T AttachDiaryCredentialHeader(),其中T:class
{
T ch=新的T();
类型objType=ch.GetType();
PropertyInfo userId=objType.GetProperty(“userId”);
authType.SetValue(ch,“myUsername”,null)
//其他属性也是如此。。。
返回ch;
}
IMHO,这有点骇客,我会把它们分开,除非像前面的帖子提到的那样,你绝对肯定这些服务的定义会保持不变。对其中一个进行一个小更改将打破这一点。我将尝试使用通用方法,然后使用反射设置属性:
public static T AttachDiaryCredentialHeader<T>() where T: class
{
T ch = new T();
Type objType = ch.GetType();
PropertyInfo userId = objType.GetProperty("UserId");
authType.SetValue(ch, "myUsername", null)
//And so on for the other properties...
return ch;
}
public static T AttachDiaryCredentialHeader(),其中T:class
{
T ch=新的T();
类型objType=ch.GetType();
PropertyInfo userId=objType.GetProperty(“userId”);
authType.SetValue(ch,“myUsername”,null)
//其他属性也是如此。。。
返回ch;
}
IMHO,这有点骇客,我会把它们分开,除非像前面的帖子提到的那样,你绝对肯定这些服务的定义会保持不变。对其中一个进行一个小更改将打破这一点。在VS解决方案中的任何位置创建一个名为where.tt的文件(技巧是.tt扩展名),并粘贴以下代码:
using System;
namespace Whatever
{
public static class Howdy
{
<#
string[] webServices = new string[] {"wsContact", "wsDiary"};
foreach (string wsName in webServices)
{
#>
public static <#=wsName#>.SoCredentialsHeader AttachContactCredentialHeader()
{
<#=wsName#>.SoCredentialsHeader ch = new <#=wsName#>.SoCredentialsHeader();
ch.AuthenticationType = <#=wsName#>.SoAuthenticationType.CRM5;
ch.UserId = "myUsername";
ch.Secret = apUtilities.CalculateCredentialsSecret(<#=wsName#>.SoAuthenticationType.CRM5,
apUtilities.GetDays(), "myUsername", "myPassword");
return ch;
}
}
<# } #>
}
使用系统;
名称空间
{
公共静态类你好
{
public static.SoCredentialsHeader附件ContactCredentialHeader()
{
.SoCredentialsHeader ch=new.SoCredentialsHeader();
ch.AuthenticationType=.SoAuthenticationType.CRM5;
ch.UserId=“myUsername”;
ch.Secret=apUtilities.CalculaterEdentialSecret(.SoAuthenticationType.CRM5,
apUtilities.GetDays(),“我的用户名”,“我的密码”);
返回ch;
}
}
}
然后看着一个whatever.cs神奇地出现了所需的代码片段
您需要将这些转换为分部类或扩展方法或其他内容。上面的代码不会“按原样”运行,但您会明白这一点。在VS解决方案中的任何位置创建一个名为whatever.tt(技巧是.tt扩展名)的文件,并粘贴以下代码:
using System;
namespace Whatever
{
public static class Howdy
{
<#
string[] webServices = new string[] {"wsContact", "wsDiary"};
foreach (string wsName in webServices)
{
#>
public static <#=wsName#>.SoCredentialsHeader AttachContactCredentialHeader()
{
<#=wsName#>.SoCredentialsHeader ch = new <#=wsName#>.SoCredentialsHeader();
ch.AuthenticationType = <#=wsName#>.SoAuthenticationType.CRM5;
ch.UserId = "myUsername";
ch.Secret = apUtilities.CalculateCredentialsSecret(<#=wsName#>.SoAuthenticationType.CRM5,
apUtilities.GetDays(), "myUsername", "myPassword");
return ch;
}
}
<# } #>
}
使用系统;
名称空间
{
公共静态类你好
{
public static.SoCredentialsHeader附件ContactCredentialHeader()
{
.SoCredentialsHeader ch=new.SoCredentialsHeader();
ch.AuthenticationType=.SoAuthenticationType.CRM5;
ch.UserId=“myUsername”;
ch.Secret=apUtilities.CalculaterEdentialSecret(.SoAuthenticationType.CRM5,
apUtilities.GetDays(),“我的用户名”,“我的密码”);
返回ch;
}
}
}
然后看着一个whatever.cs神奇地出现了所需的代码片段
您需要将这些转换为分部类或扩展方法或其他内容。上面的代码不会“按原样”运行,但您明白了。这项工作正是我试图避免的。。。您所说的将与使用枚举相同,并且它们将应用correc