Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 859
cs0815 Avatar asked Aug 21 '14 08:08

cs0815


People also ask

Does .NET framework support dependency injection?

. NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. Dependency injection in . NET is a built-in part of the framework, along with configuration, logging, and the options pattern.

What is Web API dependency injection?

Dependency Injection (often called just DI) is a software design pattern that helps us create loosely coupled applications. It is an implementation of the Inversion of Control (IoC) principle, and Dependency Inversion Principle (D in SOLID).

What is IServiceCollection in .NET core?

} IServiceCollection is the collection of the service descriptors. We can register our services in this collection with different lifestyles (Transient, scoped, singleton) IServiceProvider is the simple built-in container that is included in ASP.NET Core that supports constructor injection by default.


2 Answers

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.

like image 162
cs0815 Avatar answered Oct 17 '22 12:10

cs0815


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.

like image 4
Ognyan Dimitrov Avatar answered Oct 17 '22 11:10

Ognyan Dimitrov