Unity.WebApi | 确保控制器具有无参数的公共构造函数

Jas*_*dly 4 c# dependency-injection inversion-of-control unity-container asp.net-web-api

我在ASP.NET WebApi解决方案中使用Unity.WebApi NuGet包(Unity 4.0.1和Unity.WebApi 5.2.3).我面临的问题是,在尝试运行代码时,我收到错误:Make sure that the controller has a parameterless public constructor.我在这里搜索过类似的帖子,但我找不到任何符合我问题的帖子.

请不要只说"添加无参数构造函数",因为它显示您显然不知道IoC是什么以及为什么该语句完全没有意义并且违背了IoC的目的.我之所以这么说是因为我在迄今为止看过的很多其他主题中看到了这一点.

这是我的Startup.cs(我使用的是Owin,所以我没有Global.asax):

public void Configuration(IAppBuilder app) {
    var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();

        // Registering unity stuff
        UnityConfig.RegisterComponents();

        app.UseWebApi(config);
}
Run Code Online (Sandbox Code Playgroud)

这是我的UnityConfig.cs:

public static class UnityConfig {
    public static void RegisterComponents() {
        var container = new UnityContainer();
            // Register controller
            container.RegisterType<MyController>();

            // Register interface
            container.RegisterType<IService, Service>();

            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的API控制器:

public class MyController : ApiController {
    private IService service

    public MyController(IService service) {
        this.service = service;
    }

    public IHttpActionResult Get() {
        return Ok("All systems go!");
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

我拿出了使用声明,因为人们很难理解无论使用语句是否存在,问题就会发生.

smo*_*nes 14

根据我的经验,发生这种情况有两种不同的情况.

1.确保Service可以解析构造函数中的所有参数.它是否有任何尚未注册的依赖项?

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

2.确保使用Web API注册Unity.像这样:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Routes and other stuff here...

        var container = IocContainer.Instance; // Or any other way to fetch your container.
        config.DependencyResolver = new UnityDependencyResolver(container);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的例子:

将依赖注入Web API控制器

http://codeclimber.net.nz/archive/2015/02/20/Using-Entity-Framework-within-an-Owin-hosted-Web-API-with.aspx

编辑1:

正如评论中提到的@ NightOwl888,您不应该丢弃容器.注册在容器上注册,当容器被丢弃时,它将不知道如何解决依赖关系.这可能会导致您看到的错误.

编辑2:

既然你正在使用Owin,你应该能够做到这样的事情:

    public void Configuration(IAppBuilder appBuilder) 
    { 
      // Configure Web API for self-host. 
      HttpConfiguration config = new HttpConfiguration();
      config.DependencyResolver = new UnityDependencyResolver(
          UnityConfig.GetConfiguredContainer());

      config.Routes.MapHttpRoute( 
                    name: "DefaultApi", 
                    routeTemplate: "api/{controller}/{id}", 
                    defaults: new { id = RouteParameter.Optional } 
                ); 

      appBuilder.UseWebApi(config); 
    }
Run Code Online (Sandbox Code Playgroud)

并将您的UnityConfig更新为:

    public static class UnityConfig {
       public static IUnityContainer GetConfiguredContainer() {
            var container = new UnityContainer();
            // Register controller
            container.RegisterType<MyController>();

            // Register interface
            container.RegisterType<IService, Service>();

            //This is done in Startup instead.
            //GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
            return container;
    }
}
Run Code Online (Sandbox Code Playgroud)

从这个来源: OwinStartup时如何使用DI容器

http://damienbod.com/2013/10/01/self-host-webapi-with-owin-and-unity/

在此方法中,HttpConfiguration.DependencyResolver设置为UnityDependencyResolver实例.这是必需的,以便可以在webApi控制器中使用构造函数注入.UnityDependencyResolver类与Unity.WebApi.UnityDependencyResolver类完全相同.未使用Unity.WebApi,因为这是一个自托管的OWIN应用程序.