这篇文章是使用 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(...)
后application_start
,我没有注意到我的应用程序有任何改进。
如你看到的。
实现服务定位器:
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());