Реализация фабрики пользовательских контроллеров с участием нескольких сборок
В настоящее время мы пытаемся реализовать собственную фабрику контроллеров в нашем API, чтобы определить правильный контроллер, который будет использоваться, в зависимости от токена идентификатора, который передается нашему API. Способ настройки этого проекта заключается в том, что каждая отдельная компания (их всего около 5) имеет свою собственную сборку, которая содержит настраиваемые контроллеры, в которых есть методы действий, необходимые для выполнения любых действий, которые кто-либо пытается выполнить. Одно из требований, которые мне прислали, заключается в том, что в этих сборках контроллеры должны называться одинаково. Таким образом, вы можете иметь, например, четыре разных контроллера, каждый в своей сборке CustomerController
, Эти четыре контроллера содержат методы действия, названные одинаково, но реализация внутри них совершенно другая.
При использовании нашей пользовательской фабрики контроллеров мы используем Reflection, чтобы извлекать и создавать экземпляр правильного типа контроллера, на основе которого должна быть выбрана сборка. Я отладил это и подтвердил, что правильный контроллер возвращается в результате.
Проблема возникает во время вызова метода действия. Несмотря на то, что наша фабрика контроллеров возвращает правильный контроллер для нашего запроса, кажется, что MVC, возможно, предварительно загрузил каждый контроллер из этих сборок и все еще рассматривает их как возможное направление. Точная ошибка, которую мы получаем при вызове метода действия: The current request is ambiguous between the following action methods
Есть ли способ сказать MVC игнорировать другие контроллеры, которые не были возвращены в запросе фабрики контроллеров, чтобы он не знал, пытаться ли посмотреть на другие контроллеры, которые, кажется, не загружены? Какой смысл в Controller Factory, если MVC просто собирается проверить все остальные контроллеры на соответствие методу действия? Здесь должно быть что-то, чего мне не хватает.
Единственное другое решение, которое я нашел для решения этой проблемы, - это добавление атрибута ActionMethodSelector ко всем задействованным методам действий. Тем не менее, это делает решение довольно хрупким, если смотреть в будущее и учитывать, что каждому методу действия необходимо повторять один и тот же атрибут.
Будем рады любым советам или знаниям о том, почему MVC ведет себя так, когда я реализовал собственную фабрику контроллеров, которая должна решать, какой контроллер выбран для использования метода действия. Заранее спасибо!
1 ответ
Мы нашли решение. Фабрика контроллеров работала как задумано. Проблема была на самом деле в нашем маршруте. Перед реализацией этого решения мы пометили наши методы действий атрибутом Route. Так, например, для каждого контроллера в разных сборках мы имели
[Route("Customer/Lookup/{name}")]
public ActionResult LookupByName(string name)
{
// Custom code content here
}
Оказывается, что указание атрибута Route в этих Action Methods имеет приоритет над выбранным контроллером, и все контроллеры, которые соответствуют текущему запрошенному контроллеру / действию, все равно вызываются. Нашим решением было удалить этот атрибут и поместить то, что было необходимо, в файл RouteConfig.cs, чтобы он загружался динамически и полный контроль возвращался в нашу собственную фабрику контроллеров, чтобы решить, какой именно контроллер использовать для выбранного Action Method.
routes.MapRoute(
name: "CustomerLookup",
url: "customer/lookup/{name}",
defaults: new { controller = "Customer", action = "LookupByName", name = UrlParameter.Optional }
);