DependencyResolver + Owin + WebApi2
Asked Answered
D

2

6

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

Douglassdougy answered 21/8, 2014 at 8:26 Comment(2)
Can you use the IDependencyResolver in System.Web.Mvc?Elwina
It works fine in webapi now. problem I am facing now is that when I run an integration test using the owin testserver I am getting "Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule" this is due to the introduced dependency on System.Web I suppose?Douglassdougy
D
7

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.

Douglassdougy answered 22/8, 2014 at 8:7 Comment(1)
What are the issues? Are they just that you have another unwanted dll in the install directory or does it cause the program to malfunction?Column
H
4

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.

Hadlee answered 22/8, 2014 at 5:27 Comment(2)
Thanks I read the blogs and book a while ago. Got it working in the end (see answer below).Douglassdougy
@csetzkorn you should mark your answer as the the correct one, not this one. This answer does not answer the question you asked at all. Your answer has a solution that works and you should mark it as the correct answer.Column

© 2022 - 2024 — McMap. All rights reserved.