6

まず、Ninject1.5を使用しています。Webプロジェクトとクラスライブラリの2つのプロジェクトがあります。私のDI構成はWebプロジェクト内にあります。私のクラスライブラリ内で、次のように定義されています。

    public interface ICacheService<T>
    {
            string Identifier { get; }
            T Get();
            void Set( T objectToCache, TimeSpan timeSpan );
            bool Exists();
    }

そして、CategoryCacheServiceと呼ばれる具象クラス。

私のWebプロジェクトでは、次の2つをバインドします。

Bind( typeof( ICacheService<List<Category>> ) ).To( typeof(CategoryCacheService)).Using<SingletonBehavior>();

私のクラスライブラリには、HtmlHelperクラスの拡張メソッドがあります。次に例を示します。

public static class Category
 {
  [Inject]
  public static ICacheService<List<Category>> Categories { get; set; }

  public static string RenderCategories(this HtmlHelper htmlHelper)
  {
   var c = Categories.Get();

   return string.Join(", ", c.Select(s => s.Name).ToArray());
  }
 }

静的プロパティに挿入できないと言われましたが、代わりにKernel.Get <>()を使用する必要があります-しかし...上記のコードはクラスライブラリにあるため、カーネルにアクセスできません。この時点からカーネルを取得するにはどうすればよいですか、またはこれを行うためのより良い方法はありますか?

4

2 に答える 2

8

質問するのは良い質問です。

DIを使用するという考えの半分は、インジェクション中のコードからインスタンス化動作の懸念/微調整を取り除くことです。したがって、Categoryクラスを変更してstatic、依存関係をctorで宣言し、クライアントコードでつなぎ合わせる方が理にかなっている場合があります。

本当に良いアイデアだと確信している場合のアクセス方法について...一般的に、あなたの場合のアイデアは、を作成しCacheServiceResolverて[Webプロジェクトに]登録することです。Kernel次に、構築中のインスタンスを渡します。そうすれば、DLLはのインターフェイスにのみバインドされますCacheServiceResolver

よく使用されるもう1つのアプローチは、「GlobalGet」を公開する最後の手段である「ServiceLocator」機能をグローバルな場所に配置することです。しかし、それは一般的に悪い考えであり、一時的なダクトテーピングの目的でのみ使用する必要があります。

もう1つ注目すべき点は、Common Service Locatorです。これにより、ライブラリをコンテナに依存しないようにすることができます。ただし、EL以外では、実際にコンテナを表示するべきではないため、多くの使用法は見つかりません。

もう1つのオプションは、Func<T>ファクトリメソッドとBindそれを解決するラムダに要求し、コードからそのルックアップを抽出することです。

編集:Ninject 2では、Kernel私が言ったようにインスタンスを明示的に渡す必要はありません-IKernel解決要求が明示的に1つを渡すかどうかに関係なく、コンストラクターで単に要求することができ、それを取得します。

編集2:私の答えに本当に不満を持って、それをあまり肉屋にすることなくそれをより一般的にしようとしました。要約すると、望ましいオプションは一般的に次の順序になっています。

  1. コンテナアーティファクトはありません。ステッチはクライアントに任せてください
  2. 中立化された抽象的なコンテナ用語の代わりに、ライブラリのドメインのユビキタス言語の用語を使用して、ライブラリのコンテキストで何かを具体的に達成するように調整された、コンテナ中立の拡張ポイントを提供します
  3. CommonServiceLocatorでコンテナに依存しない統合アプローチを提供する
  4. そうして初めて、必要な人がいることを検討してください
    • あなたのコンテナを知っている
    • コンテナを理解する
于 2009-10-31T07:38:07.360 に答える
4

Webプロジェクトで、パッケージマネージャーコンソールから次のコマンドを実行します。

Install-Package Ninject.MVC3

App_StartフォルダーにNinjectWebCommonモジュールが含まれるはずです。

下部に向かって、以下のように依存関係を追加できます。

private static void RegisterServices(IKernel kernel)
{   
 kernel.Bind<IPeopleRepository>().To<PeopleRepository>();
}

クラスライブラリプロジェクトから、次のコマンドを実行します。

Install-Package Ninject

これは、クラスライブラリからリポジトリを使用してサービスを注入する方法です。

public class PeopleService : IPeopleService
{
 private readonly IPeopleRepository _peopleRepository;

 [Inject]
 public PeopleService(IPeopleRepository peopleRepository)
 {
    this._peopleRepository = peopleRepository;
 }
}
于 2013-04-24T12:03:15.407 に答える