本文介绍了在自己的 ServiceCollection 中获取 IConfiguration的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的 tests 制作 fixture.

Im making fixture to my tests.

在我的 FixtureFactory 中,我制作了自己的 ServiceCollection:

In my FixtureFactory im making my own ServiceCollection:

    private static ServiceCollection CreateServiceCollection()
    {
        var services = new ServiceCollection();

        services.AddScoped<IConfiguration>();
        services.AddScoped<ITokenService, TokenService>();
        services.AddDbContext<TaskManagerDbContext>(o => o.UseInMemoryDatabase(Guid.NewGuid().ToString()));
        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.Password.RequiredLength = 6;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireDigit = false;
            options.User.RequireUniqueEmail = true;
        }).AddEntityFrameworkStores<TaskManagerDbContext>();

        return services;
    }

然后,我从 scope 获取这个 services:

Then, im getting this services from scope:

    var services = CreateServiceCollection().BuildServiceProvider().CreateScope();

    var context = services.ServiceProvider.GetRequiredService<TaskManagerDbContext>();
    var userManager = services.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
    var roleManager = services.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
    var signInManager = services.ServiceProvider.GetRequiredService<SignInManager<ApplicationUser>>();
    var tokenService = services.ServiceProvider.GetRequiredService<TokenService>();

当我将 TokenService 添加到我的 ServiceCollection 时,问题就开始了.

The problem starts when i added TokenService to my ServiceCollection.

TokenService 的构造函数如下所示:

Constructor, of TokenService looks like this:

    private readonly IConfiguration configuration;

    private readonly UserManager<ApplicationUser> userManager;

    public TokenService(IConfiguration configuration, UserManager<ApplicationUser> userManager)
    {
        this.configuration = configuration;
        this.userManager = userManager;
    }

当我启动我的 Core 应用时效果很好,但在我上面提到的 ServiceCollection 中不起作用.

It works great when i launch my Core app, but wont work from ServiceCollection that i mentioned above.

在测试中,我开始收到此错误:

In Tests, i started to get this error:

消息:System.AggregateException:发生一个或多个错误.(无法为服务类型Microsoft.Extensions.Configuration.IConfiguration"实例化实现类型Microsoft.Extensions.Configuration.IConfiguration".)(以下构造函数参数没有匹配的装置数据:ServicesFixture fixture)---- System.ArgumentException:无法为服务类型Microsoft.Extensions.Configuration.IConfiguration"实例化实现类型Microsoft.Extensions.Configuration.IConfiguration".---- 以下构造函数参数没有匹配的夹具数据:ServicesFixture fixture

当我将 services.AddScoped(); 添加到我的 ServiceCollection 以及当我开始获取所需的服务 TokenService.

This error started to show when i added services.AddScoped<IConfiguration>(); to my ServiceCollection and when i started to get required service TokenService.

我的问题是,如何正确注册我在Service中使用的Configuration?

My question is, how to register properly Configuration that im using in Service?

我使用 Configurationsettings.json 获取项目.

Im using Configuration to get items from settings.json.

我的fixture和示例测试类:

public class ServicesFixture
{
    public TaskManagerDbContext Context { get; private set; }

    public UserManager<ApplicationUser> UserManager { get; private set; }

    public RoleManager<IdentityRole> RoleManager { get; private set; }

    public SignInManager<ApplicationUser> SignInManager { get; private set; }

    public TokenService TokenService { get; private set; }

    public ServicesFixture()
    {
        var servicesModel = ServicesFactory.CreateProperServices();

        this.Context = servicesModel.Context;
        this.UserManager = servicesModel.UserManager;
        this.RoleManager = servicesModel.RoleManager;
        this.SignInManager = servicesModel.SignInManager;
        this.TokenService = servicesModel.TokenService;
    }

    [CollectionDefinition("ServicesTestCollection")]
    public class QueryCollection : ICollectionFixture<ServicesFixture>
    {
    }
}

测试:

[Collection("ServicesTestCollection")]
public class CreateProjectCommandTests
{
    private readonly TaskManagerDbContext context;

    public CreateProjectCommandTests(ServicesFixture fixture)
    {
        this.context = fixture.Context;
    }
}

EDIT2

当我从我的集合中删除 AddScoped(); 并运行测试时,我收到此错误:

When i delete AddScoped<IConfiguration>(); from my collection and run tests, i get this error:

消息:System.AggregateException:发生一个或多个错误.(没有注册TaskManager.Infrastructure.Implementations.TokenService"类型的服务.)(以下构造函数参数没有匹配的夹具数据:ServicesFixture fixture)---- System.InvalidOperationException : 没有注册TaskManager.Infrastructure.Implementations.TokenService"类型的服务.---- 以下构造函数参数没有匹配的夹具数据:ServicesFixture fixture

推荐答案

您添加了 IConfiguration 而没有实现.

You added IConfiguration with no implementation.

startup.cs 中,框架会在幕后创建一个实现并添加它.你必须使用 ConfigurationBuilder

In startup.cs the framework would have created an implementation behind the scenes and added it. You will have to do the same using ConfigurationBuilder

var builder = new ConfigurationBuilder()
    //.SetBasePath("path here") //<--You would need to set the path
    .AddJsonFile("appsettings.json"); //or what ever file you have the settings

IConfiguration configuration = builder.Build();

services.AddScoped<IConfiguration>(_ => configuration);

//...

这篇关于在自己的 ServiceCollection 中获取 IConfiguration的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-24 11:59