重组类结构(Reorganize classes structure)

2019-10-16 16:32发布

引用我的前一个问题 ,这个故事开始于这一事实,我有一堆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的属性类型?

让我们来看看两个生成的类并得出一些虚路径的每个应用程序数据的属性。

对于第一类,getcarsRequest我们有(括号内为我们拥有合适的类型):

请求(getcarsRequest) - > MessageWrap(getcars) - > MessageData(MessageDataGetcarsRequest) - >应用程序数据(AppDataGetcarsRequest)

对于第二个,我们有一个路径:

请求(getdriversRequest) - > MessageWrap(getdrivers) - > MessageData(MessageDataGetdriversRequest) - >应用程序数据(AppDataGetdriversRequest)

那么,如何才能redevise并减少一些通用接口? 如果我们有一个适当的,通用的接口为两个类我们可以写一些CheckRequest(IRequest<T> request)

我希望我能比较清楚这里。 任何建议/判决将非常感激。 如果你有什么问题要问请随时给他们带来给我。

Answer 1:

据我了解,你必须得到有效重复二级结构:汽车和司机。 而不是修改生成的类的,你应该专注于重组的输入WSDL(我们还没有见过的)。

为了消除这种重复,可以考虑做两个对象:汽车和司机,并以这样的方式,他们可以在任何一种类型的对象的操作重组WSDL操作。 在面向对象方面,无论是汽车和司机应该从同一个基类,将有抽象方法可以由WSDL操作被称为继承。 然后,这些抽象的方法需要在赛车和车手派生/混凝土类来实现。



Answer 2:

如果你不能编辑您的WSDL提供了常见的类型,我看到两种可能性:

  1. 你可以创建一个被参数化与已知类型的通用包装类。 这些类将模仿具体类,包括它们的层次结构(由SvcUtil工具生成)。 然后你包裹在appropritate包装的原始对象,并从该点使用的包装。

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

    缺点 :您需要创建并保持原有的(原始)对象为WSDL变化的客舱布局/层次。

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

    优点 :你不需要创建和维护一个影子式的层次结构相匹配的原始类型布局/层次。

    缺点 :一般的反射比实现通过编译字节码相同的结果要慢得多。

这两种方法都需要你肯定知道在任何时候哪些类型的对象你正在处理的,这不应该是一个问题,因为已在当前设置的情况。



Answer 3:

重构可能是最好的选择,但如果它是不可行的,你可以利用的事实,他们是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;
}


文章来源: Reorganize classes structure