简体   繁体   中英

Pass data to startup.cs

How do you pass data into startup.cs ?

This is for integration testing using WebHostBuilder and TestServer

I need to pass different data depending on the Test Fixture. So dont want to pull it in from a config file, for example

The data will be supplied to a registered Middleware in startup.cs

Docs seem to suggest this should work:

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();

but when I inspect the Configuration object in startup.cs, the key is not present. And only the providers defined in startup.cs are available.

I am trying to do this in program.cs at the moment to test the concept, then will move to integration tests later

any ideas what I'm doing wrong?

Is there a better way to pass data into startup?

One way to send data into the Startup would be to register a service in Main . WebHostBuilder has ConfigureServices method which can be used just like the ConfigureServices method you can implement in the Startup class.

For example you can make a class with static variables (not the best idea but works)

public class DataContainer
{
   public static string Test;
}

Then set its values and add it as a singleton service

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();

After this your Startup can just use the regular injection way to get this

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

The injection of course works in any class and method after this, not just the constructor.

I'm not sure if this is any better than to actually create a class with static values by itself but if the class needs to be changed sometimes it can be made into an interface and the other usual injection benefits.

In ASP.NET Core 3, you can pass information as part of the configuration. In Program.cs , add a call to .UseSettings() and pass the configuration key and value as a string.

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

Then, in your Startup.cs file, you should see the constructor defining a Configuration property.

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

    public IConfiguration Configuration { get; }
    ...
}

Using that Configuration property, you can then access the value you passed from the Program.cs using .GetValue() .

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

The solution DOES NOT WORK ANYMORE . Wanted to write it in all caps since at first I kept trying to make it work and did not see the comment from @Beevik

Best way I've found is to use the factory method for UseStartup instead of the generic one.

So instead of UseStartup<Startup>() you get .UseStartup(x => new Startup(options)) where options is the custom parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM