1

私の前の質問を参照すると、話は、私が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;
        }
    }

}

2番:

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によって生成された2つのエンティティです。この2つのように、ほとんどの基礎となるAppDataプロパティによってのみ異なる別のエンティティがあります。一部のフィールドの名前を変更する生の生成ファイルを準備するPowerShellスクリプトを作成しましたが、これだけではすべての作業を完了できません。

クラスを統一するにはどうすればよいですか?パラメータ化されたインターフェイスを使用する必要があるようです...リクエストが正しいことを確認したり、リクエストを最初から作成したりするなど、一般的な便利な機能を考案するには、統合されたクラス構造が必要です。

よろしくお願いします!私の脳はそのことについて沸騰しています。


質問編集#1

さて、皆さん、これが私が欲しいものです。サービスメソッドの要求が正しいかどうかを確認したいとします。一部のリクエストのAppDataプロパティがnullでない場合は、そのリクエストが正しいと見なす必要があります。実際には、そのようなチェックのためにいくつかの一般的なクラスのメソッドを持っている方が良いでしょう。AppDataしかし、リクエストクラスに異なるプロパティタイプがある場合、どうすればそのメソッドを作成できますか?

生成された2つのクラスを見て、各AppDataプロパティへの架空のパスを描画してみましょう。

ファーストクラスの場合、getcarsRequestがあります(括弧内には適切なクラスタイプがあります)。

request(getcarsRequest)-> MessageWrap(getcars)-> MessageData(MessageDataGetcarsRequest)-> AppData(AppDataGetcarsRequest)

2つ目は、次のパスです。

request(getdriversRequest)-> MessageWrap(getdrivers)-> MessageData(MessageDataGetdriversRequest)-> AppData(AppDataGetdriversRequest)

では、どうすればそれらを再考案して、いくつかの汎用インターフェースに減らすことができるでしょうか?その2つのクラスに適切で共通のインターフェースがあれば、いくつか書くことができますCheckRequest(IRequest<T> request)

ここである程度明確になることを願っています。アドバイス/文章は大歓迎です。ご不明な点がございましたら、お気軽にお持ちください。

4

3 に答える 3

3

私が理解しているように、効果的に複製された 2 つのクラス構造があります: car と driver です。生成されたクラスを変更する代わりに、入力 wsdl の再構築に集中する必要があります (まだ見ていません)。

この重複を取り除くには、車とドライバーの 2 つのオブジェクトを作成し、どちらのタイプのオブジェクトでも操作できるように wsdl 操作を再構築することを検討してください。オブジェクト指向の用語では、車とドライバーの両方が、wsdl 操作によって呼び出すことができる抽象メソッドを持つ同じ基本クラスから継承する必要があります。これらの抽象メソッドは、車とドライバーの派生/具象クラスに実装する必要があります。

于 2012-05-07T12:56:58.680 に答える
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;
}
于 2012-05-09T19:45:38.983 に答える
0

WSDLを編集して共通の型を提供できない場合は、次の2つの可能性があります。

  1. 既知の型でパラメーター化されたジェネリックラッパークラスを作成できます。クラスは、階層を含む具象クラス(svcutilによって生成される)の構造を模倣します。次に、生のオブジェクトを適切なラッパーでラップし、その時点からラッパーを使用します。

    利点:ラッパークラスとの相互作用は、実行時のオーバーヘッドがあまりない元の(生の)オブジェクトと似ています。

    短所:WSDLの変更に応じて、元の(生の)オブジェクトのクラスレイアウト/階層を作成して維持する必要があります。

  2. または、リフレクションを使用してオブジェクトの適切なメソッドを呼び出すことができます。具体的なタイプに基づいてメソッド名を計算する必要があります(たとえばcallFunction(o, "get", "car")、を呼び出す((GetCarsRequest)o).getCars())。

    利点:元のタイプのレイアウト/階層と一致するようにシャドウタイプの階層を作成して維持する必要はありません。

    短所:一般に、リフレクションは、コンパイルされたバイトコードを介して同じ結果を達成するよりもはるかに遅くなります。

これらのアプローチはどちらも、どのタイプのオブジェクトを扱っているかを常に確実に知る必要があります。これは、現在の設定ではすでにそうであるように、問題にはならないはずです。

于 2012-05-09T19:24:07.253 に答える