我正在创建一个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配置中引用它。
所以我完全以错误的方式解决这个问题,还是有其他方法来注入这些内部类?
答案 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
的一个例子:
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
,这是为了将来的参考