C# Castle Windsor ASP.NET MVC 4和Web API应用程序相同。仅当MVC控制器没有依赖项时?

C# Castle Windsor ASP.NET MVC 4和Web API应用程序相同。仅当MVC控制器没有依赖项时?,c#,asp.net,asp.net-mvc-4,asp.net-web-api,castle-windsor,C#,Asp.net,Asp.net Mvc 4,Asp.net Web Api,Castle Windsor,这是使用Castle Windsor开发Web API的一个很好的起点,但是如果我创建一个简单的MVC控制器呢?只有在注入中没有依赖项时,它才起作用 添加此项,即: public class HomeController : Controller { private readonly IValuesRepository repository; public HomeController(IValuesRepository repository) { th

这是使用Castle Windsor开发Web API的一个很好的起点,但是如果我创建一个简单的MVC控制器呢?只有在注入中没有依赖项时,它才起作用

添加此项,即:

public class HomeController : Controller
{
    private readonly IValuesRepository repository;

    public HomeController(IValuesRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Index()
    {
        return View();
    }
}
导致以下错误:

为此对象定义的无参数构造函数

使用Castle Windsor是否有办法在同一个应用程序中使用MVC和Web API逻辑

应用程序启动
中设置
DependencyResolver.SetResolver(…)
后,我没有注意到我的应用程序有任何改进

如你所见

实现服务定位器:

internal sealed class WindsorDependencyResolver
    : ServiceLocatorImplBase, IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorDependencyResolver(
        IWindsorContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        this.container = container;
    }

    public object GetService(Type t)
    {
        return this.container.Kernel.HasComponent(t)
             ? this.container.Resolve(t) : null;
    }

    public IEnumerable<object> GetServices(Type t)
    {
        return this.container.ResolveAll(t)
            .Cast<object>().ToArray();
    }

    public IDependencyScope BeginScope()
    {
        return new WindsorDependencyScope(this.container);
    }

    public void Dispose()
    {
    }

    protected override object DoGetInstance(
        Type serviceType, string key)
    {
        if (key != null)
            return container.Resolve(key, serviceType);
        return container.Resolve(serviceType);
    }

