目标是使用IoC并能够[模拟依赖关系]进行单元测试。
项目:具有多个类库的.NET Core Web API
我正在为我的IoC使用Microsoft.Extensions.DependencyInjection,如果它支持我想要完成的任务,我想继续使用它。
问题:我的程序集(类库)中至少有一个类具有需要模拟的依赖项(例如使用Moq)。我完全理解我可以使用构造函数注入来注入接口,但这不符合方案。
我在程序集中尝试完成的工作是使用我在Web API的Startup类中启动的容器来解决依赖关系。
我该怎么做?如果这是不可能的,那么可能是另一种完成同样事情的方法,即在不使用依赖注入的情况下模拟我的打印机?
下面是一些示例代码,希望能够澄清一点。
Web API的Startup.cs(引用了定义打印机的程序集)
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPrinter, Printer>();
}
在另一个程序集中,我想使用同一个容器解析一个Printer实例。
public interface IPrinter
{
void Print(string text);
}
public class Printer : IPrinter
{
public void Print(string text)
{
Console.WriteLine("Printing: " + text);
}
}
public class Task
{
public void PrintSomething(string text)
{
//do not 'new up' but resolve it from the container of Startup.cs
var printer = new Printer();
printer.Print(text);
}
}
答案 0 :(得分:2)
这是一个隐藏在XY problem背后的设计问题。
您已经击落了The Explicit Dependencies Principle
方法和类应明确要求(通常通过方法参数或构造函数参数)所需的任何协作对象才能正常运行。
public class PrintTask {
private readonly IPrinter printer;
public PrintTask(IPrinter printer) {
this.printer = printer;
}
public void PrintSomething(string text) {
printer.Print(text);
}
}
哪个允许依赖类,已经在容器中注册
public void ConfigureServices(IServiceCollection services) {
services.AddScoped<IPrinter, Printer>();
services.AddScoped<PrintTask>();
}
来自一个灵活的解耦类,其依赖关系可以很容易地被模拟和注入。
依赖注入是最好的选择,但也有服务定位器反模式,虽然可行,但通常不建议。