【问题标题】:DependencyResolver + Owin + WebApi2DependencyResolver + Owin + WebApi2
【发布时间】:2014-10-14 19:23:39
【问题描述】:

Owin 的一大优点是它不依赖于System.Web。如果 WebApi 明确需要类似这些方面的东西,我到底该如何设置 DI:

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

其中config.DependencyResolver 需要来自System.Web.Http.DependenciesIDependencyResolver 的具体?

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

【问题讨论】:

  • 现在在 webapi 中运行良好。我现在面临的问题是,当我使用 owin testserver 运行集成测试时,我得到“看起来你忘记注册 http 模块 Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule”,这是由于引入了对 System.Web 的依赖假设?

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


【解决方案1】:

我已经设法让它工作了:

[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 测试服务器时遇到问题。我将发布另一个问题。

【讨论】:

  • 有什么问题?他们只是在安装目录中有另一个不需要的 dll 还是会导致程序出现故障?
【解决方案2】:

看看这里 - "Dependency Injection in ASP.NET Web API with Castle Windsor by Mark Seemann"。然后在Mark Seeman's blog archive。他经常谈论 DI 和 WEB API,并且经常使用 Castle Windsor。我敢打赌温莎城堡是他最喜欢的 DI 容器。当您查看档案时,不要只寻找 WEB API。有时他会在different title 下发布有关 WEB API 的帖子。

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

【讨论】:

  • 感谢我不久前阅读了博客和书籍。最后得到它的工作(见下面的答案)。
  • @csetzkorn 你应该把你的答案标记为正确的,而不是这个。这个答案根本没有回答你提出的问题。您的答案有一个有效的解决方案,您应该将其标记为正确答案。
猜你喜欢
  • 2015-01-23
  • 2014-11-10
  • 2014-08-14
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 2016-10-02
  • 2016-02-06
  • 2015-03-16
相关资源
最近更新 更多