使用ASP.NET Web API 2.1配置依赖项注入

时间:2014-02-20 21:15:23

标签: asp.net dependency-injection asp.net-web-api structuremap

我正在创建一个ASP.NET Web API 2.1站点,因为我想将依赖项直接注入控制器,所以我创建了自己的IDependencyResolver实现,以便StructureMap为我处理。

public class StructureMapDependencyResolver : IDependencyResolver
{
    public IDependencyScope BeginScope()
    {
        return this;
    }

    public object GetService(Type serviceType)
    {
        return ObjectFactory.GetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {            
        return ObjectFactory.GetAllInstances(serviceType).Cast<object>();
    }

    public void Dispose()
    {
    }
}

我告诉Web API使用此类,将此行添加到Global.asax中的Application_Start方法

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();

编译但是当我尝试访问浏览器中的任何API方法时,我收到了类似这样的错误

No Default Instance defined for PluginFamily System.Web.Http.Hosting.IHostBufferPolicySelector, System.Web.Http

当我在StructureMap配置中添加一行

时,这个问题相对容易解决
this.For<IHostBufferPolicySelector>().Use<WebHostBufferPolicySelector>();

然而,我为其他System.Web.Http类得到了其他类似的错误,虽然我可以解决其中的一些问题,但我仍然坚持如何处理其中的3个,即ITraceManager,IExceptionHandler和IContentNegotiator。

问题是TraceManager似乎是ITraceManager的默认实现,是一个内部类,所以我不能在我的StructureMap配置中引用它。

所以我完全以错误的方式解决这个问题,还是有其他方法来注入这些内部类?

2 个答案:

答案 0 :(得分:48)

我想给你一个建议和解释,为什么不这样做,以及如何以不同的方式做到(我甚至会说得更好更好)。

可以在此处找到不恰当IDependencyResolver设计的完整和完整说明:Mark Seemann的Dependency Injection and Lifetime Management with ASP.NET Web API

让我引用这些重要部分:

  

IDependencyResolver的问题

     

IDependencyResolver的主要问题是它本质上是一个服务定位器服务定位器 反模式存在许多问题,但其中大多数我已经在本博客的其他地方(以及我的书中)中描述过。我还没有写过很多关于Service Locator的一个缺点是,在每次调用GetService时都没有任何上下文。这是Service Locator反模式的一般问题,而不仅仅是IDependencyResolver。

还有:

  

...依赖图需要了解有关上下文的内容。请求URL是什么?请求的基地址(主机名等)是什么?如何在单个请求中共享依赖项实例?要回答这些问题,您必须了解上下文,而IDependencyResolver不提供此信息。

     

简而言之,IDependencyResolver不是构成依赖图的右钩子。 **幸运的是,ASP.NET Web API具有更好的可扩展性。 **

ServiceActivator

所以,这种情况下的答案是ServiceActivator。请看一下这个答案:

ServiceActivator的一个例子:

public class ServiceActivator : IHttpControllerActivator
{
    public ServiceActivator(HttpConfiguration configuration) {}    

    public IHttpController Create(HttpRequestMessage request
        , HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        var controller = ObjectFactory.GetInstance(controllerType) as IHttpController;
        return controller;
    }
}

我们可以使用StructureMap完成所有工作。 Web API框架的主要功能仍然存在......我们不必破解它们。而且我们也在使用DI / IoC然后使用服务定位器

答案 1 :(得分:-3)

尝试使用UnityHierarchicalDependencyResolver而不是另一个。它对我有用。如果有人想使用Unity

,这是为了将来的参考