2011-10-28 10 views
4

Ninject.MVC3拡張を使用してMVCアプリケーションでDIを設定するASP.NET MVC 3アプリケーションがあります。つまり、私のバインディングが定義されているフォルダにNinjectMVC3.csというファイルがあります。これは私のアプリケーションのコントローラにDIがうまくいきます。ASP.NET MVC 3アプリケーションでクラスライブラリのNinjectを参照する

私のソリューションには、ASP.NET MVC Webアプリケーションに加えて、クラスライブラリプロジェクトも含まれています。MyProject.Coreというドメインモデル、サービスなどがあります。そこでは私がサービスを利用するUserServicesと呼ばれるクラスはそうのように、EmailServices呼ばれています:

public class UserServices : IUserServices 
{   
    private readonly IEmailServices _emailServices = new EmailServices(); 

    public void CreateUser(...) 
    { 
     // Create user... 

     _emailServices.SendWelcomeEmail(newUser); 
    } 
} 

あなたが見ることができるように、UserServicesクラスはEmailServicesにハードコーディングされた依存関係を持っていますが、私はにそのための希望しますDIを使用するように構成することもできます。つまり、私のASP.NET MVCアプリケーション(または単体テストプロジェクトまたはどこでも)では、「TestEmailServicesをバインドするためにバインドIEmailServices」と言うことができるようにし、UserServicesクラスにはの代わりにEmailServicesを使用します。

これを行うにはどうすればよいですか?私のような何かを行うことができるようにしたい:

public class UserServices : IUserServices 
{   
    private readonly IEmailServices _emailServices = kernel.Get<EmailServices>(); 

    ... 
} 

しかし、私はkernel、この場合には、から来ることを行っている場所がわからないんだけど。私は何を意味しているか、私はここで間違った木を吠えていますか?

おかげ

答えて

4

あなたはこのように、コンストラクタ・インジェクションでこれを行うことができる必要があります:

private readonly IEmailServices _emailServices; 

public UserServices(IEmailServices emailServices) 
{ 
    _emailServices = emailServices; 
} 

あなたのコントローラへのサービスの注入はNinjectカスタムコントローラファクトリによって自動的に処理されなければならない、構成されたIoCコンテナを使用しwhich'll今度はコンテナによってIEmailServicesオブジェクトが与えられますコントローラが作成されIUserServicesオブジェクト、解決するために:あなたはユニットテストたら

public class MyController : Controller 
{ 
    private readonly IUserServices _userServices; 

    public MyController(IUserServices userServices) 
    { 
     _userServices = userServices; 
    } 
} 

して、手動で注入することができ偽の電子メールサービスを偽装してユーザサービスに偽装する。

+1

はい、これが答えです。 Ninjectカーネルをサービスロケータとして使用しないでください。ライブラリの実装をNinjectに結合しないでください。メインアプリケーションのオブジェクトツリー全体を構築させるだけです。 – Aaronaught

+0

ああ、私はちょうどそれを試みたはずです! <額を叩く/ /> :-)ありがとう –

0

とにかくMVC 3を使用している場合は、どのようにしてNinjectの登録についてのビルトインDependencyResolver?

System.Web.Mvc.DependencyResolver.SetResolver(yourKernel); 

その後、あなたはちょうどあなたがそれを必要とする

var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>(); 

を使用することができます。私は、SetResolverがNinjectカーネルを直接受け入れるか、ラッパークラスが必要な場合は手を知らないが、最もクリーンなソリューションだと思うだろう。

+0

これは動作しますが、それでもサービスロケータのアンチパターンに依存し、MVCでは全く必要ありません。コントローラの工場としてNinjectを登録し、他の場所では通常のコンストラクタインジェクションを使用できます。言うまでもなく、クラスライブラリを 'System.Web.Mvc'に結合します。これは正しいとは思われません。 – Aaronaught

+0

@Aaronaughtはい、いいえ。 MVC 3のDependencyResolverはすべてを処理します(コントローラファクトリが不要なため、DependencyResolverで解決できる場合はDIを自動的に使用します)。しかし、すべての依存関係を注入するオプションではない状況があるかもしれません(例:私はHtmlHelperを使用して、いくつかの書式設定を処理するサービスを使用しています。これはコントローラで実行してモデルを置くことができますが、表示機能のみのサービスでは過剰です。 –

+0

'DependencyResolver'は文字どおりサービスロケータです新しい名前で私は本当にカーネル自体でそれを使用する利点を見ることができません...それは間接参照の別の層ですか?私は、MVCの内部にあるものを超えて正当な必要性があるとは確信していませんが、そこにはあいまいな例があるかもしれないと思います。 – Aaronaught

関連する問題