[英]Castle Windsor ASP.NET MVC 4 and Web API same application. Only if MVC controllers have no dependencies?
本文是使用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(...)
后,我没有注意到我的应用程序有任何改进。
如你看到的。
实现服务定位器:
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);
}
把我带回了起点。
终于解决了。
这是其他人的解决方案
在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<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和web api控制器
container.Register(Classes
.FromAssemblyContaining<HomeController>()
.BasedOn<Controller>()
.LifestylePerWebRequest());
container.Register(Classes
.FromAssemblyContaining<ValuesController>()
.BasedOn<IHttpController>()
.LifestyleScoped());
Microsoft似乎推动将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)。
如果要实现IDependencyResolver接口并将其与框架中的Application_Start: DependencyResolver.SetResolver()连接,WindsorDependencyScope将起作用
为了使它适用于Owin Startup,我重写了HttpConfiguration
的DependencyResolver
[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;
// .......
// .......
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.