1

わかりました、ネットワーク経由でモデルを送信するための DTO を作成するという、長く曲がりくねったプロセスの途中でしたが、正しいルートをたどっているとは思えません。

私の問題は、私のモデルのエンティティのほとんどが、とにかく DTO にすぎないということです。私は基本的に貧血ドメイン モデルを持っています。これは問題ありませんが、これらのエンティティの DTO をモデル化する必要があるかどうかも疑問に思います。

私の最初の質問は、エンティティをシリアル化し、これらをネットワーク経由で渡すだけで、どのような問題が発生する可能性があるかということです。

次に、より具体的な質問には、次のようなプロパティ シグネチャが与えられます。

public virtual Unit Unit { get; set; }

シリアル化されたユニット オブジェクトではなく、UnitId を送信することは可能ですか?

編集:申し訳ありませんが、私の質問で十分に明確ではありませんでした。皆さんが投稿したように、ユニットの Id プロパティのみを指定できることはわかっていますが、これはうまくいきません。

その理由は、このプロパティ (上記) が「Country」クラスにあり、「CountryService.GetCountry(Id)」または類似の呼び出しを行ったときにのみ UnitID を返す必要があるためです。しかし、流れるサービス呼び出し "UnitService.GetUnit(Id)" では、より多くのプロパティをシリアル化してネットワーク経由で送信する必要があります。これが理にかなっていることを願っています。

ありがとう、クリス。

4

3 に答える 3

1

次に、より具体的な質問には、次のようなプロパティ シグネチャが与えられます。

public virtual Unit Unit { get; set; }

シリアル化されたユニット オブジェクトではなく、UnitId を送信することは可能ですか?

確認してください - 確認してください

  1. Unitであなたの財産をマークしないでください[DataMember]
  2. データメンバーとしてマークする2番目のプロパティを作成UnitIdます
  3. クライアントが常にUnitクラスを再構築できることを確認してください。UnitId

アップデート:

その理由は、このプロパティ (上記) が「Country」クラスにあり、「CountryService.GetCountry(Id)」または類似の呼び出しを行ったときにのみ UnitID を返す必要があるためです。しかし、流れるサービス呼び出し「UnitService.GetUnit(Id)」では、より多くのプロパティをシリアル化してネットワーク経由で送信したいと考えています。これが理にかなっていることを願っています。

その場合、2 つの別個の DataContracts が必要です。1 つはCountryService.GetCountry(Id)だけの呼び出しUnitId用で、もう 1 つは必要UnitService.GetUnit(Id)な のすべてのプロパティを含む呼び出し用Unitです。

実行時の決定に応じて、一部のプロパティを条件付きで送信することはできません。DataContract は XML スキーマでモデル化されており、これはかなり静的です。必要なプロパティ セットが 2 つある場合は、2 つの個別の DataContracts が必要です。

于 2009-11-13T14:23:56.017 に答える
0

私が理解できることから、あなたの問題は、DTO から作成されたローカルの明示的に宣言されたオブジェクト グラフがあるという事実に起因しています。私が言いたいのは、オブジェクトグラフの単純さを単一の縮退ケースに保証するアプローチを試みるのではなくpublic Unit Unit { get; set; }Countryモデルで宣言したということです(宣言している理由はわかりませんvirtualが、それは目前の問題とは直接関係ありません)。オブジェクト グラフ ノード。

たとえば、モデルのすべての「参照」プロパティを、実際にpublic UnitID Unit { get; set; }どこにあるか、または一意に識別して区別するために使用するもので定義することを検討してください。UnitIDintGuidUnitお互いのモデル。別のモデルへの参照または一連の参照がある場合は、実際の型ではなく識別子型に置き換えます。この戦略は、永続化された一連のモデル (各モデルの ID キーを持つデータベースとの間など) に適しています。これを行うと、循環参照が不可能になったため、循環参照を心配する必要なく、シリアル化が簡単になります。技術的には、これ以上の参照はありません (つまり、直接参照。現在は間接参照です)。ここでは、ドメイン モデルの設計に間接的なレイヤーを追加しているところです。次に、その間接層に対応しましょう。

あなたは貧血ドメインモデルのアプローチに問題がないと主張したので、これはそれにうまく適合するはずです. モデル設計における間接的な (IMHO) コストを支払うことで、データ検索へのインターフェイス ベースのアプローチの主な (IMHO) 利点と交換できます。

public interface IUnitRepository {
    Unit GetUnit(UnitID id);
    IEnumerable<Unit> GetUnits(IEnumerable<UnitID> ids);
    // etc.
}

コンシューマー コード (つまり、このインターフェイスとUnitドメイン モデルを使用するコード) では、インターフェイス呼び出しを実行して暗黙のオブジェクト グラフをトラバースし、間接参照によってポイントされる基になるモデルを取得するのは、少しだけ複雑に見えます。

前:

Country ct = ...;    // I assume you have this reference already
Unit ut = ct.Unit;

後:

// Somewhere earlier in your code, i.e. not *every* time this type of code appears
IUnitsRepository repo = new SomeUnitsRepositoryImpl();
Country ct = ...;    // I assume you have this reference already
Unit ut = repo.GetUnit(ct.UnitID);

これが構文的に気になる場合Countryは、フォームに入力された一連の拡張メソッドを定義できます。

public static Unit Unit(this Country c, IUnitsRepository repo) {
    return repo.GetUnit(c.UnitID);
}

拡張方法の後:

IUnitsRepository repo = new SomeUnitsRepositoryImpl();
Country ct = ...;    // I assume you have this reference already
Unit ut = ct.Unit(repo);

インターフェイスベースのアプローチにより、関心の分離、テスト容易性、消費者と生産者の分離など、従来からある一連の利点が得られます。さらに、インターフェイスの実装タイプを介して、オブジェクトの有効期間をより直接的に制御できるようになりました。つまり、Unit GetUnit(UnitID id)メソッドの実装が単純であると想定する必要はないということです。Dictionary<UnitID, Unit>このメソッドは、 のインスタンスと関連付けられた を使用して、ローカルのメモリ内キャッシュを実行できるようになりましたSomeUnitsRepositoryImpl

少し長文ですが、お役に立てれば幸いです。提供された詳細の量からは明らかではないかのように、私は現在、記録データベースのシステムを処理するために、勤務先でこの設計をいじっています。:) ドメイン モデルの設計に 1 レベルの間接化を追加するという単純な代償を払うだけで、すべてが得られるすべての柔軟性が本当に気に入っています。

于 2009-12-20T06:35:33.817 に答える
0

NonSerializedAttribute ( msdn )を追加することで、ネットワーク経由で渡されるオブジェクトを縮小できます。Unit は取得できますが、UnitId のみです。

DTO をシリアライズするだけで問題はないと思います。DTO のすべての情報を使用していますか? ドメインの境界を越えていますか? すべてのドメインで新しいエンティティを作成し、それらのマッパーを作成します。

于 2009-11-13T14:30:44.713 に答える