    protected override IEnumerable<object> DoGetAllInstances(
        Type serviceType)
    {
        return (object[])container.ResolveAll(serviceType);
    }
内部密封级风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡风挡
:ServiceLocatorImplBase,IDependencyResolver
{
私有只读IWindsorContainer;
公共风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机风机(
Iwindsor(集装箱)
{
if(容器==null)
{
抛出新的ArgumentNullException(“容器”);
}
this.container=容器;
}
公共对象GetService(类型t)
{
返回此.container.Kernel.HasComponent(t)
?this.container.Resolve(t):null;
}
公共IEnumerable GetServices(t型)
{
返回此.container.ResolveAll(t)
.Cast().ToArray();
}
公共IDependencyScope BeginScope()
{
返回新的WindsorDependencyScope(此容器);
}
公共空间处置()
{
}
受保护的覆盖对象(
类型(服务类型,字符串键)
{
if(key!=null)
返回container.Resolve(key,serviceType);
返回容器解析(serviceType);
}
受保护的覆盖IEnumerable DogetAlliance(
类型(服务类型)
{
return(object[])container.ResolveAll(serviceType);
}
带我回到起点

最终解决。

这是其他人的解决方案


在应用程序启动中

//mvc
DependencyResolver.SetResolver(
    new WindsorMvcDependencyResolver(container));

// web api:
var httpDependencyResolver = 
    new WindsorHttpDependencyResolver(container);

GlobalConfiguration.Configuration.DependencyResolver =
    httpDependencyResolver;

internal class WindsorMvcDependencyResolver
    : WindsorDependencyScope, IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorMvcDependencyResolver(
        IWindsorContainer container) : base(container)
    {
        this.container = container;
    }
}


internal sealed class WindsorHttpDependencyResolver
    : IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorHttpDependencyResolver(
        IWindsorContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        this.container = container;
    }

    public object GetService(Type t)
    {
        return this.container.Kernel.HasComponent(t)
             ? this.container.Resolve(t) : null;
    }

    public IEnumerable<object> GetServices(Type t)
    {
        return this.container.ResolveAll(t)
            .Cast<object>().ToArray();
    }

    public IDependencyScope BeginScope()
    {
        return new WindsorDependencyScope(this.container);
    }

    public void Dispose()
    {
    }
}

internal class WindsorDependencyScope : IDependencyScope
{
    private readonly IWindsorContainer container;
    private readonly IDisposable scope;

    public WindsorDependencyScope(
        IWindsorContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }

        this.container = container;
        this.scope = container.BeginScope();
    }

    public object GetService(Type t)
    {
        return this.container.Kernel.HasComponent(t) 
            ? this.container.Resolve(t) : null;
    }

    public IEnumerable<object> GetServices(Type t)
    {
        return this.container.ResolveAll(t)
            .Cast<object>().ToArray();
    }

    public void Dispose()
    {
        this.scope.Dispose();
    }
}
//mvc
DependencyResolver.SetResolver(
新温莎MVCDependencyresolver(集装箱);
//web api:
var httpDependencyResolver=
新WindsorHttpDependencyResolver(容器);
GlobalConfiguration.Configuration.DependencyResolver=
httpdependencyrolver;
内部类WindsorMvcDependencyResolver
:WindsorDependencyScope,IDependencyResolver
{
私有只读IWindsorContainer;
公共WindsorMvcDependencyResolver(
IWindsorContainer(容器):基础(容器)
{
this.container=容器;
}
}
内部密封类WindsorHttpDependencyResolver
:IDependencyResolver
{
私有只读IWindsorContainer;
公共WindsorHttpDependencyResolver(
Iwindsor(集装箱)
{
if(容器==null)
{
抛出新的ArgumentNullException(“容器”);
}
this.container=容器;
}
公共对象GetService(类型t)
{
返回此.container.Kernel.HasComponent(t)
?this.container.Resolve(t):null;
}
公共IEnumerable GetServices(t型)
{
返回此.container.ResolveAll(t)
.Cast().ToArray();
}
公共IDependencyScope BeginScope()
{
返回新的WindsorDependencyScope(此容器);
}
公共空间处置()
{
}
}
内部类WindsorDependencyScope:IDependencyScope
{
私有只读IWindsorContainer;
私有只读IDisposable作用域;
公共风向仪(
Iwindsor(集装箱)
{
if(容器==null)
{
抛出新的ArgumentNullException(“容器”);
}
this.container=容器;
this.scope=container.BeginScope();
}
公共对象GetService(类型t)
{
返回此.container.Kernel.HasComponent(t)
?this.container.Resolve(t):null;
}
公共IEnumerable GetServices(t型)
{
返回此.container.ResolveAll(t)
.Cast().ToArray();
}
公共空间处置()
{
this.scope.Dispose();
}
}
以及mvc和web api控制器的注册

container.Register(Classes
    .FromAssemblyContaining<HomeController>()
    .BasedOn<Controller>()
    .LifestylePerWebRequest());


container.Register(Classes
    .FromAssemblyContaining<ValuesController>()
    .BasedOn<IHttpController>()
    .LifestyleScoped());
container.Register(类)
.FromAssemblyContaining()
.BasedOn()
.LifestylePerWebRequest());
容器.寄存器(类)
.FromAssemblyContaining()
.BasedOn()
.lifestylescope());

如果您正在实现IDependencyResolver接口并将其与应用程序中的框架连接起来,WindsorDependencyScope将起作用。\u开始:

微软似乎在推动将Web API与MVC应用程序放在同一个项目中(由他们使用的模板引起)。但是,我不会将Web API和MVC应用程序混合到同一个项目/网站中。很可能需求和(DI)配置需要不同,这将使试图使用单个容器配置解决此问题的一切变得复杂

因此,尽管MVC和Web API完全可以在同一个应用程序中运行,也可以在单个容器中运行,但我的建议是:不要这样做。不仅从技术角度,而且从功能角度来看。Web API是一种Web服务。您也不会在同一个项目中混合使用MVC和WCF


但是如果你真的想注册,你只需要注册
System.Web.Mvc.DependencyResolver.SetResolver
(对于Mvc)和
System.Web.Http.HttpConfiguration.DependencyResolver
(对于Web API)

[assembly: OwinStartup(typeof(YourCompany.API.Startup))]
namespace YourCompany.API
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            var dependencyResolver = new WindsorHttpDependencyResolver(container);
            config.DependencyResolver = dependencyResolver;
            // ....... 
            // ....... 
        }
    }
}

我大体上同意您的考虑,但应用程序的简单性质—通过rest服务进行交互的intranet客户端应用程序的配置编辑器—使我有机会对此进行试验