Unity IoC不会将依赖注入Web API Controller

Car*_*uez 21 c# unity-container asp.net-web-api

我是使用Unity的新手,但我的问题是每当我调用我的Web服务时,我都会得到一个例外情况

"确保控制器具有无参数的公共构造函数"

我已经遵循了多个教程,我仍然遇到同样的问题.

在我的WebApiConfig类的Register函数中,我有

var container = new UnityContainer();
container.RegisterType<IValidator, Validator>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
Run Code Online (Sandbox Code Playgroud)

这是我的UnityResolver类

using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

public class UnityResolver : IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        container.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有注册任何控制器,因为每个教程都声称我不需要这样做.这是我的实际控制器

public class Controller: ApiController
{
    private IValidator _validator;

    public Controller(IValidator validator)
    {
        this._validator = validator;
    }

    [HttpPost]
    public void ReceiveIPN()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

有没有人对我做错了什么有任何想法?谢谢!

编辑1:这是Validator类的"实现".这很空,因为在解决Unity问题之前我不想在这里引入一个bug.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


public class Validator: IValidator
{
    public bool ValidateIPN(string body)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:这是我尝试使用Fiddler调用web api路由时得到的整个错误响应

{"message":"发生错误.","exceptionMessage":"尝试创建'Controller'类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.","exceptionType": System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)中的"System.InvalidOperationException","stackTrace":"at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request,HttpControllerDescriptor controllerDescriptor,Type controllerType)at at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","innerException":{"message":"发生错误.","exceptionMessage":"类型'Project.Controller'没有默认值构造函数","exceptionType":"System.ArgumentException","stackTrace":"在System.Web.Http.Internal.TypeActivator.Create [TBase]的System.Linq.Expressions.Expression.New(Type type)中(类型instanceType )在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceO System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request,HttpControllerDescriptor controllerDescriptor,Type controllerType)中的rActivator(HttpRequestMessage请求,类型controllerType,Func`1和激活器)"}}

Car*_*uez 26

所以,经过几个小时的撞墙后,我发现这不起作用,因为我的项目中有一个OWIN/Katana Startup.cs课程.现在我不确切知道这里发生了什么,所以更多的信息会很棒.

基本上,由于我使用OWIN/Katana,我有一个Startup.cs文件创建了一个新的HttpConfiguration对象并对其进行了配置,类似于在WebApiConfig.cs类中完成的操作.

private void ConfigureWebApi(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    var container = new UnityContainer();
    container.RegisterType<IValidator, Validator>();
    config.DependencyResolver = new UnityDependencyResolver(container);

    var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter().First();
    jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
Run Code Online (Sandbox Code Playgroud)

看起来代码首先通过WebApiConfig的Register函数运行,然后THEN使用Startup.cs文件中生成的HttpConfiguration对象覆盖它.我不得不在这里移动我的容器设置,以使其工作.

对不起,我之前没有提起过OWIN的东西.这对我来说是相当新的,我没有意识到它是相关的.希望这可以拯救别人我刚经历过的痛苦.

  • 确实很重要的细节;)很高兴你能够解决它.使用Owin时,操作顺序对于某些方面非常重要(WebApiConfig.Register()和app.UseWebApi()之类的东西必须按顺序排列,并且在StartUp类的末尾. (3认同)