簡體   English   中英

使用 a.Net Class 庫進行依賴注入?

[英]Dependency injection with a .Net Class Library?

我有一個 Class 庫,它做了很多文件 IO。 它有點難以測試,所以我想開始使用System.IO.Abstractions package。 它有一個接口,您可以使用真實文件系統或模擬文件系統來實現該接口。

因此,當代碼在生產中運行時,我想要真正的文件系統,但在測試時我想模擬它。 我的 class 做 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);
}

現在我想使用依賴注入來填充 _fileSystem 實例以確定使用什么。 問題是我不知道如何在 Class 庫中執行此操作。 我找到了教程,但似乎圖書館的使用者必須進行注入。 我的問題是這個 class 庫被打包上傳到一個平台。 該平台在使用 package 之前無法對其進行任何操作。 所以不知何故,圖書館必須自己弄清楚要使用什么實例。

我能想到的一種方法是使用調試符號,

#if DEBUG  #endif

但當然它的混亂和分散配置。

在 Class 庫中使用 DI 的正確方法是什么?

這是你的問題:

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

您缺少依賴注入的注入部分。 這應該是這樣的:

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

為什么?

現在您的 class 現在不再對FileSystem具有硬依賴,它現在對FileSystem的接口具有軟依賴( IFileSystem )。

現在在測試這個 class 時,您可以模擬接口:

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

在生產代碼中,您現在有兩個選擇。 您可以自己注入所有依賴項:

Service testInstance = new Service(new FileSystem);

這很快就會變得笨拙。 或者你可以使用一個注入框架(我推薦SimpleInjector雖然這只是我的意見):

依賴注入框架(帶有簡單的注入器)

使用 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 框架為我解決了它。

有關更多信息,我建議您查看類似的問題,例如什么是依賴注入?

Class 庫

class 庫在這里沒有什么特別之處。 您需要做的就是確保調用依賴注冊,並且任何消費者都從您的注冊中獲取初始依賴,或者允許他們注入自己的注冊。 這有多種模式,正確的解決方案取決於您的目標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM