3

これは非常に単純で一般的なシナリオであり、今までどのように管理していたのか、なぜ今問題が発生しているのか疑問に思います。

このオブジェクトがあります (インフラストラクチャ アセンブリの一部)

public class Queue {}

public class QueueItem
{
    public QueueItem(int blogId,string name,Type command,object data)
    {
        if (name == null) throw new ArgumentNullException("name");
        if (command == null) throw new ArgumentNullException("command");
        BlogId = blogId;
        CommandType = command;
        ParamValue = data;
        CommandName = name;
        AddedOn = DateTime.UtcNow;
    }


    public Guid Id { get; internal set; }
    public int BlogId { get; private set; }
    public string CommandName { get; set; }
    public Type CommandType { get; private set; }
    public object ParamValue { get; private set; }
    public DateTime AddedOn { get; private set; }
    public DateTime? ExecutedOn { get; private set; }
    public void ExecuteIn(ILifetimeScope ioc)
    {
        throw new NotImplementedException();
    }
}

これは、このような別のアセンブリで作成されます

 var qi = new QueueItem(1,"myname",typeof(MyCommand),null);

ここで珍しいことは何もありません。ただし、このオブジェクトは永続化されるリポジトリに送信されます。Queueオブジェクトはリポジトリに項目を要求します。リポジトリは QueueItem オブジェクトを再作成する必要があります。

ただし、ご覧のとおり、QueueItem プロパティは不変です。AddedOn プロパティはアイテムの作成時に 1 回だけ設定する必要があります。IdプロパティはQueue オブジェクトによって設定されます (これは重要ではありません)。

問題は、リポジトリで QueueItem をどのように再作成する必要があるかということです。すべてのプロパティのすべての値を必要とする別のコンストラクターを使用できますが、最初にキュー アイテムを作成するアセンブリでそのコンストラクターを使用できるようにしたくありません。リポジトリは別のアセンブリの一部であるため、内部は機能しません。

ファクトリ メソッド クラス QueueItem { /* ..残りの定義.. */ を提供することを考えました。

     public static QueueItem Restore(/* list of params*/){}
   }

少なくとも意図は明確になりますが、なぜこのアプローチが気に入らないのかわかりません。Queue だけでアイテムの作成を強制することもできますが、それは Queue をリポジトリへの依存関係として渡すことを意味しますが、これも私が望むものではありません。このための特定のファクトリ オブジェクトを用意することも、やり過ぎのように思えます。

基本的に私の質問は、その特定の作成機能を別の消費者オブジェクトに公開せずに、リポジトリでオブジェクトを再作成する最適な方法は何ですか?

アップデート

リポジトリとは、ORM のラッパーではなく、抽象化としてのパターン自体を意味することに注意してください。ドメイン オブジェクトが永続化される方法や場所は問題ではありません。リポジトリによってどのように再作成できるかが重要です。もう 1 つの重要な点は、私のドメイン モデルは 持続性モデルとは異なるということです。私はRDBMSを使用していますが、特定のストレージアクセスに依存しない方法を探しているので、これは重要ではない実装の詳細に過ぎないと思います.

これは特定のシナリオですが、基本的にリポジトリによって復元されるすべてのオブジェクトに適用できます。

Update2

わかりました、AutoMapper を忘れる方法がわかりません。プライベートフィールド/セッターをマップできないという間違った印象を受けましたが、マップできるので、これが最善の解決策だと思います。

実際、最適解 (IMO) は次のようになっていると言えます。

  1. 可能であれば、直接逆シリアル化します。
  2. 自動マップ。
  3. ドメイン オブジェクト自体のファクトリ メソッド。

最初の 2 つは、オブジェクトが特に何かを行う必要はありませんが、3 番目の場合は、オブジェクトがその場合の機能 (有効な状態データを入力する方法) を提供する必要があります。明確な意図がありますが、ほとんどマッパーの仕事をしています。

回答 が更新されました

私自身に答えると、この場合、最適な方法はファクトリ メソッドを使用することです。最初は Automapper を選択しましたが、ファクトリー メソッドを使用することが多くなりました。Automapper は便利な場合もありますが、多くの場合、十分ではありません。

4

2 に答える 2

0

ORMフレームワークがそれを処理します。オブジェクトを再水和するように指示するだけで、ドメインクラスの通常のインスタンスが提供されます(たとえば、NHibernateでは、プロパティを仮想または保護として宣言するだけでよい場合があります)。その理由は、内部では通常、基本クラスから派生したプロキシオブジェクトを操作し、これらの基本クラスをそのまま維持できるためです。

ただし、独自の永続層を実装したい場合、それはまったく別の話です。オブジェクトで最初に定義されたスコープの制約を壊さずにデータベースからオブジェクトを再水和すると、リフレクションが発生する可能性があります。また、多くの副次的な懸念についても考慮する必要があります。オブジェクトに別のオブジェクトへの参照がある場合は、前にそのオブジェクトを再水和する必要があります。

そのチュートリアルを見ることができます:ほとんどの場合、車輪の再発明はお勧めしませんが、独自のdataAccessレイヤーを構築します。

于 2012-04-06T13:22:13.127 に答える
0

オブジェクト自体のファクトリ メソッドについて話しました。しかし、DDD では、エンティティはファクトリによって作成されるべきであると述べています。したがって、新しい QueueItem を作成し、既存の QueueItem を復元できる QueueItemFactory が必要です。

わかりました、AutoMapper を忘れる方法がわかりません。

AutoMapper のことは忘れたいです。恐ろしい API を見ているだけで背筋がゾクゾクします。

于 2012-07-23T15:08:38.613 に答える