Bogdan Beda
Bogdan Beda

Reputation: 788

OWIN Service resolution Using Autofac

I have an WebApi application using OWIN and Autofac. Although controllers and parameters get resolved correctly, I would like to be able to use OwinContext.Get<type> to resolve types registered with Autofac. Is that posible?

Already setapp.UseAutofacMiddleware(container); and config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

By example, I registered builder.Register<IAppConfiguration>(c => new AppConfig()); and I'd like to resolve it using owinContext.Get<IAppConfiguration>().

Upvotes: 5

Views: 5353

Answers (3)

Adriien M
Adriien M

Reputation: 1185

If you have WebAPI in your project, you can simulate a http request like this

var dependencyScope = new AutofacWebApiDependencyScope(owinContext.GetAutofacLifetimeScope());
var myService = dependencyScope.GetService(typeof(MyService));

Upvotes: 4

Bogdan Beda
Bogdan Beda

Reputation: 788

The IOwinContext.Get uses the Environment dictionary, resolving objects registered directly with Owin, it does not take into account Autofac container.

I managed to do it by accessing the Autofac OwinLifetimeScope in the Environment property and using the scope to resolve the service.

You can access the LifetimeScope using this code

var scope=OwinContext.Get<Autofac.Core.Lifetime.LifetimeScope>("autofac:OwinLifetimeScope"); 

and then

scope.GetService(type)

You should check for nulls and write it in a better way, as Extension method maybe.

Upvotes: 4

Travis Illig
Travis Illig

Reputation: 23934

There is no way to get OwinContext.Get<T> to resolve things from Autofac. If you dive into Microsoft.Owin.OwinContext.Get in Reflector, you'll see it's backed entirely by a dictionary of things you register with an environment. It's not dynamic and there's no way (without creating your own IOwinContext implementation) to get it to resolve things either out of the dictionary or out of dependency resolution.

If you are in a DelegatingHandler or an ApiController you will have a reference to the current HttpRequestMessage. Use message.GetDependencyScope() to get the current request-level dependency scope to resolve services.

public HttpResponseMessage SomeControllerAction()
{
  var service = this.Request.GetDependencyScope().GetService(typeof(Service));
}

If you have access to the HttpConfiguration then you can use the HttpConfiguration.DependencyResolver to resolve things. Note that resolver will not have per-request dependencies available. Web API tracks request dependency scope with the inbound HttpRequestMessage so be aware of that limitation. There is an FAQ about per-request lifetime scope that can help you through that.

If you're in a place where there's only an IOwinContext, you may need to make use of a package like CommonServiceLocator and the associated Autofac.Extras.CommonServiceLocator. There really isn't a way to get a reference to the current HttpConfiguration or global container just from an IOwinContext. Again, if you go this route, you won't have per-request dependencies available, so be aware.

Upvotes: 8

Related Questions