web-dev-qa-db-ja.com

ASP.Net MVC 4およびAutofacにグローバルフィルターを登録する

このようなフィルターがあります:

public class CustomFilterAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    public MyPropery Property { get; set; }
    ....
}

プロジェクトのすべてのアクションに対して実行する必要があります

GlobalFiltersに登録しようとしましたが、プロパティが挿入されません

このソリューション を試してフィルターを登録しましたが、呼び出されません

それを行う方法についてのアイデアはありますか?

31
Swell

AutoFacにMVCグローバルフィルターを登録する新しい方法があります。まず、removeRegisterGlobalFiltersからのフィルター登録です。これは、AutofacがMVCの代わりにコントローラー/アクションに追加するためです。

次に、次のようにコンテナを登録します。

_var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<MyProperty>().As<IProperty>();

builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
                .AsActionFilterFor<Controller>().InstancePerHttpRequest();

builder.RegisterFilterProvider();

IContainer container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
_

Controllerクラスを拡張AsActionFilterFor()に渡すことにより、AutoFacにControllerクラス(MVCでは、すべてのコントローラーです)。引数なしでAsActionFilterFor()を呼び出しているため、指定したコントローラー内のすべてのアクションにフィルターを適用することも指定しています。選択したコントローラーとアクションにフィルターを適用する場合、次のようなラムダ式を使用できます。

_builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
    .AsActionFilterFor<HomeController>(c => c.Index())
    .InstancePerHttpRequest();
_

アクションがパラメーターを取る場合、defaultキーワードを使用して以下を指定します。

_builder.Register(c => new CustomFilterAttribute(c.Resolve<IProperty>()))
    .AsActionFilterFor<HomeController>(c => c.Detail(default(int)))
    .InstancePerRequest();
_

登録するフィルターの種類に基づいて、異なる拡張方法を使用する必要があることに注意してください。サポートされているフィルターの種類は次のとおりです。

  • AsActionFilterFor
  • AsAuthorizationFilterFor
  • AsExceptionFilterFor
  • AsResultFilterFor
46
Pete

これを行うには、Peteのソリューションを使用する必要があります。更新されたソリューションをありがとう。

私はついにそれを作りました、ここにそれをする方法があります:

まず、すべての依存関係を持つコンストラクターで属性を作成します

public class CustomFilterAttribute : ActionFilterAttribute, IAuthorizationFilter
{
    private IProperty _property;

    public CustomFilterAttribute(IProperty repository)
    {
        _property = property;
    }
    ....
 }

必要なものすべてをautofacに登録します

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<MyProperty>().As<IProperty>();
builder.RegisterType<CustomFilterAttribute>().SingleInstance();

builder.RegisterFilterProvider();

IContainer container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

そのようなグローバルフィルターを登録します

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(DependencyResolver.Current.GetService<CustomFilterAttribute>());
}

Global.asaxで、最初にAutofacを登録してから、グローバルフィルターを登録してください。

これで、プロパティインジェクションはもう必要ありません。コンストラクタインジェクションは正常に機能します。これは良いことです。

16
Swell