1

私はMVC3を使用しており、IoCを実装して、コンストラクター引数を介してコントローラーにサービス/マネージャーオブジェクトを提供しています。これらは順番に、モデルに渡される可能性があります。

私が抱えている問題は、これらのオブジェクトをあちこちに渡すのが面倒になる可能性があることです。

例:

public CartController(
        ICartManager cartManager,
        IProductManager productManager,
        IUpsellManager upsellManager,
        IAccountManager accountManager,
        ... more ...)
    {
        ... store to class variables ...
    }

    public ActionResult Index()
    {
        ...

        CartModel model = new CartModel(
            cartManager, 
            accountManager, 
            upsellManager, 
            productManager, 
            ... );

        return View(model);
    }

また、カートモデルには、パラメーターを渡す必要のあるサブモデルが含まれている場合があります。ご覧のとおり、すべてが非常に面倒になります。コンストラクター引数が非常に多い場合は準備ができています。コントローラーの処理が多すぎる可能性がありますが、これは複雑なページであり、サイトには他の多くの複雑なページが含まれます。そんなに多くのものを渡す必要はありませんが、どうすればそれらを渡してコントロールを維持できないのですか?

モデルでDependencyResolverを使用したいのですが、それでは目的が果たせず、ServiceLocatorはアンチパターンとして知られています。

IoCの利点を放棄せずに、どうすればこれほど多くの議論を渡さないようにできますか?

4

3 に答える 3

3

依存関係の逆転を使用する利点は、アプリケーション内のさまざまなロール間で責任を明確に分離できることです。コントローラは、HTTP リクエストと HTTP レスポンスを処理することにのみ関心があります。他のすべてのロジックは別の場所で処理され、コントローラーはこの作業を行うために依存している型に委譲します。このパターンは、システム内の機能ごとに繰り返されます。このパターンに従っていないことを検出する 1 つの方法は、new演算子を使用して型を作成し、依存関係をコンストラクターに渡すことです。これは、使用している IoC コンテナーのジョブです。

ロジックを入れ替えて、CartManager がビューの CartModel を返すようにすることをお勧めします。これは、ビューに固有のある種の DTO である可能性があります。データがこのオブジェクトにどのように配置されるかは、CartManager の責任です。他のサービスを使用する必要がある場合は、そのコンストラクターに注入できます。

public CartController : Controller

private ICartManager _cartManager;

public CartController(ICartManager cartManager) {
     _cartManager = cartManager;
}


[HttpGet]
public ActionResult Index(int userId) {
    var model = _cartManager.CreateCart(int userId);
    return View(model);
}

...

public class CartManager : ICartManager {

   IDbService _dbService;

   public CartManager(IDbService dbService){

       _dbService = dbSerivce;
   }

   CartModel CreateCart(int userId) {

      var user = _dbService.FindTheUser(int user);
      var cartModel = new CartModel { userId = userId, Name = user.Name };
      /* other stuff to map up a cartmodel 

      return cartModel;
   }
}

この考え方は、IoC コンテナーの使用に固有のものであるだけでなく、MVC アプリケーションを作成するための優れた方法でもあります。また、Rob Ashton によるこの投稿も良いガイドであることがわかりました。

于 2012-09-28T16:01:06.707 に答える
1

これらすべてのサービスを自分の見解に渡すべきではありません。つまり、テンプレートはこのデータを呼び出すためのアクションを実行する必要があり、これは(これまで見てきたように)複雑になります。不必要な複雑さに加えて、ビュー内にこれらのサービスの依存関係を作成し、ビューをこれらのサービスに緊密に結合します。サービスを変更する場合は、それを使用するすべてのビューを変更する必要があります。

最初に行う必要があるのは、ビューに必要なすべてのデータを含むViewModelを作成することです。次に、マネージャークラスから返されたデータをこのビューにマップする方法を見つける必要があります。コントローラで手動で実行することも、AutoMapperなどを使用して変換を実行することもできます。

もう1つのオプションは、ICartManagerをリファクタリングしてすべてのデータを返すようにするか(CartManagerクラスに他のサービスのコンストラクターインジェクションがあります)、それらを集約してビューモデルにマップできるオブジェクトを構築する別のサービスを作成することです。

これらのメソッドを渡す必要はありません。それらは常にオブジェクトに注入する必要があります。

于 2012-09-28T16:47:56.927 に答える
1

このシナリオではファクトリパターンを使用するのが好きです。このシナリオでは、クラスA(CartController)内でクラスB(CartModel)をインスタンス化する必要があり、BにはAが必要としない依存関係がたくさんあります。

public CartController(
    ICartModelFactory factory
    ... more ...)
{
    ... store to class variables ...
}

public ActionResult Index()
{
    ...

    CartModel model = factory.GetInstance(
        ... );

    return View(model);
}
于 2012-09-28T16:09:19.073 に答える