【问题标题】:Pass data to startup.cs将数据传递给 startup.cs
【发布时间】:2017-06-23 12:26:27
【问题描述】:

如何将数据传递到 startup.cs 中?

这是用于使用 WebHostBuilderTestServer 进行集成测试

我需要根据测试夹具传递不同的数据。所以不想从配置文件中提取它,例如

数据将提供给在 startup.cs 中注册的中间件

文档似乎表明这应该可行:

var configBuilder = new ConfigurationBuilder()
                .AddInMemoryCollection(new[]
                {
                    new KeyValuePair<string, string>("key", "value"),
                });

            var configuration = configBuilder.Build();

            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseConfiguration(configuration) // config added here
                .UseStartup<Startup>()
                .Build();

            host.Run();

但是当我检查 startup.cs 中的配置对象时,密钥不存在。并且只有 startup.cs 中定义的提供程序可用。

我目前正尝试在 program.cs 中执行此操作以测试该概念,然后将转到集成测试

任何想法我做错了什么?

有没有更好的方法将数据传递给启动?

【问题讨论】:

  • MainStartup 中的配置完全不同,它们不相互通信。因此,您在此处设置的内容仅用于 Web 主机设置。但是如何将数据发送到Startup 是另一回事。你想要它在构造函数中还是Configure 或其他地方?
  • 我在配置中需要它,当我设置一个特定的中间件时,但构造函数也可以
  • 您实际上可以在Main 中添加一个Service 用于依赖注入,也许这会起作用?如果合适的话,我可以添加一个示例作为答案。例如,它可能是一个包含您想要的数据的单例。
  • 当然——任何传递一些数据的机制都适合我!

标签: c# .net-core


【解决方案1】:

将数据发送到Startup 的一种方法是在Main 中注册服务。 WebHostBuilder 具有 ConfigureServices 方法,可以像在 Startup 类中实现的 ConfigureServices 方法一样使用。

例如,您可以使用静态变量创建一个类(不是最好的主意,但可以)

public class DataContainer
{
   public static string Test;
}

然后设置其值并将其添加为单例服务

DataContainer.Test = "testing";

var host = new WebHostBuilder()
            .ConfigureServices(s => { s.AddSingleton(typeof(DataContainer)); })
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseConfiguration(configuration) // config added here
            .UseStartup<Startup>()
            .Build();

在此之后您的Startup 可以使用常规注入方式来获取此

public Startup(IHostingEnvironment env, DataContainer data)
{
  // data.Test is available here and has the value that has been set in Main
}

当然,在这之后的任何类和方法中都可以进行注入,而不仅仅是构造函数。

我不确定这是否比实际创建一个具有静态值的类本身更好,但如果有时需要更改该类,它可以被制成一个接口和其他通常的注入好处。

【讨论】:

  • 谢谢 - 这行得通。请注意,您的类没有静态属性,所以我只是新建了一个实例 - DataContainer container = new DataContainer {Test = "testing"}; - 然后像这样传递它: .ConfigureServices(s => { s.AddSingleton(container); })
  • @ChrisCa 哎呀,忘了。但是,是的,这也确实有效,并且比静态更好。
  • 再次感谢 - 让这个打开一段时间,看看是否有任何其他方法可以做到这一点,但如果没有,我会接受这个答案 - 干杯
  • 这不适用于 ASP.NET Core 3。您不能再将任意类型注入到 Startup 类构造函数中。
【解决方案2】:

在 ASP.NET Core 3 中,您可以将信息作为配置的一部分进行传递。在Program.cs 中,添加对.UseSettings() 的调用,并将配置键和值作为字符串传递。

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder => {
        webBuilder.UseStartup<Startup>();
        webBuilder.UseSetting("CustomProperty", someProperty.ToString());
    })

然后,在您的 Startup.cs 文件中,您应该会看到定义了 Configuration 属性的构造函数。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }
    ...
}

使用Configuration 属性,您可以使用.GetValue() 访问从Program.cs 传递的值。

Configuration.GetValue<TObjectType>("CustomProperty");

【讨论】:

  • UseSettingGetSetting 仅支持 String 值 - 您不能使用该方法传递任意对象:docs.microsoft.com/en-us/dotnet/api/… - 当您使用 GetValue 时,它将尝试执行对象绑定。
【解决方案3】:

解决方案不再有效。想要全部大写,因为一开始我一直在努力让它工作并且没有看到来自@Beevik 的评论

我发现最好的方法是使用 UseStartup 的工厂方法而不是通用方法。

因此,您将得到 .UseStartup(x =&gt; new Startup(options)) 而不是 UseStartup&lt;Startup&gt;(),其中 options 是自定义参数。

【讨论】:

  • 在 .NET Core 3.1 中找不到此方法。我错过了什么?
猜你喜欢
  • 1970-01-01
  • 2015-11-16
  • 2015-09-23
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多