2013-09-25 15 views
10

Ninjectを使用してフィルタにコンストラクタの依存関係を挿入する方法を見つけようとしています。私は現在対処されているプロパティの注入について説明する多くの記事を探していますが、記事の残りの部分には、工場、ロケータ、グローバルラッパーまたはスタブ属性との複雑な設定が含まれています。Ninjectを使用したコンストラクタインジェクション

MVCを使用すると、操作のほとんどの部分をオーバーライドすることができますが、独自の依存関係リゾルバを作成する方法と同様の方法で独自のフィルタプロバイダを作成することになります。

注入を許可する正しい方法は何ですか?または特定の種類のフィルタを使用すると他の種類のフィルタを使用すると簡単になりますか?属性は、時間をコンパイルでインスタンス化されるべきであることを意味するメタデータの一部であることがあると仮定すると

public class UserValidationAttribute : ActionFilterAttribute 
{ 
    private IRepository repository; 

    public UserValidationAttribute(IRepository repository) 
    { 
     this.repository = repository; 
    } 
} 
+1

ちょっとメモ - 一般的なコンセンサスは、オプションの依存関係のためにプロパティー注入を使用する必要があるようですが、必要な依存関係のコンストラクター注入(これは意味があります - 必要な依存性なしでタイプを構築することはできませんが、 – Charleh

+0

トークン属性が存在するかどうかを調べることによって適用されるかどうかを確認するグローバルフィルタを持つメソッドを実装しました。私が現時点で取得できないのは、アクションにトークン属性を使用し、 'filterContext.ActionDescriptor.IsDefined(typeof(MyTokenAttribute)、true)を使用すると、'私は 'true'を取得しますが、私は 'false'を取得するコントローラの属性。 –

答えて

2

は、任意のIOCコンテナによって属性に注入リポジトリを持つことは不可能です。コンテナは実行時に動作します。

0

ファイラーに依存関係を注入する場合は、コンストラクター注入の代わりにプロパティー注入を使用する必要があります。

public class UserValidationAttribute : ActionFilterAttribute 
{ 
    [Inject] 
    private IRepository repository { get; set; } 

    public UserValidationAttribute() 
    { 
    } 
} 

https://stackoverflow.com/a/7192754/296861

+0

彼の依存関係は必須と思われるリポジトリなので、コンストラクタを介して注入する必要があります。また、あなたのクラスにあなたのIoCの魔法の属性を振りかけることは悪いパターンだと感じています。現在、ほとんどのIoCコンテナは、Ninject、Unity v3、StructureMapなどのMVCフィルタへの注入をサポートしています –

18

コンストラクタ・インジェクションを使用する方法があります。

まず、あなたはただ、あなたがIActionFilterとしてフィルタクラスを作成するマーカーとして

public class UserValidationAttribute : Attribute { } 

を使用する「空」1を使用して属性を置換します。

public class UserValidationFilter : IActionFilter 
{ 
    private readonly IRepository repository; 

    public UserValidationFilter(IRepository repository) 
    { 
     this.repository = repository; 
    } 

    public void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     //do something 
    } 

    public void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     //do something 
    }  
} 

次に、あなたの属性自体はコンストラクタのパラメータを持っている場合、あなたは

kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0) 
    .WhenActionMethodHas<UserValidationAttribute>(); 
    .WithConstructorArgumentFromActionAttribute<UserValidationAttribute>("myParameter", attr => attr.MyParameter); 

BindFilter構文はの一部であるようにそれらを渡すことができ

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0) 
     .WhenActionMethodHas<UserValidationAttribute>(); 
} 

のようなものに登録することができますNinject.Web.Mvc.FilterBindingSyntax