DependencyResolver + Owin + WebApi2

时间:2014-08-21 08:26:42

标签: c# asp.net-web-api asp.net-web-api2 owin castle-windsor

Owin的一大优势是它不依赖于System.Web。如果WebApi显然需要这些内容,我该如何设置DI:

var config = new HttpConfiguration();
var container = new WindsorContainer().Install(new ControllerInstaller());
container.Install(FromAssembly.This());
config.DependencyResolver = ...

config.DependencyResolver需要具体IDependencyResolver来自System.Web.Http.Dependencies

我对使用WebApi + Owin + Castle.Windsor的C#代码特别感兴趣(Google还没有多少帮助)。

2 个答案:

答案 0 :(得分:6)

我已经成功地使用了它:

[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()
    {
    }
}

我面临的问题是使用:

config.DependencyResolver = httpDependencyResolver;

引入了对system.web的依赖。所以当我尝试在某些整合测试中使用owin测试服务器时,我遇到了问题。我将发布另一个问题。

答案 1 :(得分:4)

看看这里 - "Dependency Injection in ASP.NET Web API with Castle Windsor by Mark Seemann"。然后在Mark Seeman's blog archive。他谈了很多关于DI和WEB API的事情,他经常使用Castle Windsor。我打赌Castle Windsor是他最喜欢的DI容器。当你查看存档时,不要只看WEB API。有时他会在different title下发布有关WEB API的信息。

如果您阅读his excellent book,您将对IoC / DI的主题有很好的理解。非常好的书。