我正在重构一个ASP.Net Core 2.2 Web应用程序。我决定将一些功能移动到一个单独的类库(.net core 2.2)项目中。该类库依赖于System.IO.Abstractions(以便进行单元测试)。简化版本的类库如下所示:
using System;
using System.IO.Abstractions;
namespace ClassLibrary1
{
public class TestService
{
private IFileSystem fileSystem;
internal TestService(IFileSystem fileSystem)
{
this.fileSystem = fileSystem;
}
public TestService() : this(new FileSystem()) {}
}
}
在Web应用程序项目中,我已经添加了对类库dll的引用。在Startup.cs中,我添加了using语句,并在ConfigureServices中向DI容器注册TestService(在类库中定义):
...
using ClassLibrary1;
namespace WebApplication1
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScoped<TestService>();
}
...
}
}
我将尝试在控制器中实例化服务,如下所示:
:
using ClassLibrary1;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
TestService service;
public HomeController(TestService service)
{
this.service = service;
}
...
}
}
当我运行这个项目时,我得到了以下错误信息:
我该如何解决这个问题,而不需要将 System.IO.Abstractions 包添加到 Web 应用程序项目中?FileNotFoundException: 找不到文件或程序集 'System.IO.Abstractions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=96bf224d23c43e59'。系统找不到指定的文件。
我的理解是,问题出现的原因是我正在尝试使用 DI 解析的类的构造函数包含 IFileSystem 类型,它是一个外部依赖项,因此 Web 应用程序无法解析它。
在寻找解决此问题的方法后,我尝试做的一件事是向类库添加扩展方法,以处理注册所需的依赖项。
using Microsoft.Extensions.DependencyInjection;
using System.IO.Abstractions;
namespace ClassLibrary1
{
public static class IServiceCollectionExtension
{
public static IServiceCollection AddTestService(this IServiceCollection services)
{
services.AddScoped<IFileSystem, FileSystem>();
services.AddScoped<TestService>();
return services;
}
}
}
然后在Web应用程序的ConfigureServices中使用此扩展方法,如下所示:
services.AddTestService();
然而,这将导致相同的错误消息。
编辑: 我真正的问题是如何正确地编写类库,以便可以在不必担心依赖项的情况下使用它?
所以,在 Web 应用程序中,应使用公共无参构造函数实例化 TestService,在类库解决方案中的 xunit 项目中,可以使用内部构造函数实例化 TestService。