Breaking change in asp.net mvc v2 (2.0.0.0) for MvcContrib.Castle’s WindsorControllerFactory class

posted by ercu

I could not find anything related to this anywhere, but if you know there is a simple but breaking change in asp.net mvc version 2.0.0.0’s DefaultControllerFactory, so WindsorContainerFactory got broken.

Because it could not get the instance of controller from controller factory, I kept getting the following error everytime i loaded my fresh web project built with asp.net mvc v2.

No parameterless constructor defined for this object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

While searching for a solution around the web, I found the following lines in the release notes of mvc version 2:

DefaultControllerFactory API changes will break custom controller factories that derive from it
This change affects custom controller factories that derive from DefaultControllerFactory . The DefaultControllerFactory class was fixed by removing the RequestContext property and instead passing the request context instance to the protected virtual methods GetControllerInstance and GetControllerType.

So I just fetched latest MvcContrib source, changed GetControllerInstance found in WindsorContainerFactory.cs to work with latest mvc library by taking RequestContext as parameter. I rewrote  the function as follows.

1 using System;

2 using System.Web;

3 using System.Web.Mvc;

4 using System.Web.Routing;

5 using Castle.Windsor;

6

7 namespace MvcContrib.Castle

8 {

9 /// <summary>

10 /// Controller Factory class for instantiating controllers using the Windsor IoC container.

11 /// </summary>

12 public class WindsorControllerFactory : DefaultControllerFactory

13 {

14 private IWindsorContainer _container;

15

16 /// <summary>

17 /// Creates a new instance of the <see cref=”WindsorControllerFactory”/> class.

18 /// </summary>

19 /// <param name=”container”>The Windsor container instance to use when creating controllers.</param>

20 public WindsorControllerFactory(IWindsorContainer container)

21 {

22 if (container == null)

23 {

24 throw new ArgumentNullException(“container”);

25 }

26 _container = container;

27 }

28

29 /// <summary>

30 /// This is an original code in “MvcContrib.Castle.WindsorControllerFactory”

31 /// </summary>

32 //protected override IController GetControllerInstance(RequestContext context, Type controllerType)

33 //{

34 //    if (controllerType == null)

35 //    {

36 //        throw new HttpException(404, string.Format(“The controller for path ‘{0}’ could not be found or it does not implement IController.”, context.HttpContext.Request.Path));

37 //    }

38

39 //    return (IController)_container.Resolve(controllerType);

40 //}

41

42

43 /// <summary>

44 /// This is a code replacement

45 /// </summary>

46 protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

47 {

48 if (controllerType == null)

49 {

50 throw new HttpException(404, string.Format(“The controller for path ‘{0}’ could not be found or it does not implement IController.”, requestContext.HttpContext.Request.Path));

51 }

52

53 return (IController)_container.Resolve(controllerType);

54 }

55

56

57 public override void ReleaseController(IController controller)

58 {

59 var disposable = controller as IDisposable;

60

61 if (disposable != null) {

62 disposable.Dispose();

63 }

64

65 _container.Release(controller);

66 }

67 }

68 }

The only change is

from

protected override IController GetControllerInstance(RequestContext context, Type controllerType)

to

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

Note:

1 – You must download the MvcContrib source code, and find this class as image below

2 – Rebuild this project and copy to your project bin folder

Then it worked as I expected. Hope this helps anyone.

Thanks ercu for this post

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s