使用Unity和Web API控制器的自定义依赖项解析程序时出错

时间:2015-01-16 00:03:21

标签: c# asp.net-web-api unity-container

我使用以下类作为依赖项解析器。得到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类中,我正在配置像这样的依赖解析器

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控制器中的所有依赖项似乎都被正确注入,我唯一担心的是因为它无法解决上面提到的几个(特定于框架) 类型,是否有可能导致整个框架出现故障并产生随机错误?

1 个答案:

答案 0 :(得分:14)

没有问题,您的程序在这里按预期工作。你看到的是Unity的Resolve方法抛出的第一次机会异常。抛出异常是因为Unity无法在无法解析服务时返回null。但是,如果请求的服务未在依赖项解析器实现中注册,则IDependencyResolver.GetService实现应始终返回null

如果GetService返回null,MVC将回退到所请求服务的框架的默认实现。在大多数情况下,不需要在Unity容器中覆盖这些服务,即使需要不同的服务,也可以轻松替换MVC默认实现,而无需将其添加到Unity配置中。

但是由于预期Unity会抛出此异常,因此这些方法包含catch子句。因此,您遇到的异常会在该方法中被捕获并返回null。

显然,在启动应用程序后让调试器多次停止在这些方法上是非常烦人的,因此解决方案是使用[DebuggerStepThrough]属性标记这些方法,以防止调试器在这些方法中停止。