7

NinjectMvcSiteMapProviderを使用しているMVC3アプリケーションがあります。

MvcSiteMapProviderがサイトマップにノードを動的に追加するために使用するこのクラスを作成しました。

public class PageNodeProvider : DynamicNodeProviderBase
{
    public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
    {            
         // need to get repository instance
         var repository = // how do I get this???

         foreach (var item in repository.GetItems())
         {
              yield return MakeDynamicNode(item);
         }
    }
}

MvcSiteMapProviderはこのタイプ自体をインスタンス化するため、リポジトリをインジェクトする方法がわかりません。

カーネルのハンドルを取得し、メソッドを呼び出すことで、サービスの場所を使用することを考えGet<Repository>()ました。しかし、NinjectHttpApplicationの定義を見ると、このプロパティがわかりました。

    // Summary:
    //     Gets the kernel.
    [Obsolete("Do not use Ninject as Service Locator")]
    public IKernel Kernel { get; }

Do not use Ninject as Service Locator?!他にどのようにこれを行うことになっていますか?次に、stackoverflowでこの質問を見つけました。すべての回答で、ServiceLocationを使用しないでください。

私はどうしたらいいですか?

4

2 に答える 2

4

これは、本「Why providers are bad design?」の別の章のようです。あらゆる種類の ASP.NET プロバイダーと同じ問題があります。彼らにとって本当に良い満足のいく解決策はありません。ハックするだけです。

あなたが持っている最良のオプションは、プロジェクトをフォークし、DefaultSiteMapProvider を変更して Activator の代わりに DepencencyResolver を使用し、実装をコミュニティに提供することだと思います。次に、PageNodeProvider 実装でコンストラクター注入を使用できます。これにより、すべてのタイプとすべての人に対して問題が一度解決されます。

もちろん、実装だけで DependencyResolver を使用することもできます。しかし、これは最善の解決策ではありません。インスタンスをできるだけルートに近づける必要があり、テストがより複雑になり、問題を解決してくれるからです。

于 2011-10-29T01:22:29.820 に答える
1

プロバイダーを完全に捨てることにしたように見えますが、DependencyResolver の使用について詳しく説明したいと思います。基本的に、Ninject を使用して正しいリポジトリ インスタンスを手動で取得できます。

var repository = DependencyResolver.Current.GetService<IRepository>();

NinjectMVC3.cs クラスと同様にこれを維持する必要があるため、堅牢性が低くなります。また、テストが少し複雑になります。

于 2012-04-18T15:10:18.437 に答える