无法解析Web Api Controller中的依赖项

Dmi*_*iev 3 c# asp.net castle-windsor asp.net-web-api owin

我和Owin和Windsor有一个Web Api.

得到下一个错误:

发生错误.尝试创建"DBManagerController"类型的控制器时发生错误.确保控制器在System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage)上的System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,类型controllerType)中具有无参数公共构造函数.System.InvalidOperationException.请求)在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()发生错误.类型'Swissphone.SolutionKit.Utilities.DbInit.DataManager.WebHost.Controllers.DBManagerController'没有默认的constructorSystem.ArgumentException at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator的System.Web.Http.Internal.TypeActivator.Create [TBase](Type instanceType)中的System.Linq.Expressions.Expression.New(Type type)(HttpRequestMessage请求,类型为controllerType) System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request,HttpCo),Func`1&activator)ntrollerDescriptor controllerDescriptor,类型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);
    }
}
Run Code Online (Sandbox Code Playgroud)

安装程序:

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>());
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

public class DBManagerController : ApiController
{
    private IDbInitManager _manager;

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

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

我无法解决的课程:

public class DbInitManager : IDbInitManager
{
    public DbInitManager()
    {}
}
Run Code Online (Sandbox Code Playgroud)

在获取控制器请求期间出现错误.无法解析IDbInitManager.

有没有人认为这是错误的,为什么注册依赖没有解决?

Tom*_*uλa 5

不,您没有注册所有依赖项.

基本上,发生的事情是您没有在容器中明确注册控制器.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());
    }
}
Run Code Online (Sandbox Code Playgroud)

必须明确注册必须从Windsor解决的每个依赖项.