在MVC 3中实现控制器创建策略的最佳方法

时间:2011-10-23 21:52:46

标签: c# .net asp.net-mvc-3

我有一个控制器工厂,它根据路径值以不同的方式构建一个控制器。这些是:

  1. 如果路径值与“模块”路径匹配,则使用路径值确定正确的类型以计算限定类型名称。这是,如果用户键入[http:// localhost:8080 / siijyp / modules / Personas / Naturales / Documento / Display?id = 1],控制器工厂将构建并返回OIMSIIJYP.Web。 * Personas.Naturales.Documento *控制器
  2. 如果路由值与“模块”路由匹配且它还包含“脚本”值,则控制器工厂使用Mono.CSharp在运行时构建控制器
  3. 如果路由值与模块不匹配,则会在DefaultControllerFactory执行控制时构建控制器。
  4. 很明显,所有这些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;
    }
    

1 个答案:

答案 0 :(得分:3)

我认为还有另一种解决方法,您可以使用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")

使用路由可以获得相同的设施。