【发布时间】:2019-05-27 15:29:00
【问题描述】:
我正在尝试将IResourceService 的实现集合注入IResourceService 的另一个实现中,以便第一个实现能够在它无法对资源进行操作的情况下重定向到正确的服务。到目前为止,我尝试过的每一个实现都导致了循环依赖——所以我要么想知道如何解决这个问题,要么想知道如何设计它以使其不成问题。
我正在创建许多控制器,它们都负责不同的资源。我将简化这个问题的情况——但实际上我有一个PetController,它能够对所有提供 ID 的宠物进行简单的操作。例如,导航到/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.");
}
【问题讨论】:
-
我很想看看你对
ResourceControllerSelector的阐述,因为这对我来说似乎是正确的。如果要求IResourceController的实例,我希望只解析一种类型。 -
不一样,但这似乎与您正在尝试的相似:stackoverflow.com/a/53642638/991609
-
是的,如果您不更改代码的结构,
ResourceControllerSelector似乎是正确的选择。很遗憾,由于我们不知道您的问题域,因此我们无法提供真正的帮助。 -
@KrikWoll 资源控制器选择器看起来像这样(我会将其添加到原始问题中)
-
@DavidG 我不知道如何将
ResourceControllerSelector注入控制器,也将控制器注入ResourceControllerSelector
标签: c# asp.net dependency-injection .net-core