c# - 使用 .Net 类库进行依赖注入(inject)?

标签 c# dependency-injection

我有一个执行大量文件 IO 的类库。测试有点困难,所以我想开始使用 System.IO.Abstractions包裹。它有一个接口(interface),您可以使用真实的文件系统或模拟的文件系统来实现。

因此,当代码在生产中运行时,我想要真实的文件系统,但在测试时我想模拟它。我的类做 IO 的事情看起来像这样。

private readonly IFileSystem _fileSystem;

public Service(){
   _fileSystem = new FileSystem();  //In test we want Mock file system here
}

internal bool Run(){
   string[] sourceFilePaths = _fileSystem.Directory.GetFiles(_sourceDirectory, "*.xml", SearchOption.AllDirectories);
}

现在我想使用依赖注入(inject)来填充 _fileSystem 实例以确定要使用的内容。问题是我不知道如何在类库中执行此操作。我找到了教程,但似乎库的使用者必须进行注入(inject)。我的问题是这个类库被打包上传到一个平台。在使用该包之前,该平台无法对该包执行任何操作。因此,图书馆必须以某种方式弄清楚要使用哪个实例。

我能想到的一种方法是使用调试符号,

#if DEBUG  #endif

但是当然它很困惑并且分散了配置。

在类库中使用 DI 的正确方法是什么?

最佳答案

这是你的问题:

public Service(){
   _fileSystem = new FileSystem();  //In test we want Mock file system here
}

您缺少依赖项注入(inject)的注入(inject)部分。这应该看起来像这样:

public Service(IFileSystem fileSystem){
   _fileSystem = fileSystem;  //In test we want Mock file system here
}

为什么?

现在您的类不再对 FileSystem 具有硬依赖关系,它现在对 FileSystem 接口(interface)具有软依赖关系,(IFileSystem >).

现在,在测试此类时,您可以模拟接口(interface):

//example using nsubstitue (I prefer moq but I've been using this lately)
var mockIFileSystem = Substitute.For<IFileSystem>();
Service testInstance = new Service(mockIFileSystem);

在生产代码中,您现在有两种选择。您可以自己注入(inject)所有依赖项:

Service testInstance = new Service(new FileSystem);

这很快就会变得笨拙。或者你可以使用注入(inject)框架(我推荐SimpleInjector,尽管这只是我的意见):

依赖注入(inject)框架(带有简单注入(inject)器)

使用 DI 框架,您可以注册所有依赖项并允许框架为您解析它们:

var container = new SimpleInjector.Container();

// Registrations here
container.Register<IFileSystem, FileSystem>();
container.Register<IService, Service>();

// Request instance
IService services = container.GetInstance<IService>();

注意:我从未创建上面的 IFileSystem 实例,DI 框架为我解决了它。

有关更多信息,我建议您查看类似的问题,例如 What is dependency injection?

类库

这里的类库没有什么特别的。您需要做的就是确保调用依赖项注册,并且任何消费者从您的注册中获取初始依赖项,或者允许他们注入(inject)自己的注册。这有多种模式,正确的解决方案取决于您的目标。

关于c# - 使用 .Net 类库进行依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62909267/

相关文章:

c# - 手动解析 InstancePerRequest 类型时未收到 Autofac 相同的注入(inject)实例

c# - "Invalid attempt to read when no data is present"在对查询结果启动 foreach 循环时

c# - AJAX 路径不对

java - 从 C# System.TimeZone 创建 java.util.Date

javascript - Aurelia 中的全局应用状态

java - 从子上下文引用在父上下文中创建的 Spring Singletons

c# - 如何等待 Parallel Linq 操作完成

c# - .Net RegularExpressionValidator 与 Regex 类的匹配方式不同

c# - 单元测试 IServiceCollection 注册

php - 依赖注入(inject),几乎每个类都依赖于其他几个类