Castle Windsor ASP.NET MVC 4和Web API相同的应用程序。 只有MVC控制器没有依赖关系?

本文是使用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逻辑?

application_start设置DependencyResolver.SetResolver(...)之后,我没有注意到我的应用程序有任何改进。

如你看到的。

WebApiScopedLifetimeDependencyResolverSample.Windsor.WindsorDependencyResolver类型似乎没有实现

实现服务定位器:

 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 GetServices(Type t) { return this.container.ResolveAll(t) .Cast().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 DoGetAllInstances( Type serviceType) { return (object[])container.ResolveAll(serviceType); } 

把我带回了起点。

终于解决了。

这是其他人的解决方案


在application_start中……

 //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 GetServices(Type t) { return this.container.ResolveAll(t) .Cast().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 GetServices(Type t) { return this.container.ResolveAll(t) .Cast().ToArray(); } public void Dispose() { this.scope.Dispose(); } } 

并注册了mvc和web api控制器

 container.Register(Classes .FromAssemblyContaining() .BasedOn() .LifestylePerWebRequest()); container.Register(Classes .FromAssemblyContaining() .BasedOn() .LifestyleScoped()); 

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

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

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

如果您正在实现IDependencyResolver接口并将其与框架中的Application_Start: DependencyResolver.SetResolver()连接起来,WindsorDependencyScope将起作用

为了使它适用于Owin Startup,我重写了HttpConfigurationDependencyResolver

 [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; // ....... // ....... } } }