Configure Inverse Control (IoC) in ASP.NET MVC with Castle Windsor

I move on to the Sanderson Pro ASP.NET MVC Framework, and in chapter 4 he discusses Creating a Custom Factory Controller , and it seems that the original AddComponentLifeStyle or AddComponentWithLifeStyle method used to register the controllers is now deprecated:

 public class WindsorControllerFactory : DefaultControllerFactory { IWindsorContainer container; public WindsorControllerFactory() { container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); // register all the controller types as transient var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes() where typeof(IController).IsAssignableFrom(t) select t; //[Obsolete("Use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) instead.")] //IWindsorContainer AddComponentLifeStyle<I, T>(string key, LifestyleType lifestyle) where T : class; foreach (Type t in controllerTypes) { container.Register(Component.For<IController>().ImplementedBy<???>().Named(t.FullName).LifeStyle.Is(LifestyleType.Transient)); } } // Constructs the controller instance needed to service each request protected override IController GetControllerInstance(Type controllerType) { return (IController)container.Resolve(controllerType); } } 

A new suggestion is to use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) , but I cannot figure out how to represent the type of implementation controller in the ImplementedBy<???>() . I tried ImplementedBy<t>() and ImplementedBy<typeof(t)>() , but I cannot find a suitable way to pass the implementation type. Any ideas?

+8
reflection asp.net-mvc inversion-of-control castle-windsor
source share
5 answers

I do this with ControllerBuilder.SetControllerFactory and the code that you can find in the open source project MvcContrib :

Global.asax.cs

 protected void Application_Start() { ... IWindsorContainer windsorContainer = new WindsorContainer(); windsorContainer.RegisterControllers(Assembly.GetExecutingAssembly()); ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(windsorContainer)); ... } 

WindsorControllerFactory

 public class WindsorControllerFactory : DefaultControllerFactory { private readonly IWindsorContainer _container; public WindsorControllerFactory(IWindsorContainer container) { if (container == null) { throw new ArgumentNullException(); } _container = container; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (controllerType == null) { throw new HttpException(); } if (!typeof(IController).IsAssignableFrom(controllerType)) { throw new ArgumentException(); } try { return (IController)_container.Resolve(controllerType); } catch (Exception ex) { throw new InvalidOperationException(); } } public override void ReleaseController(IController controller) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } _container.Release(controller); } } 

WindsorExtensions (see MvcContrib )

 public static class WindsorExtensions { public static IWindsorContainer RegisterController<T>(this IWindsorContainer container) where T : IController { container.RegisterControllers(typeof(T)); return container; } public static IWindsorContainer RegisterControllers(this IWindsorContainer container, params Type[] controllerTypes) { foreach (Type type in controllerTypes) { if (ControllerExtensions.IsController(type)) { container.Register(Component.For(type).Named(type.FullName).LifeStyle.Is(LifestyleType.Transient)); } } return container; } public static IWindsorContainer RegisterControllers(this IWindsorContainer container, params Assembly[] assemblies) { foreach (Assembly assembly in assemblies) { container.RegisterControllers(assembly.GetExportedTypes()); } return container; } } 

Control Extensions (see MvcContrib )

 public static class ControllerExtensions { public static bool IsController(Type type) { return type != null && type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) && !type.IsAbstract && typeof(IController).IsAssignableFrom(type); } } 
+6
source share

You may also consider using the new installer option in the latest version of Windsor. There is more Windsor tutorial documentation: http://stw.castleproject.org/Windsor.Windsor-tutorial-part-three-writing-your-first-installer.ashx

+2
source share

There's a tutorial (in work, but 9 parts already out) that discusses using Windsor in ASP.NET MVC here . This is most relevant and covers most common usage resources on this topic, as far as I know.

+1
source share

@Lirik, as a complement: drop your own IControllerFactory if you are using MVC3. Just register controllers with Windsor and implement IDependencyResolver with the Windsor container inside.

Set IDependencyResolver as MVC DependencyResolver and DefaultControllerFactory will automatically connect the controllers registered in the container (via DependencyResolver ).

+1
source share

something like:

 public void Register(IWindsorContainer container) { Assembly.GetAssembly(typeof(ControllersRegistrarMarker)).GetExportedTypes() .Where(IsController) .Each(type => container.AddComponentLifeStyle( type.Name.ToLower(), type, LifestyleType.Transient)); } 

Registrarmarkers are just an empty class in your controller assembly

-one
source share

All Articles