简体   繁体   中英

DependencyResolver + Owin + WebApi2

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM