2015-03-10 1 views
2

У меня есть веб-Api с owin и Windsor.Не удается разрешить зависимости в Web Api Controller

Получить следующую ошибку:

An error has occurred.An error occurred when trying to create a controller of type 'DBManagerController'. Make sure that the controller has a parameterless public constructor.System.InvalidOperationException at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()An error has occurred.Type 'Swissphone.SolutionKit.Utilities.DbInit.DataManager.WebHost.Controllers.DBManagerController' does not have a default constructorSystem.ArgumentException at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

Это странно, потому что я все зависимости Зарегистрируйтесь.

Вот мой класс запуска:

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var httpContext = HttpContext.Current; 
     var hibernateConfigFileName = string.Empty; 
     if (httpContext != null) 
     { 
      hibernateConfigFileName = httpContext.Server.MapPath(Properties.Settings.Default.HibernateConfigFile); 
     } 
     else 
     { 
      throw new InvalidOperationException("When using IIS hosting, HttpContext.Current must not be NULL"); 
     } 
        var windsorContainer = new WindsorContainer(); 

     windsorContainer.Install(new ContextInstaller(), new DbInitInstaller()); 

     var configuration = new HttpConfiguration() { DependencyResolver = new WindsorResolver(windsorContainer) }; 


     configuration.Routes.MapHttpRoute("DBManager", 
      "api/{controller}/{action}/{id}", 
      new { id = RouteParameter.Optional }); 


     app.UseWebApi(configuration); 
    } 
} 

монтажники:

public class ContextInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      Component.For<IUserContext>().ImplementedBy<UserContext>(), 
      Component.For<ITenantContext>().ImplementedBy<TenantContext>()); 

    } 
} 


public class DbInitInstaller : IDbInitInstaller 
{ 

    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      Component.For<IDbInitManager>().ImplementedBy<DbInitManager>()); 
    } 
} 

Контроллер:

public class DBManagerController : ApiController 
{ 
    private IDbInitManager _manager; 

    public DBManagerController(IDbInitManager manager) 
    { 
     _manager = manager; 
    } 

    [HttpGet] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "value1", "value2" }; 
    } 
} 

класса, что я не могу решительность:

public class DbInitManager : IDbInitManager 
{ 
    public DbInitManager() 
    {} 
} 

Я получаю ошибку во время запроса запроса к контроллеру. Не удается разрешить IDbInitManager.

У кого-нибудь есть идея, что это неправильно и почему зарегистрированная зависимость не разрешена?

ответ

3

Нет, вы не регистрировали все зависимости.

В основном, произошло то, что вы не зарегистрировали свои контроллеры явно в своем контейнере. Windsor пытается разрешить вам незарегистрированные конкретные типы, но поскольку он не может его решить (вызванный ошибкой в ​​вашей конфигурации), он возвращает null. Он вынужден вернуть null, потому что Web API заставляет его делать это из-за контракта IDependencyResolver. Поскольку Windsor возвращает значение null, Web API попытается создать сам контроллер, но поскольку он не имеет конструктора по умолчанию, он выдает исключение «Убедитесь, что контроллер имеет исключение без параметров». Это сообщение об ошибке вводит в заблуждение и не объясняет настоящую причину.

Вы можете добавить еще один инсталлятор для контроллеров:

public class ControllersInstallers : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Classes.FromThisAssembly() 
          .BasedOn<IHttpController>() 
          .LifestylePerWebRequest()); 
    } 
} 

Каждая зависимость, которая должна быть решена с Виндзор должен быть явно зарегистрирован.

+1

Thanx, Thomas. Теперь он работает –