将 IServiceProvider
注入服务类是一种不好的做法,作为在ASP.NET Core 2.0中获取可选依赖项的方法吗?这会打破Explicit Dependency Principal吗?
我有一个类需要一个可选服务,EventBus . 如果EventBus已注册,我希望服务类发布一个事件,如果不是简单地忽略它 .
public class SomeService {
private readonly IServiceProvider _serviceProvider;
public SomeService(IServiceProvider serviceProvider) {
_serviceProvider = serviceProvider;
}
public SomeAction() {
var eventBus = _serviceProvider.GetService(typeof(IEventBus)) as IEventBus;
if (eventBus != null) {
eventBus.publish("SomeAction Happened!");
}
}
}
我无法看到如何使用内置的IoC Container of ASP.NET Core 2.0创建可选的依赖项 .
编辑:任何建议如何在ASP.NET Core中实现可选的依赖项?或者没有反模式可以获得相同效果的任何其他策略?
2 回答
如果方法直接需要它以使其正常运行,则不会被认为是可选的 .
它应该明确地作为依赖注入
否则考虑将它作为可选依赖项显式传递给方法
强调我的
注入
IServiceProvider
被视为反模式,因为它遵循服务定位器模式 .例如,如果依赖类也用作工厂,则存在一些例外情况 .
注入
IServiceProvider
是Service Locator anti-pattern的实现 . 防止这样做 . 依赖性也不应该是optional . 这引入了复杂性 . 而是使用Null Object pattern . 实现所需的依赖性,简化了消费者及其测试 .换句话说,
SomeService
应如下所示:在Composition Root中,如果不存在实际实现,则使用
NullEventBus
实现 . 这应该像这样简单:由于此实现不执行任何操作,因此可以将其注入所有使用者 .