views:

1030

answers:

2

Hi there,

trying to work my way through Steve Sandersons MVC book - but have hit a brick wall when creating the WindsorControllerFactory. It looks as though the method has changed from MVC1 to MVC2. This is the error I'm getting when trying to compile the project:

'WebUI.WindsorControllerFactory.GetControllerInstance(System.Type: no suitable method found to override'. Any help would be appreciated - I can't get past this!

This is the code - as transcribed from the book:

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;
using Castle.MicroKernel;
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);
        }
    }
}

++++ Regards, Martin

A: 

In MVC2, the signature of this method is as follows:

protected internal virtual IController GetControllerInstance(
    RequestContext requestContext,
    Type controllerType
)

(Taken from MSDN.)

David M
Wow - that was quick! Thanks. But...Now I'm getting the following error:'WebUI.WindsorControllrtFactory.GetControllerInstance(System.Web.Routing.RequestContext, System.Type)' must declare a body because it is not marked abstract, extern, or partialAny ideas?
Spudhead
Post the corrected code - you have a typo...
David M
I know, sorry - the:protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType) { return (IController)container.Resolve(controllerType); }fixed the issue - thanks.
Spudhead
+8  A: 

The GetControllerInstance changed from ASP.NET MVC 1.0 to ASP.NET MVC 2 due to an unfortunate bug regarding race conditions.

The signature in ASP.NET MVC 1.0 was:

protected virtual IController GetControllerInstance(
    Type controllerType);

And in ASP.NET MVC 2 it is:

protected virtual IController GetControllerInstance(
    RequestContext requestContext,
    Type controllerType)

For this particular case it looks like you'll only have to change the signature of your method to:

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType) 
    { 
        return (IController)container.Resolve(controllerType); 
    } 

The underlying race condition was that the RequestContext instance could be shared by multiple simultaneous requests, which would be a major no-no. Fortunately it didn't seem like any users ran into that issue, but it was fixed anyway in ASP.NET MVC 2.

Eilon
That did it - I can't thank you enough! I've been going bonker for hours trying to find a way to fix it! Brilliant, many thanks.
Spudhead
+1 - thanks for the explanation of the race condition
David M