Я пытаюсь внедрить коллекцию реализаций IResourceService
в другую реализацию IResourceService
, чтобы первая реализация могла перенаправить на правильный сервис в случае, когда она не может работать с ресурсом.Каждая реализация этого, которую я до сих пор пробовал, приводила к циклической зависимости - поэтому я либо хочу знать, как обойти это, либо как спроектировать это так, чтобы это не было проблемой.
Ясоздание ряда контроллеров, которые присматривают за разными ресурсами.Я упрощу для случая этого вопроса - но на самом деле у меня есть PetController
, который может выполнять простые операции с домашними животными, для которых все имеют идентификаторы.Так, например, переход к /pet/1234
даст вам сводную информацию о питомце и типе этого питомца.
Затем у меня будет несколько контроллеров для каждого типа питомца, т.е. DogController
, CatController
и HamsterController
.Все они наследуются от BasePetController
, который фактически выполняет всю тяжелую работу.В сценарии, где вы выполняете операцию над /dog/1234
, но PetId 1234 фактически соответствует хомяку, я хочу, чтобы DogController
возвратил соответствующий ответ (перенаправление при получении, конфликт при обновлении и т. Д.).
Итак, у меня есть что-то вроде этого:
BasePetController : IResourceController
{
BasePetController(IResourceController[] resourceControllers){}
abstract Type SupportedResourceType { get; }
}
DogController : BasePetController
{
DogController(IResourceController[] resourceControllers) : base(resourceControllers) {}
Type SupportedResourceType => typeof(Dog);
}
Это затем добавляется к DI следующим образом:
services.AddSingleton<IResourceController, DogController>();
services.AddSingleton<IResourceController, CatController>(); // etc.
Это приводит к циклической зависимости, потому что DogController
нуждается в себе в порядкечтобы создать себя эффективно.
Я попытался ввести ResourceControllerSelector
, чтобы отделить этот конфликт немного дальше, но без кубиков.
Я хочу, чтобы контроллер ушел (В псевдоКод)
If (can't update dog because it isn't a dog) {
controller = getResourceControllerForPet()
action = controller.GetActionForUpdateOperation()
return information for the user to go to the correct action
}
Я думаю, что отдельные контролеры домашних животных должны нести ответственность за знание того, может ли это обрабатывать определенный ресурс, а не за другую службу, которая знает всю эту информацию + какие действия вызывать и т. Д. Но можетне могу понять, как дать каждому питомцу возможность самостоятельно получать эту информацию и / или на уровне API, не создавая циклическую зависимость.
Любая помощь по этому вопросу будет принята с благодарностью.Будь то помощь в решении проблемы внедрения зависимостей, дизайн требуемых сервисов или даже сам API.
Добавление реализации ResourceControllerSelector
, где resourceControllers
- это IEnumerable<IResourceController>
.
public IResourceController SelectController(Type resourceType)
{
EnsureArg.IsNotNull(resourceType, nameof(resourceType));
return this.resourceControllers.SingleOrDefault(x => x.SupportedResourceType == resourceType)
?? throw new ArgumentOutOfRangeException(nameof(resourceType), resourceType, "No resource controller has been configured to handle the provided resource.");
}