1

Я использую пакет Unity.WebApi NuGet (Unity 4.0.1 и Unity.WebApi 5.2.3) в решении ASP.NET WebApi. Проблема, с которой я сталкиваюсь, заключается в том, что при попытке запустить код я получаю ошибку: Make sure that the controller has a parameterless public constructor. Я искал похожие темы здесь, но я не смог найти нить, которая соответствовала моей проблеме.Unity.WebApi | Удостоверьтесь, что контроллер имеет безкоммертный открытый конструктор

Пожалуйста, не просто скажите «Добавить конструктор без параметров», потому что он показывает, что вы, очевидно, не знаете, что такое 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); 
} 

Это мой 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); 
    } 
} 

Это мой API контроллер:

public class MyController : ApiController { 
    private IService service 

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

    public IHttpActionResult Get() { 
     return Ok("All systems go!"); 
    } 
} 

EDIT

Я использовал выражения для использования, потому что люди с трудом понимают, что проблема возникает, независимо от того, существуют ли там операторы.

+1

Можете ли вы рассказать о классе обслуживания? Вам не хватает регистрации любого класса, требуемого классом Service? – Noor

+1

Может быть, ваш контейнер находится перед тем, как он будет использоваться MVC? Это нелогично, что это заставило бы эту ошибку, но, может быть. Попробуйте использовать «var container = new UnityContainer()» из блока использования. – NightOwl888

+0

Noor Нет деталей для обмена. Предположим, что у него есть метод, который печатает «Hello World». NightOwl888 Я изначально сделал это, так что это не тот случай. Использование пришло позже по линии, пытаясь понять эту проблему. Я думаю, что это что-то неуловимое, потому что это основано на Овине, но я не уверен. –

ответ

11

По моему опыту есть два разных сценария, когда это происходит.

1. Убедитесь, что все параметры в конструкторе Service могут быть разрешены. Имеются ли у вас какие-либо зависимости, которые вы еще не зарегистрировали?

Make sure that the controller has a parameterless public constructor in Unity

2. Убедитесь зарегистрировать Unity с Web API. Как так:

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); 
    } 
} 

примеров здесь:

Injecting Dependency into Web API Controller

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

EDIT 1:

Как @ NightOwl888 упоминается в комментариях, не следует утилизировать контейнер , Регистрации регистрируются в контейнере, и когда контейнер расположен, он не знает, как разрешить зависимости. Это может привести к ошибке, которую вы видите.

EDIT 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); 
    } 

и обновить 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; 
    } 
} 

Из этого источника: How to use DI container when OwinStartup

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

In this method, the HttpConfiguration.DependencyResolver is set to a UnityDependencyResolver instance. This is required so that contructor injection can be used in the webApi controllers. The UnityDependencyResolver class is exactly the same as the Unity.WebApi.UnityDependencyResolver class. Unity.WebApi is not used because this is a self hosted OWIN application.

+0

Пожалуйста, обратитесь к моим комментариям, отвечая на вопрос NightOwl. Заявление об использовании появилось ПОСЛЕ этих проблем, и оно было добавлено в процессе попытки решить проблему. Не имеет значения, есть ли использование, я все еще вижу ту же проблему. Кроме того, предположим, что в нем ничего нет, и у него есть пустой конструктор по умолчанию. Или, если ваше воображение хочет бежать, предположим, что у него есть метод, который печатает «Hello world», опять же, пустой конструктор по умолчанию. Другими словами, ваши решения не решают эту проблему. –

+0

Я вижу. И вы также зарегистрировали свой DependencyResolver с помощью WebApi (2)? Обратите внимание, что это другая регистрация из обычного MVC. В этом случае у меня нет идей. – smoksnes

+0

Я обновил пример регистрации Unity для WebAPi с Owin. – smoksnes

0

Установите DependencyResolver в HttpConfiguration, созданной при запуске, не GlobalConfiguration.Configuration и убедитесь, что все ваши конструктору услуги являются общедоступными, надеюсь, что это помогает

0

Убедитесь, что все вложенные типы, которые также инъецируются правильно. Вы получите сообщение об ошибке на уровне контроллера, даже если вложенные типы будут устранены неправильно.

Смежные вопросы

 Смежные вопросы