views:

1055

answers:

2

I have an app, modelled on the one from Apress Pro ASP.NET MVC that uses castle windsor's IoC to instantiate the controllers with their respective repositories, and this is working fine

e.g.

public class ItemController : Controller
{
    private IItemsRepository itemsRepository;
    public ItemController(IItemsRepository windsorItemsRepository)
    {
        this.itemsRepository = windsorItemsRepository;
    }

with

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using Castle.Core.Resource;
using System.Reflection;
using Castle.Core;

namespace WebUI
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        WindsorContainer container;

        // The constructor:
        // 1. Sets up a new IoC container
        // 2. Registers all components specified in web.config
        // 3. Registers all controller types as components
        public WindsorControllerFactory()
        {
            // Instantiate a container, taking configuration from web.config
            container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

            // Also register all the controller types as transient
            var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                                  where typeof(IController).IsAssignableFrom(t)
                                  select t;
            foreach (Type t in controllerTypes)
                container.AddComponentWithLifestyle(t.FullName, t, LifestyleType.Transient);
        }

        // Constructs the controller instance needed to service each request
        protected override IController GetControllerInstance(Type controllerType)
        {
            return (IController)container.Resolve(controllerType);
        }
    }
}

controlling the controller creation.

I sometimes need to create other repository instances within controllers, to pick up data from other places, can I do this using the CW IoC, if so then how?

I have been playing around with the creation of new controller classes, as they should auto-register with my existing code (if I can get this working, I can register them properly later) but when I try to instantiate them there is an obvious objection as I can't supply a repos class for the constructor (I was pretty sure that was the wrong way to go about it anyway).

Any help (especially examples) would be much appreciated. Cheers MH

+4  A: 

Just declare your required dependencies in your controller constructor, i.e.:

public class MyController: Controller {
  private readonly IItemsRepository itemsRepo;
  private readonly IPersonRepository personRepo;
  public MyController(IItemsRepository i, IPersonRepository p) {
    itemsRepo = i;
    personRepo = p;
  }
}

Windsor will resolve the dependencies automatically when it instantiates the controller.

There are lots of projects on google code that you can use for guidance, for instance WineCellarManager.

BTW: you don't need to code your own WindsorControllerFactory, you can get that (and a lot more) from MVCContrib

Mauricio Scheffer
That's not always practical, for example in the object validation rules I need to check any part numbers added against the main DB - it is better to do this in the object as it keeps the business logic out of the controllers, but the object doesn't have a repos (nor do I really want to create one, unless I need to check the data)
Mad Halfling
Validation has nothing to do with this... please create another question for that
Mauricio Scheffer
It does, because in my validation rules I need access to the database repos.
Mad Halfling
It's not related to wiring controllers and services with Windsor. It's more a design question than a how-to question. Please create another question...
Mauricio Scheffer