重组类结构

时间:2012-05-02 09:21:33

标签: c# .net oop inheritance interface

引用我的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)

我希望我在这里明白一点。任何建议/句子将非常感激。如果您对我有任何疑问,请随时将它们带给我。

3 个答案:

答案 0 :(得分:3)

据我所知,你有两个有效复制的类结构:汽车和司机。您应该专注于重构输入wsdl(我们还没有看到),而不是修改生成的类。

为了消除这种重复,考虑制作两个对象:car和driver,并以这样的方式重构wsdl操作,使它们可以对任何类型的Object进行操作。在面向对象的术语中,汽车和驱动程序都应该从具有可由wsdl操作调用的抽象方法的相同基类继承。然后,这些抽象方法需要在汽车和驱动程序派生/具体类中实现。

答案 1 :(得分:0)

如果您无法编辑WSDL以提供通用类型,我会看到两种可能性:

  1. 您可以创建使用已知类型进行参数化的通用包装类。这些类将模仿具体类的结构(由svcutil生成),包括它们的层次结构。然后将原始对象包装在appropritate包装器中,并使用该点上的包装器。

    Advantage :与包装类的交互与原始(原始)对象类似,没有太多的运行时开销。

    缺点:您需要在WSDL更改时创建和维护原始(原始)对象的类布局/层次结构。

  2. 或者,您可以使用反射来调用对象上的相应方法 - 您需要根据具体类型计算方法名称(例如callFunction(o, "get", "car")来调用((GetCarsRequest)o).getCars()

    Advantage :您无需创建和维护阴影类型层次结构以匹配原始类型布局/层次结构。

    缺点:反射通常比通过编译的字节码获得相同的结果要慢得多。

  3. 这两种方法都要求您始终确切知道您正在处理哪种类型的对象,这不应该是您当前设置中已有的问题。

答案 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;
}