web-dev-qa-db-fra.com

Enregistrer des filtres globaux dans ASP.Net MVC 4 et Autofac

J'ai un filtre comme celui-ci:

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

J'ai besoin qu'il soit exécuté pour toutes les actions de mon projet

J'ai essayé de l'enregistrer dans les GlobalFilters mais ma propriété n'est pas injectée

J'ai essayé Cette solution pour enregistrer mon filtre mais il n'est pas appelé

Une idée sur comment faire ça?

31
JuChom

Il existe une nouvelle façon d'enregistrer les filtres globaux MVC dans AutoFac. Tout d'abord, supprimer l'enregistrement du filtre de votre RegisterGlobalFilters parce que nous aurons la gestion Autofac en les ajoutant à nos contrôleurs/actions au lieu de MVC.

Enregistrez ensuite votre conteneur comme suit:

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));

Notez qu'en passant la classe Controller dans l'extension AsActionFilterFor(), nous demandons à AutoFac d'appliquer ce filtre à toutes les classes qui dérivent de la classe Controller (qui, dans MVC , est tous les contrôleurs). Puisque nous appelons AsActionFilterFor() sans aucun argument, nous spécifions également que nous voulons que le filtre soit appliqué à toutes les actions dans les contrôleurs spécifiés. Si vous souhaitez appliquer votre filtre à un contrôleur et une action sélectionnés, vous pouvez utiliser des expressions lambda comme ceci:

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

Si votre action prend un paramètre, utilisez le mot clé default pour spécifier:

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

Notez que vous devez utiliser une méthode d'extension différente en fonction du type de filtre que vous enregistrez, voici les types de filtres pris en charge:

  • AsActionFilterFor
  • AsAuthorizationFilterFor
  • AsExceptionFilterFor
  • AsResultFilterFor
46
Pete

Vous devez maintenant utiliser la solution de Pete maintenant pour ce faire. Merci à lui pour une solution mise à jour.

Je l'ai finalement fait, voici comment le faire:

Créez d'abord votre attribut avec un constructeur avec toutes les dépendances

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

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

Enregistrez tout ce dont vous avez besoin dans 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));

Enregistrez votre filtre global comme ça

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

Assurez-vous que dans votre global.asax vous enregistrez d'abord Autofac puis les filtres globaux.

Maintenant, vous n'avez plus besoin d'injection de propriété, l'injection de constructeur fonctionnera bien, ce qui est une bonne chose!

16
Swell