使用 ASP.NET Web API 2.1 配置依赖项注入 [英] Configuring dependency injection with ASP.NET Web API 2.1

查看:34
本文介绍了使用 ASP.NET Web API 2.1 配置依赖项注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating an ASP.NET Web API 2.1 site and as I want to inject dependencies directly into the controllers, I've created my own implementation of IDependencyResolver so that StructureMap will handle that for me.

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 使用这个类

I've then told Web API to use this class by adding this line to the Application_Start method in Global.asax

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();

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

That compiled but when I tried to access any of the API methods in a browser I got an error like this

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

那个问题相对容易解决,因为我在 StructureMap 配置中添加了一行

That one was relatively easy to solve as I added a line to my StructureMap configuration

this.For<IHostBufferPolicySelector>().Use<WebHostBufferPolicySelector>();

但是,对于其他 System.Web.Http 类,我遇到了其他类似的错误,虽然我可以解决其中的一些错误,但我仍然无法解决其中的 3 个,即 ITraceManager、IExceptionHandler 和 IContentNegotiator.

However then I got other similar errors for other System.Web.Http classes and while I could resolve some of them I am stuck on how to deal with 3 of them, namely ITraceManager, IExceptionHandler and IContentNegotiator.

问题在于,似乎是 ITraceManager 的默认实现的 TraceManager 是一个内部类,因此我无法在 StructureMap 配置中引用它.

The issue is that TraceManager which seems to be the default implementation of ITraceManager is an internal class and so I can't reference it in my StructureMap configuration.

那么我是完全错误的方法还是有其他方法可以注入这些内部类?

So am I going about this completely the wrong way or is there some other way to inject these internal classes?

推荐答案

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

I'd like to give you a suggestion and explanation why not to go this way, and how to do it differently (I'd even say better and properly).

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

The full and complete explanation of the inappropriate IDependencyResolver design could be found here: Dependency Injection and Lifetime Management with ASP.NET Web API by Mark Seemann

让我引用这些重要的部分:

Let me cite these essential parts:

IDependencyResolver 的问题

IDependencyResolver 的主要问题在于它本质上是一个服务定位器.Service Locator 反模式 存在许多问题,但我已经在本博客(以及我的书中)的其他地方描述了其中的大部分问题.Service Locator 的一个我还没有详细描述的缺点是,在每次调用 GetService 时根本没有上下文.这是 Service Locator 反模式的普遍问题,而不仅仅是 IDependencyResolver.

The main problem with IDependencyResolver is that it's essentially a Service Locator. There are many problems with the Service Locator anti-pattern, but most of them I've already described elsewhere on this blog (and in my book). One disadvantage of Service Locator that I haven't yet written so much about is that within each call to GetService there's no context at all. This is a general problem with the Service Locator anti-pattern, not just with IDependencyResolver.

还有:

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

...dependency graph need to know something about the context. What was the request URL? What was the base address (host name etc.) requested? How can you share dependency instances within a single request? To answer such questions, you must know about the context, and IDependencyResolver doesn't provide this information.

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

In short, IDependencyResolver isn't the right hook to compose dependency graphs. **Fortunately, the ASP.NET Web API has a better extensibility point for this purpose. **

服务激活器

因此,这种情况下的答案是 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 而不是 Service locator

All we can do with StructureMap, is in place. The key features of the Web API framework are still in place... we do not have to hack them. And we are also rather using DI/IoC then Service locator

这篇关于使用 ASP.NET Web API 2.1 配置依赖项注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