在MVC 3中实现控制器创建策略的最佳方式
本文关键字:策略 最佳 方式 创建 控制器 MVC 实现 | 更新日期: 2023-09-27 18:12:14
我有一个控制器工厂,它根据路由值以不同的方式构建控制器。这些都是:
- 如果路由值与"模块"路由匹配,它会使用路由值来确定正确的类型,并计算合格的类型名。这是,如果用户输入[http://localhost:8080/siijyp/modules/Personas/Naturales/documentento /Display?id=1],控制器工厂构建并返回oimsiijypp . web .* personas . naturales . documentto * controller
- 如果路由值与"模块"路由匹配,并且它还包含一个"脚本"值,控制器工厂将在运行时使用Mono构建控制器。CSharp
- 如果路由值与模块不匹配,则按照
DefaultControllerFactory
的方式构建控制器。
很明显,所有这些if
语句都是错误的,我也知道有一个IControllerActivator
类型,用于DefaultControllerFactory
创建给定控制器类型的控制器。但我不知道的是,在MVC 3中实现这些控制器创建策略的最佳方式是什么。
任何想法?
代码:
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;
}
我认为它有另一个解决方案,你可以使用Area
。假设我有两个名称相同但存储在不同位置的控制器一个在区域内,另一个是正常的,例如
admin/Controller/CommonController.cs //here admin is an area name
Controller/CommonController.cs
现在我有两个动作都是尝试渲染两个不同的视图。
@Html.Action("SystemInfo", "Common", new { area = "Admin" }) // here Admin is the area name
@Html.Action("HeaderLinks", "Common")
同样的功能可以通过路由获得。