2013-03-11 7 views
11

この質問は特にNinjectに関連していません。それは一般的なコーディングに関する質問ですが、私がやっていることよりも、Ninjectの問題を完全に処理するより良い方法があるかもしれないので、ここに投稿しています。Ninjectカーネルにグローバルにアクセスする

Ninject標準カーネルにGlobal.asaxのインスタンスからグローバルにアクセスできるかどうかを知りたいと思います。私はいくつかのクラスを持っている場合は

public class MvcApplication : NinjectHttpApplication 
{ 
    protected override void OnApplicationStarted() 
    { 
     base.OnApplicationStarted(); 

     // MVC global registration, routing and filtering code goes here... 
    } 

    protected override IKernel CreateKernel() 
    { 
     return Container; 
    } 

    private static IKernel Container 
    { 
     get 
     { 
      IKernel kernel = new StandardKernel(); 
      kernel.Load(new ServiceModule(), new RepositoryModule()); 
      return kernel; 
     } 
    } 
} 

、例えば、私が依存チェーンを開始したいと思いコントローラとインタフェースしていないFacadeクラスは、私の理解は、私がすべきである:ここでは

コードです使用は:

_className = kernel.Get<IClassName>(); 

ただし、これを行うには、私が知っている唯一の方法は、Ninject標準カーネルの新しいインスタンスを作成することですが、私が正しく理解していれば、の新しいインスタンスを作成するのは良いアイデアではありませんNinjectカーネルです。これは、基本的に、ネル。

アプリケーション起動時に、アプリケーションのどこからでも、Global.asaxでインスタンス化された既存のカーネルにアクセスすることは可能ですか、これを行うにはより良い方法がありますか?

よろしく、

フレッド・シャトー

答えて

0

あなたはNinjectのFactoryパターンの実装の多くを必要としているように聞こえます。カーネルをGlobal.asaxから他のアプリケーションとやり取りできるFactoryクラスに移行することができます。

また、実行時に指定されたパラメータがインタフェースバインディングを決定する状況にある場合は、サービスをラップすることができます。これはDIとServiceLocaterのハイブリッド設定ですが、ServiceLocaterはサービスレベルインスタンス化でのみ発生し、他のすべてのレイヤーは通常DI/IOCパターンでコーディングされます。

MyService : IService1 
{ 
    public void DoSomething(MyCustomParameter parameter) 
    { 
     //Builds the Kernel using the supplied parameter 
     //We've in our resolver bound IService1 To MyActualService 
     var trueService = kernel.Get<IService1>(); 
     return trueService.DoSomething(parameter); 
    } 
} 

MyActualService : IService1 
{ 
    public void DoSomething() 
    { 
     //Do the Actual work 
    } 
} 
+1

あなたは工場出荷時のために設定すると、MVC拡張機能の実装にどのような影響を与えるかを知ることが起こるでしょうか? –

+0

悲しいことに、私はそれを試さずに分からなかった部分です。私は、ユニークな懸念やアーキテクチャの選択のために、私が取り組んでいるアプリケーションのために上記のラッピング方法を使用しました。 – Kaiser12

1

私はサービスロケータを稼働させることができました。これはかなりうまく動作しているようです。リクエストがMVCコントローラアクションメソッドを介してアプリケーションに入ると、NinjectはNinject.Mvc.Extensionsによって提供される通常の方法で機能します。これは、コントローラコンストラクタを介してインスタンスクラスを注入します。要求が他の方法でアプリケーションに入ると、サービス・ロケータを呼び出して、そのクラス・コンストラクタのインスタンス・クラスを提供します。

ここでコードは次のとおりです。

まず、Microsoft.Practices.ServiceLocation

そして次Ninjectアダプタクラスへの参照。

public class NinjectServiceLocator : ServiceLocatorImplBase 
{ 
    public IKernel Kernel { get; private set; } 

    public NinjectServiceLocator(IKernel kernel) 
    { 
     Kernel = kernel; 
    } 

    protected override object DoGetInstance(Type serviceType, string key) 
    { 
     return Kernel.Get(serviceType, key); 
    } 

    protected override IEnumerable<object> DoGetAllInstances(Type serviceType) 
    { 
     return Kernel.GetAll(serviceType); 
    } 
} 

そしてGlobal.asaxの

public class MvcApplication : NinjectHttpApplication 
{ 
    private static IKernel _kernel; 


    protected override IKernel CreateKernel() 
    { 
     return Container; 
    } 

    private static IKernel Container 
    { 
     get 
     { 
      if (_kernel == null) 
      { 
       _kernel = new StandardKernel(); 
       _kernel.Load(new ServiceModule(), new RepositoryModule()); 

       ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(_kernel)); 
      } 

      return _kernel; 
     } 
    } 
} 

メモこのコードは、デフォルトのコントローラに依存リゾルバフォールバックを提供Ninject.Mvc.Extensionsの使用を必要とします。そうしないと、カスタム依存リゾルバが必要になることがあります。

これは私の懸念事項をすべて解決するようです。インスタンスクラスを作成し、オブジェクトグラフ全体を解決し、必要な場所からでも動作します。そして、私が知る限り、アプリケーションごとにNinject標準カーネルは1つしかありません。

私はService Locatorパターンを使用するのが嫌だと知っていますが、複数のNinjectカーネルを使用するとさらに悪いことに悩まされてしまうと思います。

フレッド・シャトー

20

最も簡単な方法(IMO):System.Web.MVCで使用する場合はNinjectの

_className = (IClassName)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IClassName)); 
2

新しいバージョンは、このメソッドを持っています

var obj = DependencyResolver.Current.GetService<IClassName>();

オンザフライでDIバインディングを操作する必要がない場合を除き、StandardKernelをインスタンス化するのは少し重いです。

IKernel kernel = new StandardKernel(); var obj = DependencyResolver.Current.GetService<IClassName>();

関連する問題