Injecting dependency into CustomAttribute using Castle Windsor
Asked Answered
G

2

15

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?

Gaylord answered 25/5, 2011 at 15:8 Comment(3)
Don't put behavior in attributes...Gwendagwendolen
possible duplicate of How do I use Windsor to inject dependencies into ActionFilterAttributesGaylord
IMHO best answer is here #10709065 (and in that question itself - very good example (hint: IFilterProvider)).Freckle
G
13

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.

Gaylord answered 26/5, 2011 at 9:25 Comment(0)
B
1

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.

Behrens answered 25/5, 2011 at 21:26 Comment(8)
OK - Please then explain the difference between what I am doing and this article: asp.net/mvc/tutorials/understanding-action-filters-vbGaylord
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?Gaylord
I had to overrule the downvote with a big fat upvote. A picture says more than a thousand words.Crosseye
@BonyT: Do you see any dependencies being injected in the attributes shown in that article?Crosseye
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.Gaylord
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 fullKellikellia
@Krzysztof do you prefer/suggest using castle windsor interceptor instead of actionFilter?Eduard
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.Solange

© 2022 - 2024 — McMap. All rights reserved.