实现涉及多个程序集的自定义控制器工厂

Implementing Custom Controller Factory involving multiple Assemblies

目前,我们正在尝试在我们的 API 中实施自定义控制器工厂,以根据传递给我们的 API 的标识符令牌来确定要使用的正确控制器。这个项目的设置方式是每个不同的公司(只有大约 5 个)都有自己的程序集,其中包含自定义控制器,这些控制器具有执行某人试图执行的任何操作所需的操作方法。我收到的其中一项要求是,这些程序集中的控制器必须具有相同的名称。因此,例如,您可以有四个不同的控制器,每个控制器都在一个不同的程序集中,所有控制器都命名为 CustomerController。这四个控制器都包含名称相同的动作方法,但它们内部的实现完全不同。

在使用我们的自定义控制器工厂时,我们使用反射来拉取并创建一个正确控制器类型的实例,该实例基于应该定位的程序集。我对此进行了调试,并确认结果返回了正确的控制器。

问题发生在操作方法调用期间。尽管我们的 Controller Factory 正在为我们的请求返回正确的控制器,但似乎 MVC 可能已经从这些程序集中预加载了每个控制器,并且仍在将它们视为一个可能的方向。我们在调用操作方法时遇到的确切错误是:The current request is ambiguous between the following action methods

有没有办法告诉 MVC 忽略控制器工厂请求中未返回的其他控制器,以便它知道不要尝试查看其他似乎未加载的控制器?如果 MVC 只是要检查所有其他控制器的动作方法匹配,那么 ControllerFactory 有什么意义?这里一定有我想念的东西。

我发现解决此问题的唯一其他解决方案是向所有涉及的操作方法添加 ActionMethodSelector 属性。然而,当向前看并考虑到每个单独的 Action Method 都需要在它们之间重复相同的属性时,这使得解决方案非常脆弱。

当我实现了一个自定义控制器工厂,该控制器工厂应该决定选择哪个控制器来使用 Action 方法时,期待任何关于为什么 MVC 以这种方式运行的建议或知识。提前致谢!

我们找到了解决方案。控制器工厂按预期工作。问题实际上出在我们的路由中。在实施此解决方案之前,我们已使用 Route 属性标记我们的操作方法。因此,例如,对于我们拥有的不同程序集中的每个控制器

[Route("Customer/Lookup/{name}")] public ActionResult LookupByName(string name) { // Custom code content here }

事实证明,在这些 ActionMethods 上指定 Route 属性优先于所选的控制器,并且无论如何都会调用与当前请求 controller/action 匹配的所有控制器。我们的解决方案是删除此属性并将需要的内容放入 RouteConfig.cs 文件中,以便动态加载它并将完全控制权返回给我们的自定义控制器工厂,以决定哪个控制器专门用于所选的 ActionMethod。

routes.MapRoute( name: "CustomerLookup", url: "customer/lookup/{name}", defaults: new { controller = "Customer", action = "LookupByName", name = UrlParameter.Optional } );