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

问题描述 投票:0回答:2

我正在创建一个 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()
    {
    }
}

然后我通过将此行添加到 Global.asax 中的 Application_Start 方法来告诉 Web API 使用此类

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();

已编译,但当我尝试在浏览器中访问任何 API 方法时,出现这样的错误

没有为 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 配置中引用它。

那么我的处理方式是否完全错误,还是有其他方法来注入这些内部类?

asp.net dependency-injection asp.net-web-api structuremap
2个回答
50
投票

我想给你一个建议和解释为什么不走这条路,以及如何以不同的方式去做(我什至会说更好和正确)。

不恰当的

IDependencyResolver
设计的完整解释可以在这里找到:Mark Seemann 的 使用 ASP.NET Web API 进行依赖注入和生命周期管理

让我引用这些重要部分:

IDependencyResolver 的问题

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

还有:

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

简而言之,

IDependencyResolver
不是构成依赖图的正确钩子。 **幸运的是,ASP.NET Web API 为此具有更好的扩展点。 **

服务激活器

因此,这种情况下的答案是

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,然后使用服务定位器


-3
投票

只需尝试使用 UnityHierarchicalDependencyResolver 而不是另一个。这对我有用。如果有人想使用 Unity,这可供将来参考

© www.soinside.com 2019 - 2024. All rights reserved.