无法加载文件或程序集

问题描述 投票:1回答:1

我正在重构ASP.Net Core 2.2 webapp。我决定将一些功能移到一个单独的类库(.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,版本= 7.0.0.0,文化=中性,PublicKeyToken = 96bf224d23c43e59'。系统找不到文件指定。

我如何解决此问题而不将System.IO.Abstractions包添加到webapp项目中?

我的理解是,出现问题是因为我正尝试使用DI解析的类的构造函数包含IFileSystem类型,该类型是外部依赖项,因此webapp无法解决它。

在寻找解决此问题的方法后,我试图做的一件事是在类库中添加扩展方法,该方法负责注册所需的依赖项:

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;
        }
    }
}

然后在Webapp的ConfigureServices中使用此扩展方法,如下所示:

services.AddTestService();

但是这会导致相同的错误消息。

编辑:

我真正的问题是如何正确编写类库,以便可以使用它而不必担心依赖关系?

因此,在webapp中,应该使用公共的无参数构造函数实例化TestService,并且在xunit项目的classlib解决方案中,可以使用内部构造函数实例化TestService。

c# asp.net-core dependency-injection
1个回答
2
投票

您不应该解析类库中的依赖项。 The composition root只能在主应用程序中。合成根是应用程序生命周期中可以设置对象图的起点和最早点。

因此Startup.cs是ASP.NET Core应用程序中的合成根。

services.AddScoped<IFileSystem, FileSystem>();

类库没有合成根。

© www.soinside.com 2019 - 2024. All rights reserved.