Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将IServiceProvider作为依赖项获取ASP.NET核心中的可选依赖项_C#_Asp.net Core_Dependency Injection_Anti Patterns - Fatal编程技术网

C# 将IServiceProvider作为依赖项获取ASP.NET核心中的可选依赖项

C# 将IServiceProvider作为依赖项获取ASP.NET核心中的可选依赖项,c#,asp.net-core,dependency-injection,anti-patterns,C#,Asp.net Core,Dependency Injection,Anti Patterns,将IServiceProvider注入到服务类中,作为获取ASP.NET Core 2.0中可选依赖项的一种方法,这是一种不好的做法吗?这个坏了吗 我有一个类需要一个可选服务EventBus。如果注册了EventBus,我希望服务类发布一个事件,如果不是简单地忽略它的话 public class SomeService { private readonly IServiceProvider _serviceProvider; public SomeService(IServiceP

IServiceProvider
注入到服务类中,作为获取ASP.NET Core 2.0中可选依赖项的一种方法,这是一种不好的做法吗?这个坏了吗

我有一个类需要一个可选服务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!");
      }
   }
}
我看不出如何使用ASP.NET Core 2.0的内置IoC容器创建可选依赖项


编辑:对如何在ASP.NET核心中实现可选依赖项有何建议?或任何其他策略,以在没有反模式的情况下获得相同的效果?

如果该方法直接要求该策略才能正确运行,则该策略将不被视为可选策略

它应该作为依赖项显式注入

public class SomeService {
    private readonly IEventBus eventBus;

    public SomeService(IEventBus eventBus) {
        this.eventBus = eventBus;
    }

    public SomeAction() {
        if (eventBus != null) {
            eventBus.publish("SomeAction Happened!");
        }

        //...
    }
}
public SomeAction(IEventBus eventBus = null) {
    if (eventBus != null) {
        eventBus.publish("SomeAction Happened!");
    }

    //...
}
< P>考虑将它作为可选的依赖项

显式传递给方法
public class SomeService {
    private readonly IEventBus eventBus;

    public SomeService(IEventBus eventBus) {
        this.eventBus = eventBus;
    }

    public SomeAction() {
        if (eventBus != null) {
            eventBus.publish("SomeAction Happened!");
        }

        //...
    }
}
public SomeAction(IEventBus eventBus = null) {
    if (eventBus != null) {
        eventBus.publish("SomeAction Happened!");
    }

    //...
}
显式依赖原则规定: 方法和类应明确要求(通常通过方法参数或 构造函数参数)他们需要的任何协作对象 要正确运行

重点矿山


注入
IServiceProvider
被认为是一种反模式,因为它遵循服务定位器模式


有一些例外情况,例如,如果依赖类也被用作工厂。

注入
IServiceProvider
是。防止这样做。依赖性也不应该被忽略。这就带来了复杂性。相反,使用。使依赖性成为必需的,简化了使用者及其测试

换句话说,
SomeService
应该如下所示:

public class SomeService {
   private readonly IEventBus _bus;

   public SomeService(IEventBus bus) {
      _bus = bus ?? throw new ArgumentNullException(nameof(bus));
   }

   public SomeAction() {
       eventBus.publish("SomeAction Happened!");
   }
}
在您的应用程序中,如果不存在真正的实现,您将使用
NullEventBus
实现。这应该很容易做到:

public class NullEventBus : IEventBus
{
    public void publish(string message) {
        // do nothing.
    }
}

由于此实现不起任何作用,因此可以将其注入所有消费者。

这称为服务定位器,是的,这是一种您应该避免的反模式