Reputation: 11006
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?
Upvotes: 15
Views: 9712
Reputation: 196
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.
UPDATE: This method is available only for Net5 and higher
Upvotes: 8
Reputation: 13360
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");
Upvotes: 12
Reputation: 31163
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.
Upvotes: 14