[英]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 庫在這里沒有什么特別之處。 您需要做的就是確保調用依賴注冊,並且任何消費者都從您的注冊中獲取初始依賴,或者允許他們注入自己的注冊。 這有多種模式,正確的解決方案取決於您的目標。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.