Injecting dependency into CustomAttribute using Castle Windsor

10,956

Solution 1

OK - this seems to be a duplicate of Database injection into a validation attribute with ASP MVC and Castle Windsor which has been answered.

Also How do I use Windsor to inject dependencies into ActionFilterAttributes.

Having read through the above, and the referenced articles - the key one for me is http://weblogs.asp.net/psteele/archive/2009/11/04/using-windsor-to-inject-dependencies-into-asp-net-mvc-actionfilters.aspx for anyone else who is interested.

Solution 2

You can't. Attributes are metadata. Putting behaviour into them is wrong. Putting dependencies is even worse.

Use your attribute as marker to denote objects to which you want to apply the behavior and implement the behavior elsewhere.

In MVC elsewhere usually means a custom action invoker that uses data from the attribute to provide the behavior you need.

Share:
10,956

Related videos on Youtube

BonyT
Author by

BonyT

...

Updated on June 01, 2022

Comments

  • BonyT
    BonyT almost 2 years

    In my ASP.Net MVC application I have implemented a Custom ActionFilter to Authorize users.

    I use CastleWindsor to provide dependency injection into all of the controllers as follows:

      protected virtual IWindsorContainer InitializeServiceLocator()
        {
            IWindsorContainer container = new WindsorContainer();
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
    
            container.RegisterControllers(typeof(HomeController).Assembly);
            ComponentRegistrar.AddComponentsTo(container);
    
            ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
    
            return container;
        }
    

    Within my CustomAttribute, I need a dependency that is used by all of my controllers, however I am unable to user Constructor based injection in an attribute.

    So what's the cleanest way out here? How can I provide the dependency?

    • Mark Seemann
      Mark Seemann almost 13 years
      Don't put behavior in attributes...
  • BonyT
    BonyT almost 13 years
    OK - Please then explain the difference between what I am doing and this article: asp.net/mvc/tutorials/understanding-action-filters-vb
  • BonyT
    BonyT almost 13 years
    Also - this answer provides criticism without really giving any kind of solution... "elsewhere?" Please be specific. How would you implement authorization that applies throughout the application on many controllers and requires a dependency?
  • Steven
    Steven almost 13 years
    I had to overrule the downvote with a big fat upvote. A picture says more than a thousand words.
  • Steven
    Steven almost 13 years
    @BonyT: Do you see any dependencies being injected in the attributes shown in that article?
  • BonyT
    BonyT almost 13 years
    OK - I'll say this one more time - A reasonable answer provides a solution. Quote from article: "Authorization filters are used to implement authentication and authorization for controller actions." My authorization implementation requires an external dependency. If you don't believe that it should be injected into the attribute then provide a feasible alternative - or stay out of the discussion.
  • Crixo
    Crixo almost 13 years
    I have to aggree with Bony. Krzysztof I understand your point to, but please let us know what you have in mind with "implement the behavior elsewhere". Are you referring to the solution implemented in sutekishop(see AuthenticateAttribute+AuthenticateFilter)? That solution, due to anti-pattern, does not look as clean as the one suggested on next answer by Bony... I'm using that too and I'm kind of happy so far. But please Krzysztof tell as more about what are we missing here: I'd really like to undersand your point in full
  • kite
    kite almost 12 years
    @Krzysztof do you prefer/suggest using castle windsor interceptor instead of actionFilter?
  • Ognyan Dimitrov
    Ognyan Dimitrov over 10 years
    BonyT, you just have to derive from RoleProvider and then place registration for this provider in web.config. In this way you do not bother with attributes but the default implementation in authorize attribute will call IsUserInRole and GetRolesForUser from your implementation.