简体   繁体   English

如何在测试中从 ConfigureServices 将设置传递到 class(派生 ASP.NET Core Startup.cs)

[英]How to pass in settings into a class (derived ASP.NET Core Startup.cs) from ConfigureServices in a test

I basically have this code我基本上有这个代码

[Fact]
public async Task Test()
{
   var settings = new MySettings() { Name = "Jhon" }; //<-- use this

   var webHostBuilder = new WebHostBuilder()
    .UseStartup<TestStartup>()
    .ConfigureServices(services =>
    {
        // this is called...
        services.AddSingleton(settings);
    });
       
     //omitted code.. 
 }

And I want to be able to use MySettings in the TestStartup .我希望能够在MySettings中使用TestStartup

Whatever I try just returns Name == null ..无论我尝试什么,都会返回Name == null ..

I have tried this我试过这个

public class TestStartup : Startup
{
    public TestStartup(IConfiguration configuration) : base(configuration)
    {
       Configuration = configuration;

       // Name is always != "Jhon"

       // doesn't work
       var mySettings = configuration.Get<MySettings>();

       // doesn't work either
       var mySettings = new MySettings();
       configuration.Bind("MySettings", mySettings);

       // tried various other things that didn't work
    }
}

What am I missing?我错过了什么?

You can leverage the MemoryConfigurationProvider :您可以利用MemoryConfigurationProvider

using Microsoft.Extensions.Configuration;

var webHostBuilder = new WebHostBuilder()
    .ConfigureAppConfiguration(configurationBuilder => configurationBuilder
        .AddInMemoryCollection(new Dictionary<string, string?>
        {
            { "Name", "Jhon" },
            {"Logging:LogLevel:Default", "Warning"}
        }))
    .UseStartup<TestStartup>()
    // ...

and then it can be consumed with any standard pattern for configuration, for example:然后它可以与任何标准配置模式一起使用,例如:

public class TestStartup : Startup
{
    public TestStartup(IConfiguration configuration) : base(configuration)
    {
       var nameKeyValue = Configuration["Name"];
    }
}

If you wanted to pass a whole class over it could be done with this helper如果你想传递整个 class 可以用这个助手来完成

public static class TestHelpers<T> where T : new()
{
    /// <summary>
    /// Helper class to convert an object of type T to a dictionary.
    /// </summary>
    /// <param name="objectToConvert"></param>
    /// <returns></returns>
    public static Dictionary<string, string?> ConvertObjectToDictionary(T objectToConvert)
    {
        var dictionary = new Dictionary<string, string?>();

        foreach (var property in objectToConvert.GetType().GetProperties())
        {
            var value = property.GetValue(objectToConvert);
            dictionary.Add(property.Name, value?.ToString());
        }

        return dictionary;
    }

    /// <summary>
    /// Helper class to convert a dictionary back to an object of type T.
    /// </summary>
    /// <param name="configDictionary"></param>
    /// <returns></returns>
    public static T ConvertDictionaryToObject(Dictionary<string, string> configDictionary)
    {
        var objectToPopulate = new T();
        var properties = objectToPopulate.GetType().GetProperties();

        foreach (var property in properties)
        {
            if (configDictionary.ContainsKey(property.Name))
            {
                var value = configDictionary[property.Name];
                if (value != null)
                {
                    try
                    {
                        property.SetValue(objectToPopulate, Convert.ChangeType(value, property.PropertyType));
                    }
                    catch (Exception ex)
                    {
                        // swallow exception for private properties. This could be logged out
                    }
                }
            }
        }

        return objectToPopulate;
    }
}

and use it like this并像这样使用它

var settings = new MySettings() { Name = "Jhon" };

// convert the class to dictionary
var mySettingsDictionary= TestHelpers<MySettings>.ConvertObjectToDictionary(settings);

// and convert it back to class     
var mySettingsClass= TestHelpers<MySettings>.ConvertDictionaryToObject(mySettingsDictionary);

// and in the TestStartup like this
var mySettingsClass= TestHelpers<MySettings>.ConvertDictionaryToObject(Configuration.AsEnumerable().ToDictionary(x => x.Key, x => x.Value))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在startup.cs的ConfigureServices方法中正确注入DbContext实例(ASP.net core 1.1)? - How to inject DbContext instance in the ConfigureServices method of startup.cs correctly (ASP.net core 1.1)? ASP.NET Core 5.0中Startup.cs的ConfigureServices方法如何进行日志记录 - How to perform logging in ConfigureServices method of Startup.cs in ASP.NET Core 5.0 如何将连接字符串从startup.cs asp.net核心传递到UnitOfWork项目 - How to pass connection string to UnitOfWork project from startup.cs asp.net core ConfigureServices方法中的ASP.NET Core 1.0访问服务(Startup.cs) - ASP.NET Core 1.0 access service in ConfigureServices method (Startup.cs) ASP.NET Core 在 Startup.cs ConfigureServices 方法中访问服务 - ASP.NET Core access service in Startup.cs ConfigureServices method 当调用ConfigureServices和Configure方法时,在startup.cs中的asp.net core mvc(dotnet 5)中? - in asp.net core mvc (dotnet 5) in startup.cs when ConfigureServices and Configure method called? 从 startup.cs asp.net 内核重定向用户 - Redirect user from startup.cs asp.net core 如何删除 Startup.cs 中的 WebDav ASP.NET Core - How to remove WebDav in Startup.cs ASP.NET Core 如何在 ASP.NET Core 中的 Startup.cs 中注册 RoleManager - How to register RoleManager in Startup.cs in ASP.NET Core 如何从 asp.net 核心中的 startup.cs 获取 HTTP 标头值? - How to get HTTP header value from startup.cs in asp.net core?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM