MVC v2 Preview 2 Areas, Spring IOC and McvContrib SpringControllerFactory

10 views
Skip to first unread message

Chad

unread,
Oct 30, 2009, 1:25:17 PM10/30/09
to mvccontrib-discuss
Hello,

I've been playing around with MVC v2 (Preview 2) Areas and was running
into some problem using the MvcContrib SpringControllerFactory.
Namely, if you have two areas both of which contain a controller with
the same name --e.g., "Login", Spring was not able to resolve the
correct controller. A small change to the MvcContrib
SpringControllerFactory fixed it which I've posted below in case
anyone else has this issue. (No doubt it something like it will be
folded into McvContrib at some point so this is really just intended
to a temporary fix.)

Hope it helps,

Chad Finsterwald
http://www.blueskycollaborative.com/

New SpringControllerFactory. The changes are to the CreateController
method where I added some simple support for areas.

using System;
using System.Web.Mvc;
using System.Web.Routing;
using Spring.Context;
using Spring.Objects.Factory;

namespace MvcContrib.Spring
{
/// <summary>
/// Controller Factory implementation for Spring.net
/// </summary>
public class SpringControllerFactory : IControllerFactory
{
private static IObjectFactory _objectFactory;

/// <summary>
/// Configures the controller factory to use the
/// given spring.net IObjectFactory for controller lookup.
/// If you call Configure multiple times, the last call will
prevail.
/// </summary>
/// <param name="objectFactory">IObjectFactory instance to use
for lookups.</param>
public static void Configure(IObjectFactory objectFactory)
{
_objectFactory = objectFactory;
}

/// <summary>
/// Configures the controller factory to use the
/// given spring.net IApplicationContext for controller
/// lookup. If you call Configure multiple times, the
/// last call will prevail.
/// </summary>
/// <param name="ctx"></param>
public static void Configure(IApplicationContext ctx)
{
_objectFactory = ctx;
}

public IController CreateController(RequestContext context,
string controllerName)
{
if (string.IsNullOrEmpty(controllerName))
throw new ArgumentNullException("controllerName");

string area = string.Empty;
if (context.RouteData.DataTokens.ContainsKey("area"))
{
area = context.RouteData.DataTokens["area"].ToString() ;
}

controllerName = area + controllerName + "Controller";

if (_objectFactory == null)
{
throw new ArgumentException("CreateController has been
called before Configure.");
}

try
{
return (IController)_objectFactory.GetObject
(controllerName);
}
catch (Exception e)
{
throw new InvalidOperationException("Failed creating
instance of: " +
controllerName + " using
spring.net object factory", e);
}
}

public void ReleaseController(IController controller)
{
var disposable = controller as IDisposable;

if (disposable != null)
{
disposable.Dispose();
}
}
}
}


Spring IOC set-up. Note the convention I've used is to prepend the
name of the area in front of the controller, --e.g. given two area
with the names "Administration" and "Participant" both with a
controller called Login I used the following:
AdministrationLoginController and ParticipantLoginController.

<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<!-- Controllers -->
<object id="HomeController" sing
<object id="SearchController" singleton="false"
type="Main.Controllers.SearchController"/>
<object id="SponsorsController" singleton="false"
type="Main.Controllers.SponsorsController"/>
<object id="ParticipantLoginController" singleton="false"
type="Participant.Controllers.LoginController"/>
<object id="AdministrationLoginController" singleton="false"
type="Administration.Controllers.LoginController"/>
<!-- End Controllers -->
</objects>
</spring>

Jeremy Skinner

unread,
Oct 31, 2009, 9:25:56 AM10/31/09
to mvccontri...@googlegroups.com
Thanks for this - it is a good interim solution.

My intention is to change all of the existing controller factories to inherit from the built-in DefaultControllerFactory. This way, they will all automatically gain the correct behaviour for dealing with areas.

Jeremy

2009/10/30 Chad <chad.fin...@gmail.com>

Jeremy Skinner

unread,
Oct 31, 2009, 9:38:04 AM10/31/09
to mvccontri...@googlegroups.com
...actually, thinking about this further this probably won't work for Spring. The DefaultControllerFactory assumes resolution by type, but IIRC Spring only supports creating instances by name, not type (ugh). I'll just build in your solution instead.

Jeremy


2009/10/31 Jeremy Skinner <jer...@jeremyskinner.co.uk>

Eric Hexter

unread,
Oct 31, 2009, 10:16:47 AM10/31/09
to mvccontri...@googlegroups.com
#fail

Chad

unread,
Nov 1, 2009, 2:59:54 PM11/1/09
to mvccontrib-discuss
Glad it was a help.

On Oct 31, 8:38 am, Jeremy Skinner <jer...@jeremyskinner.co.uk> wrote:
> ...actually, thinking about this further this probably won't work for
> Spring. The DefaultControllerFactory assumes resolution by type, but IIRC
> Spring only supports creating instances by name, not type (ugh). I'll just
> build in your solution instead.
>
> Jeremy
>
> 2009/10/31 Jeremy Skinner <jer...@jeremyskinner.co.uk>
>
> > Thanks for this - it is a good interim solution.
>
> > My intention is to change all of the existing controller factories to
> > inherit from the built-in DefaultControllerFactory. This way, they will all
> > automatically gain the correct behaviour for dealing with areas.
>
> > Jeremy
>
> > 2009/10/30 Chad <chad.finsterw...@gmail.com>
Reply all
Reply to author
Forward
Message has been deleted
0 new messages