3

I'm trying to use depedency resolver inside a Web Api method. This worked fine and works fine with classic ASP.NET MVC with the DepedencyResolver.GetService()

But I can't get this to work inside WepApi methods.

My registration register all instances as InstancePerApiRequest and if I add any of all the types I have registred in my bootstrapper on the constructor of my WebAPiConroller thay inject fine but not anymore when calling them inside.

Like this in my say Get Method

var userRepository = (IUserRepositoryu)GlobalConfiguration
       .Configuration.DependencyResolver.GetService(typeof(IUserRepository));

I got the no scope WebRequest error. The strange thing is that it worked fine in Beta before they change it all to the GlobalConfiguration.

So my question is, how can I activate my Autofac registered assemblies in the lifetime scope of my webAPi as before?

My error:

"No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself."

 var resolver = new AutofacWebApiDependencyResolver(container);
 configuration.DependencyResolver = resolver;
Community
  • 1
  • 1
RockJohan
  • 75
  • 1
  • 8

3 Answers3

5

In Web API the global dependency resolver is used to access global instances. Per-request services come from a dependency scope that Web API creates to handle the request. I'm not sure that there is any way in Web API to access the current dependency scope - it would be interesting to know.

The best option here is to just use dependency injection rather than calling the resolver directly like this. Which part of your code needs to make this call?

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101
  • I have Bus that take a DTO and I want that Bus to load it's own handle that are assigned to this DTO. in Beta and classic ASP .Net MVC I used the DependecnyResolver to do so and it uses the same instacne as the webrequest did a function I wanted to use. In RC this seams to have change so I only can inject my objects in the controllers constructors but not resolve the objects (services) inside the controller under the same request as the controllers constructors. – RockJohan Jun 25 '12 at 07:52
  • ie: public class FooController(ICommandBus commandBus) In Atofac I have told the ICommandBus to live in the ApiLifetime than in my WepAPi methdo say Get I wat to uder this commandbus and the commandbus itself uses the resolver to create the commands handlers based on the same config and the same lifetime-scope as it self lives in.But since the resolver was bind to the GlobalConfig it seams like the GlobalConfig lifetime handler only worj when it creats the controller but not when call it manually after the controll was created.Thought the error I got is based on problem with lifetime scope. – RockJohan Jun 25 '12 at 07:53
  • public SomeModel Get() { var userRepository = (IUserRepositoryu)GlobalConfiguration .Configuration.DependencyResolver.GetService(typeof(IUserRepository)); } will not work. If I try to create the commandbus that injects without problem in my controller constructor I got the same problem. It's like the lifetimescope cannot be handled when the controller is created. – RockJohan Jun 25 '12 at 07:54
  • 2
    Ok - cool. I think what you want is to add an `IComponentContext` dependency to your controller like so: `FooController(ICommandBus commandBus, IComponentContext context)` and then resolve the handlers from the context. Any Autofac component can take a dependency on `IComponentContext` and get access to its own scope to resolve dependencies from. Let me know if you need more details - good luck! – Nicholas Blumhardt Jun 26 '12 at 05:38
0

AutoFac has integration with ASP.NET WebAPI consider to use it.

Also dependecy resolver for WebAPi is slightly different to ASP.NET MVC, so make shure, that you have implemented resolver suitable for WebAPI and added it to WebAPI configuration.

http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver

Regfor
  • 8,515
  • 1
  • 38
  • 51
  • If you look at my code I have done that.The problem is that Autofac throw an No scope error when try to use the configured DS inside my webApi code.It all works fine when using the Autofac WebApi configuration for WebApiController constructors but not when I manually want to resvole an instance in my webapi. It worked fine in Web APi Beta but that was before the GlobalCOnfiguration and changes MS made in the RC release I also use latest RC release of Autofac. So either I'm using the GlobalCOnfiguration to manually resolve an instance wrong or there is a bug or problem using it with Autofac. – RockJohan Jun 20 '12 at 18:12
0

As the error indicated, you must always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime. The correct way is getting the dependency from current web api request:

// Get the request lifetime scope so you can resolve services.
var requestScope = Request.GetDependencyScope();
// Resolve the service you want to use.
var userRepository = requestScope.GetService(typeof(IUserRepository)) as IUserRepository;

See more from Autofac offical documentations: http://docs.autofac.org/en/latest/integration/webapi.html#standard-web-api-filter-attributes-are-singletons

Johnny Qian
  • 668
  • 7
  • 14