c# - 当 Controller 类在不同的程序集中时,如何将 Controller 注册到 ASP.NET MVC 中?

标签 c# asp.net asp.net-mvc plugins inversion-of-control

我的目标是修改 asp.net mvc 的 Controller 注册,这样我就可以在单独的(子)程序集中创建 Controller 和 View ,只需将 View 文件和 DLL 复制到主机 MVC 应用程序,新 Controller 就可以有效地运行“插入”到主机应用程序。

显然,我需要某种 IoC 模式,但我不知所措。

我的想法是创建一个引用了 system.web.mvc 的子程序集,然后开始构建继承自 Controller 的 Controller 类:

单独组装:

using System.Web;
using System.Web.Mvc;

namespace ChildApp
{
    public class ChildController : Controller
    {
        ActionResult Index()
        {
            return View();
        }
    }
}

是的,一切都很好,花花公子。但是后来我研究了修改主机应用程序的 Controller 注册表以在运行时加载我的新子 Controller ,我感到困惑。可能是因为我需要更深入地了解 C#。

无论如何,我认为我需要创建一个 CustomControllerFactory 类。所以我开始编写一个类来覆盖 GetControllerInstance() 方法。在我打字的时候,intellisence 弹出了这个:

托管 MVC 应用程序:

public class CustomControllerFactory : DefaultControllerFactory 
{
    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return base.GetControllerInstance(requestContext, controllerType);
    }
}

现在,在这一点上我不知所措。我不知道那是做什么的。最初,我打算编写一个像这样的服务定位器的“Controller Loader”类:

托管 MVC 应用程序:

public class ControllerLoader
{
    public static IList<IController> Load(string folder)
    {
        IList<IController> controllers = new List<IController>();

        // Get files in folder
        string[] files = Directory.GetFiles(folder, "*.plug.dll");
        foreach(string file in files)
        {
            Assembly assembly = Assembly.LoadFile(file);
            var types = assembly.GetExportedTypes();
            foreach (Type type in types)
            {
                if (type.GetInterfaces().Contains(typeof(IController)))
                {
                    object instance = Activator.CreateInstance(type);
                    controllers.Add(instance as IController);
                }
            }
        }
        return controllers;
    }
}

然后我计划使用我的 Controller 列表在 Controller 工厂中注册它们。但是……怎么办?我觉得我快要搞清楚了。我想这一切都归结为这个问题:我如何连接到 return base.GetControllerInstance(requestContext, controllerType);?或者,我应该使用完全不同的方法吗?

最佳答案

从“根”ASP.NET MVC 项目引用其他程序集。如果 Controller 在另一个命名空间中,则需要修改 global.asax 中的路由,如下所示:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { typeof(HomeController).Namespace }
    );

}

请注意 MapRoute 方法的附加 namespaces 参数。

关于c# - 当 Controller 类在不同的程序集中时,如何将 Controller 注册到 ASP.NET MVC 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7560005/

相关文章:

ASP.NET 表单例份验证 + NTLM + LDAP

c# - 如何先调用客户端脚本函数,然后调用服务器端按钮点击事件?

asp.net-mvc - 如何在 ASP.NET MVC View 中设置页面标题?

c# - 是否使用存储库模式?需要 ORM? MVC 网络 API REST

asp.net - Microsoft.VisualBasic.Financial.Rate 错误, "Cannot calculate rate using the arguments provided"

c# - 从 C# 代码内部访问 F# List<List<>>

javascript - 如何将焦点设置到文本框 Html.TextBoxFor - mvc 2

asp.net-mvc - Bootstrap 模式页面 Asp.net MVC 验证

c# - 我怎样才能有一个不执行任何操作的 LINQ where 子句?

c# - 带有数据源的 asp 日历在表中不存在的日期上没有差异