无法加载文件或程序集。

3

我正在重构一个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;
        }

        ...
    }
}

当我运行这个项目时,我得到了以下错误信息:

FileNotFoundException: 找不到文件或程序集 'System.IO.Abstractions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=96bf224d23c43e59'。系统找不到指定的文件。

我该如何解决这个问题,而不需要将 System.IO.Abstractions 包添加到 Web 应用程序项目中?
我的理解是,问题出现的原因是我正在尝试使用 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。

1
尝试使用 .NET Standard 2.0 创建类库。根据此表,.NET Core 2.2 支持最高 .NET Standard 2.0。 - Matt.G
1个回答

3

你不应该在类库中解决依赖关系。 组合根 只能在主应用程序中。组合根是应用程序生命周期中可以设置对象图的起始和最早的点。

所以,在 ASP.NET Core 应用程序中,Startup.cs 是组合根。

services.AddScoped<IFileSystem, FileSystem>();

类库没有组合根。


那么其他人在我的组织内如何使用这个类库呢?他们需要事先了解类库的依赖关系并解决它们。也许问题没有表述清楚——我不是试图让提供的代码示例工作,而是寻找如何正确编写类库的信息,以便其他人可以使用它而不必担心依赖关系。我已经更新了问题以使其更清晰。 - Georgi Rangelov
@GeorgiRangelov,如果没有应用程序,您无法使用类库,而且使用的IoC容器是应用程序的选择,而不是库的选择。 - StepUp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接