将自定义依赖项解析器与 Unity 和 Web API 控制器一起使用时出错
Errors while using custom dependency resolver with Unity and Web API controller
我正在使用以下 class 作为依赖项解析器。从 http://www.asp.net/web-api/overview/advanced/dependency-injection
获得参考
public class UnityWebAPIResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityWebAPIResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType); **// This line throws error**
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType); **// This line throws error**
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityWebAPIResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
在路由配置后的 WebApiConfig class 中,我正在像这样配置依赖解析器
config.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());
问题是我遇到了几个这样的错误..
InvalidOperationException - The type IHostBufferPolicySelector does not have an accessible constructor.
InvalidOperationException - The type ModelMetadataProvider does not have an accessible constructor.
InvalidOperationException - The type ITraceManager does not have an accessible constructor.
InvalidOperationException - The type ITraceWriter does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerSelector does not have an accessible constructor.
InvalidOperationException - The type IAssembliesResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerTypeResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpActionSelector does not have an accessible constructor.
InvalidOperationException - The type IActionValueBinder does not have an accessible constructor.
InvalidOperationException - The type IContentNegotiator does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerActivator does not have an accessible constructor.
InvalidOperationException - The type IBodyModelValidator does not have an accessible constructor.
即使我尝试在 global.asax 中做这样的事情,我也会遇到同样的错误。
GlobalConfiguration.Configuration.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());
问题:我的 API 控制器中的所有依赖项似乎都已正确注入,我唯一担心的是因为它不能解决上面提到的几个 (框架特定) 类型,它是否有可能导致整个框架故障并产生随机错误?
没有问题,您的程序在这里按预期运行。您看到的是 Unity 的 Resolve
方法抛出的第一次机会异常。抛出异常是因为当无法解析服务时,Unity 永远不会 return null
。 IDependencyResolver.GetService
然而,如果请求的服务未在依赖解析器实现中注册,则实现应始终 return null
。
如果 GetService
returns null
,MVC 将回退到框架对所请求服务的默认实现。在大多数情况下,不需要在 Unity 容器中重写这些服务,即使需要不同的服务,您也可以轻松替换 MVC 的默认实现,而无需将其添加到 Unity 配置中。
但由于 Unity 预计会抛出此异常,因此这些方法包含 catch
子句。因此,您遇到的异常是在该方法中捕获的,并且 null 是 returned.
显然启动应用程序后调试器多次停在那些方法上是很烦人的,所以解决办法是用[DebuggerStepThrough]
属性标记这些方法,以防止调试器停在这些方法。
我正在使用以下 class 作为依赖项解析器。从 http://www.asp.net/web-api/overview/advanced/dependency-injection
获得参考 public class UnityWebAPIResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityWebAPIResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType); **// This line throws error**
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType); **// This line throws error**
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityWebAPIResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
在路由配置后的 WebApiConfig class 中,我正在像这样配置依赖解析器
config.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());
问题是我遇到了几个这样的错误..
InvalidOperationException - The type IHostBufferPolicySelector does not have an accessible constructor.
InvalidOperationException - The type ModelMetadataProvider does not have an accessible constructor.
InvalidOperationException - The type ITraceManager does not have an accessible constructor.
InvalidOperationException - The type ITraceWriter does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerSelector does not have an accessible constructor.
InvalidOperationException - The type IAssembliesResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerTypeResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpActionSelector does not have an accessible constructor.
InvalidOperationException - The type IActionValueBinder does not have an accessible constructor.
InvalidOperationException - The type IContentNegotiator does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerActivator does not have an accessible constructor.
InvalidOperationException - The type IBodyModelValidator does not have an accessible constructor.
即使我尝试在 global.asax 中做这样的事情,我也会遇到同样的错误。
GlobalConfiguration.Configuration.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());
问题:我的 API 控制器中的所有依赖项似乎都已正确注入,我唯一担心的是因为它不能解决上面提到的几个 (框架特定) 类型,它是否有可能导致整个框架故障并产生随机错误?
没有问题,您的程序在这里按预期运行。您看到的是 Unity 的 Resolve
方法抛出的第一次机会异常。抛出异常是因为当无法解析服务时,Unity 永远不会 return null
。 IDependencyResolver.GetService
然而,如果请求的服务未在依赖解析器实现中注册,则实现应始终 return null
。
如果 GetService
returns null
,MVC 将回退到框架对所请求服务的默认实现。在大多数情况下,不需要在 Unity 容器中重写这些服务,即使需要不同的服务,您也可以轻松替换 MVC 的默认实现,而无需将其添加到 Unity 配置中。
但由于 Unity 预计会抛出此异常,因此这些方法包含 catch
子句。因此,您遇到的异常是在该方法中捕获的,并且 null 是 returned.
显然启动应用程序后调试器多次停在那些方法上是很烦人的,所以解决办法是用[DebuggerStepThrough]
属性标记这些方法,以防止调试器停在这些方法。