引用我的previous question,故事开始于我有一堆svcutil生成的类。它们是从外部WSDL生成的。你走了:
第一个请求类:
public partial class getcarsRequest
{
[System.ServiceModel.MessageHeaderAttribute(Namespace = "http://svc.datadomains.com/revision123_2/")]
public CarsServiceApp.RequestHeader Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name = "getcarsRequest", Namespace = "carinfo", Order = 0)]
public CarsServiceApp.getcars MessageWrap;
public getcarsRequest()
{
}
public getcarsRequest(CarsServiceApp.RequestHeader Header, CarsServiceApp.getcars getcarsRequest1)
{
this.Header = Header;
this.MessageWrap = getcarsRequest1;
}
}
public partial class getcars
{
private MessageType messageField;
private MessageDataGetcarsRequest messageDataField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public MessageType Message
{
get
{
return this.messageField;
}
set
{
this.messageField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public MessageDataGetcarsRequest MessageData
{
get
{
return this.messageDataField;
}
set
{
this.messageDataField = value;
}
}
}
public partial class MessageDataGetcarsRequest
{
private AppDataGetcarsRequest appDataField;
private AppDocumentType appDocumentField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public AppDataGetcarsRequest AppData
{
get
{
return this.appDataField;
}
set
{
this.appDataField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public AppDocumentType AppDocument
{
get
{
return this.appDocumentField;
}
set
{
this.appDocumentField = value;
}
}
}
public partial class AppDataGetcarsRequest
{
private string addressField;
private int codeField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public address address
{
get
{
return this.addressField;
}
set
{
this.addressField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public int code
{
get
{
return this.codeField;
}
set
{
this.codeField = value;
}
}
}
第二
public partial class getdriversRequest
{
[System.ServiceModel.MessageHeaderAttribute(Namespace = "http://svc.datadomains.com/revision123_2/")]
public carsServiceApp.RequestHeader Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name = "getdriversRequest", Namespace = "driverinfo", Order = 0)]
public carsServiceApp.getdrivers MessageWrap;
public getdriversRequest()
{
}
public getdriversRequest(carsServiceApp.RequestHeader Header, carsServiceApp.getdrivers getdriversRequest1)
{
this.Header = Header;
this.MessageWrap = getdriversRequest1;
}
}
public partial class getdrivers
{
private MessageType messageField;
private MessageDataGetdriversRequest messageDataField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public MessageType Message
{
get
{
return this.messageField;
}
set
{
this.messageField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public MessageDataGetdriversRequest MessageData
{
get
{
return this.messageDataField;
}
set
{
this.messageDataField = value;
}
}
}
public partial class MessageDataGetdriversRequest
{
private AppDataGetdriversRequest appDataField;
private AppDocumentType appDocumentField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public AppDataGetdriversRequest AppData
{
get
{
return this.appDataField;
}
set
{
this.appDataField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public AppDocumentType AppDocument
{
get
{
return this.appDocumentField;
}
set
{
this.appDocumentField = value;
}
}
}
public partial class AppDataGetdriversRequest
{
private string nameField;
private int customerCodeField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public name name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public int customerCode
{
get
{
return this.customerCodeField;
}
set
{
this.customerCodeField = value;
}
}
}
这只是svcutil生成的两个实体。还有另外一个像这两个实体的实体只有大多数基础AppData
属性不同。我写了一个电源shell脚本,准备原始生成的文件重命名一些字段,但这还不足以完成所有工作。
我如何组成班级统一?好像我应该使用参数化界面...... 我需要统一的类结构来设计常见的有用功能,比如检查请求是否正确或从头开始创建请求。
先谢谢你,伙计们!我的大脑都是关于那些东西的。
问题编辑#1
好的,伙计们,这是我想要的。假设我们要检查任何服务方法的正确性请求。如果某个请求的AppData
属性不为null,我们应该认为该请求是正确的。实际上,我们最好有一些通用的类方法来进行这种检查。但是,如果任何请求类具有不同的AppData
属性类型,我们如何才能创建该方法?
让我们看看两个生成的类,并为每个AppData属性绘制一些虚构的路径。
对于头等舱,我们有getcarsRequest(在括号中我们有适当的类类型):
request(getcarsRequest) - &gt; MessageWrap(getcars) - &gt; MessageData (MessageDataGetcarsRequest) - &gt; AppData(AppDataGetcarsRequest)
对于第二个,我们有下一个路径:
request(getdriversRequest) - &gt; MessageWrap(getdrivers) - &gt; MessageData (MessageDataGetdriversRequest) - &gt; AppData(AppDataGetdriversRequest)
那么我们如何将它们重新设置并减少到某些通用接口呢?如果我们有两个类的适当的通用接口,我们可以编写一些CheckRequest(IRequest<T> request)
。
我希望我在这里明白一点。任何建议/句子将非常感激。如果您对我有任何疑问,请随时将它们带给我。
答案 0 :(得分:3)
据我所知,你有两个有效复制的类结构:汽车和司机。您应该专注于重构输入wsdl(我们还没有看到),而不是修改生成的类。
为了消除这种重复,考虑制作两个对象:car和driver,并以这样的方式重构wsdl操作,使它们可以对任何类型的Object进行操作。在面向对象的术语中,汽车和驱动程序都应该从具有可由wsdl操作调用的抽象方法的相同基类继承。然后,这些抽象方法需要在汽车和驱动程序派生/具体类中实现。
答案 1 :(得分:0)
如果您无法编辑WSDL以提供通用类型,我会看到两种可能性:
您可以创建使用已知类型进行参数化的通用包装类。这些类将模仿具体类的结构(由svcutil生成),包括它们的层次结构。然后将原始对象包装在appropritate包装器中,并使用该点上的包装器。
Advantage :与包装类的交互与原始(原始)对象类似,没有太多的运行时开销。
缺点:您需要在WSDL更改时创建和维护原始(原始)对象的类布局/层次结构。
或者,您可以使用反射来调用对象上的相应方法 - 您需要根据具体类型计算方法名称(例如callFunction(o, "get", "car")
来调用((GetCarsRequest)o).getCars()
)
Advantage :您无需创建和维护阴影类型层次结构以匹配原始类型布局/层次结构。
缺点:反射通常比通过编译的字节码获得相同的结果要慢得多。
这两种方法都要求您始终确切知道您正在处理哪种类型的对象,这不应该是您当前设置中已有的问题。
答案 2 :(得分:0)
重构可能是最佳选择,但如果不可行,您可以利用它们partial
并添加界面的事实。
public IData<TRequest> {
T AppData { get; set; }
bool IsValid { get; }
}
public partial class MessageDataGetdriversRequest : IData<AppDataGetcarsRequest>
{
bool IsValid { get { this.AppData != null; } }
}
public partial class MessageDataGetdriversRequest: IData<AppDataGetdriversRequest>
{
bool IsValid { get { this.AppData != null; } }
}
然后,您可以var data = getcars.MessageData;
或var data = getdrivers.MessageData;
,然后查看data.IsValid
。
也可以在IsValid
上实现this IData<T>
作为扩展方法,而不是IData
的属性,在这种情况下,您甚至不需要为每个类声明它(但这将是一种方法,而不是财产。)
public partial class MessageDataGetdriversRequest : IData<AppDataGetcarsRequest> { }
public partial class MessageDataGetdriversRequest: IData<AppDataGetdriversRequest> { }
public static bool IsValid(this IData<T> data)
{
return data.AppData != null;
}