I have a controller factory which depending on the route values builds a controller in different ways. These are:
- If the route values match with a “module” route it determines the correct type using the route values to calculate the qualified type name. This is, if user types [http://localhost:8080/siijyp/modules/Personas/Naturales/Documento/Display?id=1], the controller factory builds and returns an OIMSIIJYP.Web.*Personas.Naturales.Documento*Controller
- If the route values match with a “module” route and it also contains a “script” value, the controller factory builds the controller in runtime using Mono.CSharp
- If the route values don´t match with a module, it builds the controller as the
DefaultControllerFactorydoes it.
It is rather evident all these if statements are wrong, I also know there is a IControllerActivator type which is used for the DefaultControllerFactory to create a controller given a controller type. But what I don´t know is which is the best way to implement these controller creation strategies in MVC 3.
Any idea?
The code:
public IController CreateController(RequestContext requestContext,
string controllerName)
{
#region Argument checking
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
if (string.IsNullOrEmpty(controllerName))
{
throw new ArgumentException(
"ControllerName cannot be null nor empty",
"controllerName");
}
#endregion
Type controllerType = null;
var routeData = requestContext.RouteData;
if (IsRequestingAModule(routeData))
{
var module = routeData.Values["module"];
var submodule = routeData.Values["submodule"];
var controllerQualifiedName = string.Format(
"OIMSIIJYP.Web.{0}.{1}.{2}Controller", module,
submodule, controllerName);
try
{
controllerType = Type.GetType(controllerQualifiedName, true,
true);
if (IsRequestingAScriptingBehavior(routeData))
{
return GetControllerRuntimeUsingMono(routeData,
controllerName, controllerType);
}
else
{
return _container.Resolve(controllerType) as IController;
}
}
catch (TypeLoadException)
{
throw new HttpException(404,
string.Format(CultureInfo.CurrentCulture,
"Controller not fount", new object[] {
requestContext.HttpContext.Request.Path
}));
}
}
else
{
var controllerTypes =
from type in Assembly.GetExecutingAssembly().GetTypes()
where StringComparer.CurrentCultureIgnoreCase.Compare(
type.Name, controllerName + "Controller") == 0
select type;
switch (controllerTypes.Count())
{
case 0:
throw new HttpException(404,
string.Format(CultureInfo.CurrentCulture,
"Controller not found", new object[] {
requestContext.HttpContext.Request.Path
}));
case 1:
controllerType = controllerTypes.First();
break;
default:
throw UnityControllerFactory.
CreateAmbiguousControllerException(routeData.Route,
controllerName, controllerTypes.ToList());
}
}
return _container.Resolve(controllerType) as IController;
}
I think it has another workaround, you can use
Area. Suppose I have two controller same name but stored in two different place one of them inside of area and other is normal, For exampleNow i’ve two Action both are try to render two different view.
the same facility can be obtain using routing.