This article is a good starting point for doing Web API with Castle Windsor, but what if I create a simple MVC controller? It only works if there is no dependency into the inject.
Adding this one, i.e.:
public class HomeController : Controller
{
private readonly IValuesRepository repository;
public HomeController(IValuesRepository repository)
{
this.repository = repository;
}
public ActionResult Index()
{
return View();
}
}
Causes the following error :
parameterless constructor defined for this object
Is there a way to have MVC and Web API logic in a same application using Castle Windsor?
After setting DependencyResolver.SetResolver(...)
in application_start
, I didn't notice any improvement in my application.
As you can see.
Implementing the service locator :
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);
}
took me back to the starting point.
Finally solved.
Here's the solution for someone else
In 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();
}
}
And the registration for both mvc and web api controller
container.Register(Classes
.FromAssemblyContaining<HomeController>()
.BasedOn<Controller>()
.LifestylePerWebRequest());
container.Register(Classes
.FromAssemblyContaining<ValuesController>()
.BasedOn<IHttpController>()
.LifestyleScoped());