Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property Injection in Web API ActionFilterAttribute does not use Http request scope #452

Closed
alexmg opened this issue Jan 22, 2014 · 3 comments

Comments

@alexmg
Copy link
Member

alexmg commented Jan 22, 2014

From rob.lyn...@gmail.com on August 01, 2013 23:58:40

What steps will reproduce the problem? 1. Register NHibernate using the standard pattern:

builder.Register(c => cfg.BuildSessionFactory()).As().SingleInstance();
builder.Register(c => c.Resolve().OpenSession()).InstancePerWebApiRequest();

  1. Create a TransactionAttribute class that derives from the Web API ActionFilterAttribute. Add a public get/set property called Session, of type ISession.
  2. Register the filter provider in the setup method:

builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

  1. Add a TransactionAttribute to any web api controller action. It will fail to be picked up because the filter provider has tried to use the configuration.DependencyResolver to resolve the Session property, rather than the HttpRequest scope. What is the expected output? What do you see instead? What version of Autofac are you using? On what version of .NET/Silverlight? Please provide any additional information below.

Original issue: http://code.google.com/p/autofac/issues/detail?id=452

@alexmg
Copy link
Member Author

alexmg commented Jan 22, 2014

From travis.illig on August 08, 2013 13:59:25

Labels: Module-Integration-WebApi

@tillig tillig added the wontfix label Apr 24, 2014
@tillig
Copy link
Member

tillig commented Apr 24, 2014

As it turns out, this is by design.

When attribute filters are located by the base Web API framework, the actual attribute instances are cached in the action descriptor (or controller descriptor) inside the application HttpConfiguration object - effectively making the attribute filters singletons.

You can see this if you look at the source for ActionDescriptorFilterProvider and start following the chain of execution - ReflectedHttpActionDescriptor (the primary implementation of HttpActionDescriptor) caches the generated list of filters; HttpControllerDescriptor also caches the set of custom attributes/filters.

As such, if the properties get resolved out of the request context, once the current request is over, the set of cached filters effectively becomes invalid, working against disposed/stale dependencies. There's nothing we can really do about that.

Even if you register Autofac action filters, the "request lifetime scope" from which the filters get resolved is not actually the same request lifetime scope being used to resolve the controller servicing the request. We don't get access to the current request lifetime scope from inside the IFilterProvider interface, so, again, we don't have much choice.

Given we can't change things from our end, I'm going to close this one as wontfix. If the Web API framework updates to enable better handling of this, we'll certainly take a look at updating.

@tillig
Copy link
Member

tillig commented May 14, 2014

As noted in #525, a potential fix would be to dynamically proxy all filters such that the filter instance cached is the proxy and the actual thing executing would be resolved each request. However, that may be challenging to maintain and may interfere with other things in unexpected ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants