Dashboard > MonoRail > Home > How to Enable Windsor integration
Log In   View a printable version of the current page.
How to Enable Windsor integration
Added by Gauthier Segay, last edited by Brian Chan on May 12, 2008  (view change)
Labels: 


By enabling Windsor Container integration, your controllers and filters might request dependencies that can be satisfied by the container, thus leading your design to a loosely coupled architecture.

Table of contents

  • Necessary assemblies on the web project
  • Web.config
  • Global.asax
  • Container set up
  • Benefits
    • specific configuration for a controller

Necessary assemblies on the web project

Make your web project reference the following assemblies:

  • Castle.DynamicProxy.dll
  • Castle.Model.dll
  • Castle.MicroKernel.dll
  • Castle.Windsor.dll
  • Castle.MonoRail.WindsorExtension.dll

Web.config

Use the useWindsorIntegration attribute:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="monoRail"
                 type="Castle.MonoRail.Engine.Configuration.MonoRailSectionHandler, Castle.MonoRail.Engine" />
        <section name="castle"
                 type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
    </configSections>

    <monoRail useWindsorIntegration="true">
        <viewEngine
          viewPathRoot="views"
          customEngine="Castle.MonoRail.Framework.Views.NVelocity.NVelocityViewEngine, Castle.MonoRail.Framework.Views.NVelocity" />
    </monoRail>
    <castle>
      <!-- component and facilities configuration goes here -->
    </castle>
</configuration>

Global.asax

You must make your container available to the web application. The best place for it is the global.asax:

~/global.asax
<%@ Application Inherits="YourApp.Web.HttpApplication"  %>
~/src/HttpApplication.cs
namespace YourApp.Web {
    using System;
    using System.Web;

    using Castle.Windsor;
    using Castle.ActiveRecord;

    public class HttpApplication : HttpApplication, IContainerAccessor
    {
        private static WebAppContainer container;

        public void Application_OnStart()
        {
            container = new WebAppContainer();
        }

        public void Application_OnEnd()
        {
            container.Dispose();
        }

        public IWindsorContainer Container
        {
            get { return container; }
        }
    }
}

Container set up

You must register a facility named MonoRailFacility.

It ensures that the lifestyle of each controller is set to Transient - as using the default, singleton, would be a terrible mistake and register each component/controller on the ControllerTree.

Also note that from now on, your controllers (and optionally the filters) are standard components, and need to be registered on the container

~/src/WebAppContainer.cs
{
    using System;

    using YourApp.Web.Controllers;

    using Castle.Model.Resource;
    using Castle.Windsor.Configuration.Interpreters;
    using Castle.MonoRail.WindsorExtension;

    public class WebAppContainer : AppContainer
    {
        public WebAppContainer() : base( new XmlInterpreter( new ConfigResource() ) )
        {
        }

        protected override void RegisterFacilities()
        {
            base.RegisterFacilities();

            AddFacility( "rails", new MonoRailFacility() );
        }

        protected override void RegisterComponents()
        {
            base.RegisterComponents();

            AddComponent( "home.controller", typeof(HomeController) );
        }
    }
}

Benefits

From this point your controllers and filters can use the container auto-wiring capabilities.

A specific configuration for a controller

Suppose you have a controller that receives files uploads. Where should it store the files? Make it configurable!

On the controller

public class ImageGalleryController : Controller
{
  ...

  public ImageGalleryController(String imageDirectory)
  {
    this.imageDirectory = imageDirectory;
  }

  ...
}

Let's assume that this controller was registered on the container with the key imagegallery.controller. On the configuration section:

<castle>
  <components>
    <component id="imagegallery.controller">
      <parameters>
        <imageDirectory>C:\mytempdir\safedir</imageDirectory>
      </parameters>
    </component>
  <components>
</castle>

Your controller could assume a default directory and allow it to be overriden as well

public class ImageGalleryController : Controller
{
  private String imageDirectory = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData );

  public ImageGalleryController()
  {
  }

  public string ImageDirectory
  {
    get { return imageDirectory; }
    set { imageDirectory = value; }
  }

  ...
}

The previous configuration for the component still valid. But now it's optional as the controller can live without it.

Instead of calling AddComponent for each controller, you could call:

protected void RegisterComponents(){
		Register(
AllTypes.Of<IController>().FromAssembly(Assembly.GetExecutingAssembly()));

}
Posted by nelsonmichael at Jul 09, 2008 12:55; last updated at Jul 09, 2008 15:47
Site running on a free Atlassian Confluence Community License granted to Castle Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.4 Build:#809 Jun 12, 2007) - Bug/feature request - Contact Administrators