3

Message私は非常に大きなコンストラクター(13個のパラメーター)を持つ複雑なエンティティ( )を持っていますが、これらのパラメーターのいくつかはエンティティ( Verb)です。

別のエンティティのリポジトリが必要なものがいくつかあります(たとえば、いくつかのデフォルトの場合)。

IoCを使用し、コードをクリーン/ベストプラクティスに保つための良い方法は何ですか?

簡略化されたコード(デフォルトの動詞リストを静的コンストラクターによって個人的に構築された静的オブジェクトとして配置します。これは、メッセージエンティティが何らかのIRepositryを必要とする理由の最も単純な例です)。

private static IVerbRepository verbRepository;

static Message()
{
    using (IKernel kernel = new StandardKernel())
    {
        verbRepository = kernel.Get<IVerbRepository>();
    }
}

public Message(int id, string precis,
    DateTime created, DateTime validTo,
    PriorityType priority, Source source, SID createdBy,
    string content = null, string helpText = null,
    DateTime? validFrom = null, bool emailOnExpiry = false,
    IEnumerable<SID> targetUsers = null,
    IOrderedEnumerable<MessageVerb> verbs = null) : base(id)
{
    Verbs = verbs ??
            new List<MessageVerb>
            {
                new MessageVerb(
                verbRepository.GetByName("Acknowledge"), true,
                string.Empty)
            }.OrderBy(x => x.IsDefault);

    Precis = precis;
    Created = created;
    ValidTo = validTo;
    Priority = priority;
    Source = source;
    CreatedBy = createdBy;
    Content = content;
    HelpText = helpText;
    ValidFrom = validFrom;
    EmailOnExpiry = emailOnExpiry;
    TargetUsers = targetUsers;
}

一般的な方法は、コンストラクターにパラメーターを追加することのようです。これがどのように優れているのかわかりませんか?つまり、メッセージを作成するたびに、リポジトリを取得するためのコードを作成する必要があります。これをファクトリでラップアラウンドすると仮定すると、メッセージエンティティ用に異なるリポジトリを(実際にはそうでない場合でも)許可することは意味がありませんか?

編集1

最初のソリューションに基づいて、コードはこれを望みます、

public Message(IVerbRepository verbRepository ...) {  }

同じドメインアセンブリの他の場所

public MessageService
{
    private IVerbRepository VerbRepository {get; set;}
    public static IOrderedEnumerable<MessageVerb> DefaultVerb {get;}
}

私のDDDの外のはるかに高いところ(メッセージの作成を受け入れる私のWebサービスとしましょう)

public class MessageWebService
{
    private static IVerbRepository _verbRepository;

    public void AddMessage(some parameters)
    {
        var message = new Message(_verbRepository, ...);
    }
}
4

2 に答える 2

6

IoCには、使用しているService Locatorと、要求しているDependencyInjectionの2つのフレーバーがあります。

現在のところ、Service Locatorは、暗黙の依存関係(クラスのパブリックインターフェイスを見ても理解できない依存関係)を導入し、テストを困難にするため、一種のアンチパターンと見なされています。

一方、依存性注入にはこれらの問題はありませんが、クラス宣言ではより冗長になる傾向があります。

さて、あなたの質問について。

これがどのように優れているのかわかりませんか?

それは明白です。クラスがこのサービスまたはそのサービスに依存していることがわかります。ところで、あなたのクラスはそうではありません、それはデフォルトの動詞(クラスの外に簡単に移動することができます)を見つけるために動詞リポジトリを使用するだけです。

これをファクトリでラップアラウンドすると仮定すると、メッセージエンティティ用に異なるリポジトリを(実際にはそうでない場合でも)許可することは意味がありませんか?

あなたがテストについて考えるとき、それはします。CUTが依存しているサービスをテスト可能な実装(スタブ)に簡単に置き換えることができるはずです。

于 2012-08-28T11:46:08.257 に答える
2

ドメインモデルはデータソースを認識してはなりません=リポジトリを使用しないでください。おそらく、必要なビジネスルールを実装できるサービスクラスが必要です(サービスはリポジトリを使用できます)。

また、モデルが太すぎるようです。それを細かく分割して、代わりにコンポジションを使用することはできませんか?

コンストラクターは、必要な情報のみを引数として受け取る必要があります。それはまさにそれを示すために使用されます。他のすべては、プロパティセッターまたはメソッドを使用して設定できます。私はプライベートセッターとパブリックメソッドを好む傾向がありますが、crudではなくタスクベースのUIを使用する必要があります(imho CRUDはどちらの方法でもDDDには適していません)

于 2012-08-28T11:52:02.197 に答える