1

すべてのドメインオブジェクトにGetHashCodeを実装するように強制しています。

namespace Core
{
  [Serializable]
  public abstract class DomainObject
  {
    public abstract override int GetHashCode();
  }
}

namespace Entity.Domain
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    private System.Int32 _effDte;

    [DataMember]
    public virtual System.Int32 EffDte
    {
        get { return _effDte; }
        set { _effDte = value; }
    }

    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}

これらのドメインオブジェクトをWCFを介して公開する場合、次の生成されたサービスをコンパイルするには、更新後の変更が必要です。

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3053
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace IdCardManagerServiceReference {
using System.Runtime.Serialization;
using System;


[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="IdCard", Namespace="http://schemas.datacontract.org/2004/07/Entity.Domain")]
[System.SerializableAttribute()]
public partial class IdCard : Core.DomainObject, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { 
    [System.NonSerializedAttribute()]
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    [System.Runtime.Serialization.OptionalFieldAttribute()]
    private int EffDteField;

    [global::System.ComponentModel.BrowsableAttribute(false)]
    public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
        get {
            return this.extensionDataField;
        }
        set {
            this.extensionDataField = value;
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int EffDte {
        get {
            return this.EffDteField;
        }
        set {
            if ((this.EffDteField.Equals(value) != true)) {
                this.EffDteField = value;
                this.RaisePropertyChanged("EffDte");
            }
        }
    }
}

GetHashCodeの要件を維持する方法についてのアイデアはありますが、クライアント上のコードの要件を(更新または部分的なクラスとして)削除しますか?

4

2 に答える 2

3

WCF サービスのすべての C# コンシューマーが元のコードと同じモデルをそのまま使用することが本当に必要な場合は、[サービス参照の追加] ツールの [参照されたアセンブリでの型の再利用] 機能を使用します。モデル/コントラクト/インターフェイスを、共有の「定義」アセンブリとして機能する他の実装コードを含まない単一のアセンブリに分割してください。「サービス参照の追加」ツールがクライアント プロキシ コードを生成するときの型を再利用するアセンブリとして、このアセンブリをマークします。

また、予防的な警告として、「公式」の C# サービス クライアントをサービスに 1 つだけ実装することで、物事を簡素化してください。サービスとの接続を必要とするすべてのプロジェクトに、Visual Studio によって生成された冗長なサービス参照プロキシを追加しないでください。

編集:

モジュール化されたサービス対応 API を設計した最近の個人的な経験から言えば、WCF サービスだけでなく包括的な設計にも関連するモジュール化のトピックについて、より一般的なアドバイスを提供できます。

私たちのシステムでは、[DataContract]ドメイン オブジェクト、モデル、データ コントラクトなど、参照したいものは何でも、としてマークされたオブジェクトのみを含む単一の「定義」アセンブリを作成する際に、上記で提案したことを実行しました。

このアセンブリには、これらのドメイン オブジェクトに関してのみメソッドを定義するリポジトリ インターフェイスのコレクションもあります。これらのモデルは永続化されたデータベースであり、それぞれに ID 列があるため、各モデルごとに ID 値を保持するために使用される、このアセンブリで定義された厳密に型指定された識別子構造体もあります。このように sをラップする struct を使用することは、それ自体intを使用するよりも望ましい方法です。これはint、コンパイラ支援による意味解析が得られるためです。つまり、両方のドメインが型によって表現可能であるという事実にもかかわらず、2 つの異なるドメインを意味的に表すため、 にModel1ID変換することはできません。Model2IDint

モジュール性を促進するのは、これらのリポジトリ インターフェイスの定義です。WCF サービス実装クラスは、WCF サービス クライアント実装クラス、データベース リポジトリ実装クラス、キャッシング プロキシ実装クラス、メソッド呼び出しロギング実装クラスなどと同様に、必要なすべてのインターフェイスを単純に実装します。具体的な実装クラスはすべて、他のアセンブリ。つまり、インターフェイスとモデルを含む「定義」アセンブリにはありません。これらのクラスはインターフェイスを実装し、コンシューマー コードには同じように見えます。

重要なのは、API コンシューマ コードを特定の実装クラスにとらわれないようにし、インターフェイスのみを参照することです。モデル自体は、ビジネス ロジックの実装が見つからない単純なデータ コンテナーとして保持されます。このパターンは貧血と呼ばれていると思いますが、私にとって「貧血」には否定的な意味合いがあるため、このデザインを説明するときにその用語を使用したくありません.

得られるのは、WCF サービスと直接対話しているか、データベースと直接対話しているか、キャッシングがシームレスに実装されているか、メソッド呼び出しがログに記録されているか、または他のプロキシが使用するものを気にしないビジネス ロジックを実装するコンシューマー コードです。あなたが思いつくことができます。

要約すると、インターフェイスを使用して設計し、自分の生活を楽にします。ただし、これは、自制を実践する能力に自信がある場合にのみ行ってください。私が設計したシステムには、モデルの定義、インターフェイスの設計、データベース アクセス コードの記述だけを手動で行う必要があるという点で、WCF サービスに付随するほぼすべての定型コードを生成する T4 テンプレートがあります。 . WCF ファサードは、T4 テンプレートを右クリックして「カスタム ツールを実行」するだけで無料で利用できます。大好きです。:)

于 2010-10-08T14:45:01.323 に答える
0

部分クラスの名前空間を修正します。属性と継承を調整する必要がある場合があります。

namespace DCS2000.IDCardExclude.UI.IdCardManagerServiceReference
{
  [Serializable]
  [DataContract]
  public partial class IdCard : DomainObject
  {
    public override int GetHashCode()
    {
        return EffDte.GetHashCode();
    }
  }
}
于 2010-10-06T15:00:52.050 に答える