Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>().

like image 871
bbeda Avatar asked Feb 25 '15 17:02

bbeda


3 Answers

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.

like image 142
Travis Illig Avatar answered Sep 24 '22 20:09

Travis Illig


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.

like image 29
bbeda Avatar answered Sep 22 '22 20:09

bbeda


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));
like image 30
Adriien M Avatar answered Sep 25 '22 20:09

Adriien M