控制器默认命名空间顺序MVC C#

时间:2018-05-18 14:20:37

标签: c# asp.net-mvc

我在最后一个mvc版本5.2.6上分离了两个项目的控制器和视图

我们有许多具有相同控制器的客户端项目,但有时需要覆盖控制器。

我会这样做: 我的库项目中的默认控制器,但如果我们在主项目中找到控制器,请使用这个控制器。

但是当我这样做时:

ControllerBuilder.Current.DefaultNamespaces.Add("MainProject.Controllers");
ControllerBuilder.Current.DefaultNamespaces.Add("Library.Controllers");

我得到一个错误控制器是不明确的

更新

理念是为所有客户网站提供通用控制器。客户端网站将仅包含视图,但需要覆盖某些控制器以用于特定的客户端开发。

1 个答案:

答案 0 :(得分:0)

在我的例子中,我有两个类似的控制器。一个在Core命名空间中,一个在Client中:

namespace CustomControllerFactory.Core.Controllers
{
    public class DemoController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.CalledFrom = "Core";
            return View();
        }
    }
}

namespace CustomControllerFactory.Client.Controllers
{
    public class DemoController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.CalledFrom = "Client";
            return View();
        }
    }
}

为此,我创建了一个自定义控制器工厂:

public class CustomControllerFactory : IControllerFactory
{
    public IController CreateController(RequestContext requestContext, string controllerName)
    {
        var ns = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
        var coreNs = $"{ns}.Core.Controllers";
        var clientNs = $"{ns}.Client.Controllers";

        //find out if core or client exists: https://stackoverflow.com/questions/8499593/c-sharp-how-to-check-if-namespace-class-or-method-exists-in-c
        var coreControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                               from type in assembly.GetTypes()
                               where type.Namespace == coreNs
                               select type);

        var clientControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                                 from type in assembly.GetTypes()
                                 where type.Namespace == clientNs
                                 select type);

        Type controllerFullType = null;
        if (coreControllers.Any(x => x.Name == $"{controllerName}Controller"))
        {
            controllerFullType = Type.GetType($"{ns}.Core.Controllers.{controllerName}Controller");
        }
        else if (clientControllers.Any(x => x.Name == $"{controllerName}Controller"))
        {
            controllerFullType = Type.GetType($"{ns}.Client.Controllers.{controllerName}Controller");
        }
        else
        {
            throw new ApplicationException("no valid controller found");
        }

        IController controller = Activator.CreateInstance(controllerFullType) as Controller;
        return controller;
    }

    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
    {
        return SessionStateBehavior.Default;
    }

    public void ReleaseController(IController controller)
    {
        (controller as IDisposable)?.Dispose();
    }

}

执行以下操作:

  1. 检查核心命名空间中是否存在合适的控制器
  2. 检查客户端命名空间中是否存在合适的控制器
  3. 如果没有找到,则抛出异常(实现回退可能?)
  4. 如果找到则创建Core,否则创建客户端控制器
  5. 然后你必须在global.asax中注册你的工厂:

    ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));