2016-12-15 9 views
1

私は、WCFサービスを使用するクライアントがDataContractオブジェクト上でnew()を実行するときに、抽象基本クラスのコンストラクタを初期化するための回避策を考え出しています。私は、DataContractオブジェクトが生の初期化されていないオブジェクトとして作成されているので、コンストラクタは呼び出されないことに気付いています。私は[OnSerializing][OnSerialized][OnDeserializing]、および[OnDeserialized]という属性を使いましたが、明示的にXMLを使用するように強制しない限り、WCFのシリアライゼーションエンジンでは受け入れられないことがわかりました。この特定のケースでは望ましくありません。ここでは、私が使用しようとしているものの非常に単純化されたコーディング例があります。クライアントがDataContractでnewを呼び出すときに、抽象基本コンストラクタを初期化する方法はありますか?

[DataContract(Namespace = "http://somenamespace/Data/ContractBase/v1")] 
public abstract ContractBase 
{ 
    [DataMember(IsRequired = true)] 
    public SomeDataContract BaseClassObject { get; set; } 

    public string Name { get; set; }   

    public ContractBase() 
    { 
     BaseClassObject = new SomeDataContract("randomConstructorArgument"); 
     Name = "Ezra"; 
    } 
} 

[DataContract(Namespace = "http://somenamespace/Data/TheClass/v1")] 
[KnownType(typeof(ContractBase))] 
public sealed class TheClass : ContractBase 
{ 
    [DataMember] 
    public PetDataContract MyPet { get; set; } 

    [DataMember] 
    public int SomeIntProperty { get; set; } 

    public TheClass() 
     : base() 
    { 
     MyPet = new PetDataContract ("Fido"); 
     SomeIntProperty = -1; 
    } 
} 

私はTheClassのコンストラクタが呼び出されることはありませんので、TheClass myClass = new TheClass();を実行するクライアントは基本コンストラクタを初期化しないことを知っています。私は、次のようなメソッドを追加して、何の成功もせずにシリアライゼーションが発生したときにトリガーしようとしました。

private void Initialize() 
{ 
    MyPet = new PetDataContract ("Fido"); 
    SomeIntProperty = -1; 

    base.Initialize(); 
} 

[OnSerializing] 
private void OnSerializing(StreamingContext c) 
{ 
    Initialize(); 
} 

基本クラスには、「コンストラクタ」がチェーンされるようにInitializeメソッドもあります。コンストラクター自体は、同じ共通ソースコードを使用するためのInitialize();呼び出しを含むように更新されます。

XmlSerializerでシリアル化を強制することなくこれを処理する方法はありますか?私の現在の回避策は、WCFサービスでサーバー上にオブジェクトを作成し、ポストコンストラクターのバージョンを返すメソッドを提供することです。

public TheClass CreateTheClass(TheClass contract) 
{ 
    // Calls the constructor of TheClass and its base constructor. 
    return new TheClass(); 
} 

これは期待どおりに機能しますが、ネットワークI/Oコストのために避けたいサービスコールです。どんな助けも非常に高く評価されます。

ありがとうございます!

+0

これを見てくださいhttp://stackoverflow.com/questions/6316118/constructor-in-wcf-datacontract-not-reflected-on-client –

+0

@DanHunexデータ契約を完全に移動するのは興味深い考えです彼らが知る必要があるものだけを知らない。私のDataContractクラスの奇妙な点は、バックエンドプロセスが明示的な実装を探しているため(明示されていない理由)、インターフェイスを明示的に実装する必要があることです。公開されたDataContractに公開された部分を取り出し、それらのプロパティをインターフェイスプロパティの明示的な実装に変換するために既存のクラスを変更できますか?私はそれを試してみましょう。 –

答えて

0

this articleによれば、上記の属性はDataContractSerializerでうまくいくはずです。あなたの最後の例は少し奇妙です - あなたはOnSerializing属性を使用しようとしていますが、コンストラクタはWCFによる逆シリアル化中に呼び出されないと言っています。

Initializeの方法を使用して、OnDeserializing(またはデシリアライズが完了した後でコードを呼び出す場合はOnDeserialized)という方法を使用することをお勧めします。

関連する問題