我们目前正在开发一个动态系统,需要在运行时加载一些扩展。
扩展构建在与 MVC 应用程序相同的架构上,这意味着一个 Controller 文件夹,包含以 Controller 结尾的类、位于/View/ControllerName 中的关联 View 和 ViewComponents,以及相关模型。
无法将此项目添加为对项目的引用,因此我创建了一个在运行时加载它们的中间件:
foreach (var item in extensions)
{
Assembly.LoadFrom($@"extensions\{item.Name}.dll");
}
到目前为止一切顺利,它们在运行时加载。但是,当我尝试访问在其中一个扩展 Controller 中创建的路由时,WebSite 给我一个 404 响应。
我尝试添加扩展作为引用,它运行良好,所以这不是我的扩展中的问题。
如何设法将我的 dll Controller 注册到 MVC 主站点?
这不是 ASP MVC 4,这是 ASP Core,因此这个答案似乎无效:asp.net mvc put controllers into a separate project
虽然依赖注入(inject)可能是一个解决方案,但我没有找到任何解决方案来让我的扩展为自己注册服务(这对扩展创建者来说很复杂)。
我的扩展路由是在 Controller 端定义的:
[Route("[controller]/[action]")]
public class LotteryController : Controller { ... }
在我的 Startup.cs 上,我实际上保留了默认路由:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
事实是,我希望我的扩展启用路由:http://localhost/Lottery/Index
它给了我一个空白页。出于测试目的,我当前的索引操作是
// GET Index
public IActionResult Index()
{
return Content("From extension");
//return View();
}
这是我的扩展项目层次结构
最佳答案
MVC 将在启动时自动查找继承自 Controller
的 Controller 并包含它们。这将适用于外部程序集,但很可能只适用于静态链接的程序集。
如果您正在动态加载它们,您可能想要尝试延迟 MVC 的启动或单独注册程序集。
此代码片段展示了如何在其他程序集中搜索 Controller 。可以找到对此进行解释的完整文章 here .一旦加载了程序集,您就可以使用它来强制 MVC 在它们中搜索 Controller 。
services.AddMvc().AddControllersAsServices(new[]
{
typeof(MyController).Assembly,
typeof(ExternalPocoController).Assembly
});
这将在这些程序集中搜索 Controller 。唯一需要注意的是,它可能 无法找到关联的 View 。老实说,我对此不确定,因为我只用 WebAPI Controller 做过。 编辑 This看起来这可能是一种让 View 工作的方法
作为旁注,我可能建议使用路由装饰器或通过旧方法映射路由。两者同时使用似乎会带来麻烦。
关于c# - ASP MVC Core RC1 将 Controller 、 View 和模型放在运行时加载的其他程序集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36306705/