Reputation: 17408
One of the great advantages of Owin is that it has no dependency on System.Web
. How on earth do I setup the DI if WebApi clearly requires something along those lines:
var config = new HttpConfiguration();
var container = new WindsorContainer().Install(new ControllerInstaller());
container.Install(FromAssembly.This());
config.DependencyResolver = ...
Where config.DependencyResolver
requires a concrete of IDependencyResolver
which comes from System.Web.Http.Dependencies
?
I am especially interested in C# code which uses WebApi + Owin + Castle.Windsor (Google has not helped much yet).
Upvotes: 6
Views: 6661
Reputation: 6251
Take a look right here - "Dependency Injection in ASP.NET Web API with Castle Windsor by Mark Seemann". Then at Mark Seeman's blog archive. He talks a lot about DI and WEB API and he uses Castle Windsor a lot. I bet Castle Windsor is his favorite DI container. When you look at the archive do not look just for WEB API. Sometimes he posts about WEB API under different title.
If you read his excellent book you will get very good understanding on the topic of IoC/DI. Very good book.
Upvotes: 4
Reputation: 17408
I have managed to get it working using:
[assembly: OwinStartup(typeof(Bla.Startup))]
namespace Bla
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//...
var container = new WindsorContainer().Install(new ControllerInstaller());
var httpDependencyResolver = new WindsorHttpDependencyResolver(container);
config.DependencyResolver = httpDependencyResolver;
//...
}
}
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestylePerWebRequest());
//...
}
}
internal class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
internal sealed class WindsorHttpDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorHttpDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
The problem I am facing is that the use of:
config.DependencyResolver = httpDependencyResolver;
introduces a dependency on system.web. So I have issues when I try to use the owin testserver in some integartion tests. I will post another question.
Upvotes: 7