3

Я застрял со странной ситуацией. Я следую Onion Architecture и моя архитектура нечто вроде этого:Простой инжектор - убедитесь, что контроллер имеет беззаторный публичный конструктор при производстве

1-Core 
    - Domain Classes 
    - Repository Interfaces 
    - Service Interfaces 
2-Infrastructure 
    - Data 
    - Dependency Injection // Here I am using Simple Injector as dependency injection 
    - Repository Interfaces Implementation 
    - Service Interfaces Implementation 
3-WebApi 
    - Web Api Project 
4-WebClient 
    - My AngularJs App 
5-Test 
    - Test Project 

Dependency Injection:

[assembly: PreApplicationStartMethod(typeof(IocConfig), "RegisterDependencies")] 
namespace Infrastructure.DependencyResolution 
{ 
    public class IocConfig 
    { 
     public static void RegisterDependencies() 
     { 
      var container = new Container(); 

      container.RegisterWebApiRequest<IRepositoryAsync<Category>, Repository<Category>>(); 
      container.RegisterWebApiRequest<ICategoryService, CategoryService>(); 
      container.RegisterWebApiRequest<IDataContextAsync>(() => new MyContext()); 
      container.Verify(); 
      GlobalConfiguration.Configuration.DependencyResolver = 
      new SimpleInjectorWebApiDependencyResolver(container); 

     } 
    } 
} 

Web Api Project:

public class HomeController : ApiController 
{ 
    private readonly ICategoryService _categoryService; 
    public HomeController(ICategoryService categoryService) 
    { 
     _categoryService = categoryService; 
    } 
} 

Все работает очень хорошо на мой local IIS. Но теперь я опубликовал это приложение на сервере, и теперь он дает мне ошибку ниже:

{"message":"An error has occurred.","exceptionMessage":"An error occurred when trying to create a controller of type 'HomeController'. Make sure that the controller has a parameterless public constructor.","exceptionType":"System.InvalidOperationException","stackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()","innerException":{"message":"An error has occurred.","exceptionMessage":"Type 'JetAdz.WebApi.Controllers.HomeController' does not have a default constructor","exceptionType":"System.ArgumentException","stackTrace":" at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"}}

ответ

7

Пожалуйста, взгляните на внутреннее исключение исключенного броска. В нем содержатся детали, описывающие, почему это происходит.

Здесь есть несколько проблем. Вы должны убедиться, что вы зарегистрировали все ваши типы корней явно в контейнере. Контроллеры являются корневыми типами, потому что они разрешены напрямую (от них ничего не зависит, но они имеют зависимости). Если вы не зарегистрируете их явно, контейнер не может проверить, могут ли они быть созданы при вызове Verify(). Вы можете зарегистрировать свои контроллеры по телефону следующее:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 

Это описано в the documentation.

После этого вы, вероятно, непосредственно видите способ Verify() сбой при запуске приложения, и в этом случае вы получите очень подробное сообщение, объясняющее, что происходит не так.

Из внутреннего исключения вы можете видеть, что метод веб-API DefaultHttpControllerActivator.GetInstanceOrActivator вызывает TypeActivator.Create<T>(Type). Это происходит только тогда, когда звонок request.GetDependencyScope().GetService(controllerType) возвращает null. Но это, как правило, то, что не может произойти, если вы подключились к SimpleInjectorWebApiDependencyResolver в конвейер веб-API. Это связано с тем, что SimpleInjectorWebApiDependencyResolver никогда не вернет null, когда требуется разрешение IHttpController. Вместо этого он генерирует исключение, когда контроллер не может быть разрешен.

Так что это для меня указание проблемы перенаправления привязки в вашем приложении. Это означает, что SimpleInjector.Integration.WebApi.dll ссылается на другую версию IHttpController, чем то, что использует ваше приложение. Связывание переадресаций предназначено для решения этой проблемы, поэтому убедитесь, что ваше приложение имеет правильное связывание. Для System.Web.Http.DLL это выглядит следующим образом (но учтите, что вам могут понадобиться другие привязки, а):

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    ... 
    <dependentAssembly> 
     <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" 
      culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" /> 
    </dependentAssembly> 
    </assemblyBinding> 
</runtime> 

Обычно переплеты управляется менеджером пакетов NuGet, но он не в состоянии сделать это на регулярной основе.

Когда проблема переадресации привязки исправлена, вы увидите, что внутреннее исключение содержит информацию, поступающую от Simple Injector, с той же информацией, которую вы увидите при вызове Verify().

+0

Как я могу увидеть внутреннее исключение на рабочем сервере? –

+0

В файле журнала. – Steven

+0

Я получил эту ошибку из файла журнала. –

5

Вы не регистрируете правильный DependencyResolver для WebAPI. Согласно WebApi Dependency Injection page и Simple Injector WebApi page, это должно быть сделано следующим образом.

public static void Register(HttpConfiguration config) 
{ 
    var container = new Container(); 

    container.RegisterWebApiRequest<IRepositoryAsync<Category>, Repository<Category>>(); 
    container.RegisterWebApiRequest<ICategoryService, CategoryService>(); 
    container.RegisterWebApiRequest<IDataContextAsync>(() => new MyContext()); 
    container.Verify(); 

    config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 

    // Other Web API configuration not shown. 
} 

Указанная вами конфигурация предназначена для инъекций зависимостей MVC (которые также могут понадобиться).

+0

Это кажется интересным, но тогда почему он отлично работает на моем локальном iis. –

+0

Возможно, потому, что он работает в классическом режиме. – NightOwl888

+0

Это не решило проблему. –

0

Я использую весенние файлы XML для ввода переменных в свои классы. В моем случае это была ошибка копирования/вставки, когда я создал новый контроллер.

Так что, хотя это не совсем связано с проблемой ОП, оно получает то же сообщение об ошибке и мою помощь кому-то еще.

я скопированная (угловые скобки изменены квадратные скобки):

[object id="className" type="Project.ClassName" scope="request"] 
    [constructor-arg name="OtherClassName" ref="otherclassName"/] 
[/object] 

когда то, что мне было нужно:

[object id="className" type="Project.ClassName" scope="request"] 
    [property name="OtherClassName" ref="otherclassName"/] 
[/object] 

Обратите внимание на свойстве вместо конструктора-Arg.

Поскольку у моего класса не было конструктора, ищущего параметр.

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

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