【发布时间】:2017-01-25 01:21:18
【问题描述】:
我有一个使用大量依赖注入的 ASP.NET Core 项目。
问题是这些开始叠加在我的控制器操作上:
public async Task LoginAsync(
[FromBody] LoginModel login,
[FromServices] IConnectionMultiplexer redis,
[FromServices] ISerialiserFactory serialiser,
[FromServices] IDataService dataService,
[FromServices] ILookupNormalizer normaliser,
[FromServices] IPasswordHasher hasher,
...
我可以将它们放在构造函数中,但大多数方法不使用它们,并且那些使用它们的方法并不总是使用它们。
我可以直接实例化它们,但是我失去了在启动时注入它们的能力。
有没有更简单的方法来获取这些注入的服务?理想情况下,我想这样称呼:
// It turns out I need the injected serialiser
var serialiser = services.Get<ISerialiserFactory>();
在 ASP.NET Core 中有没有办法做到这一点?
【问题讨论】:
-
如果大多数方法不使用这些依赖项,也许值得将您的控制器分成两个控制器?
-
@SergeyBerezovskiy 很有可能,但这会导致我的大多数控制器在需要所有这些服务时被拆分用于极端情况(可能是 1% 的请求)。
-
@Keith:重新考虑你的软件设计怎么样?如果你在一个动作中需要像
IPasswordHasher这样的服务,这意味着你的抽象很糟糕。控制器和动作应该只协调而不执行任何业务逻辑!将您的 Login 方法重构为服务,将依赖项注入新服务并将 ONE 服务注入您的操作/控制器。这篇博文可能对 Mark Seemann 有用,他已经写了一本关于 DI 的综合书籍;)blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices 或在 SO 上查看他的答案 -
也不要使用
var serialiser = services.Get<ISerialiserFactory>();,它是服务定位器模式和反模式。难以测试/模拟 -
@Tseng 是的,
LoginAsync调用实际包含业务逻辑的方法 - 一个新服务是我真正想要的,但它需要一些单例服务和其他存在那个行动。这就是为什么我确定这些 [FromService] 参数堆栈是错误的,但完全不清楚如何通过业务逻辑获取这些参数。
标签: c# dependency-injection asp.net-core