Here's the skeleton of a standard ASP.NET Core application:
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.Build();
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
In this piece the ASP.NET Core apparatus instantiates an instance of Startup.cs
class
.UseStartup<Startup>()
My query is how can I get hold (reference) of this already instantiated instance of Startup object that I can plug into my Library/Framework.
Context is to setup some Uber level framework and get a reference of this junction (Startup.cs) where all the requests are getting initiated.
The Configure method is used to specify how the app responds to HTTP requests. The request pipeline is configured by adding middleware components to an IApplicationBuilder instance. IApplicationBuilder is available to the Configure method, but it isn't registered in the service container.
startup.cs. As you can see, Startup class includes two public methods: ConfigureServices and Configure. The Startup class must include a Configure method and can optionally include ConfigureService method.
The Startup class contains the ConfigureServices and Configure methods. While the former is used to configure the required services, the latter is used to configure the request processing pipeline. The Configure method is executed immediately after the ConfigureServices method.
If ConfigureServices exists on Startup class, it will be called by the Web host. Of course, for this to happen Web host has to instantiate Startup first. Therefore, Startup constructor will execute before ConfigureServices. We will usually have our configuration and logging setup inside of the constructor.
Startup.cs file is entry point, and it will be called after Program.cs file is executed at application level. It handles the request pipeline. Startup class triggers the second the application launches. What is Program.cs ?
For example, to name the Startup class as MyStartup, specify it as .UseStartup<MyStartup> () . Open Startup class in Visual Studio by clicking on the Startup.cs in the solution explorer. The following is a default Startup class in ASP.NET Core 2.x.
The name "Startup" is by ASP.NET Core convention. However, we can give any name to the Startup class, just specify it as the generic parameter in the UseStartup<T> () method. For example, to name the Startup class as MyStartup, specify it as .UseStartup<MyStartup> () .
For example, to name the Startup class as MyStartup, specify it as .UseStartup<MyStartup> () . Open Startup class in Visual Studio by clicking on the Startup.cs in the solution explorer.
If your Startup
implements IStartup
interface, getting reference to it is easy:
var host = new WebHostBuilder()
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
var startup = host.Services.GetService(typeof(IStartup)); // or from any other part of code using IServiceProvider.
However, asp.net core does not require your startup class to implement this interface. If it does not - it will use adapter pattern and adapt your Startup
class to IStartup
interface. You will still have an instance of IStartup
, but it will not be your Startup
class. Instead it will be an instance of ConventionBasedStartup
. Asp.net core will explore methods of your startup class, find Configure
and ConfigureServices
methods and will pass them to ConventionBasedStartup
which will adapt them to IStartup
interface. In this case, it's not possible to retrieve instance of your startup class without heavy reflection, because it's not actually stored in any field (even in private) of ConventionBasedStartup
and is only reachable through delegate references.
Long story short - if you want to get instance of your Startup
class - make it implement IStartup
interface.
Update about how to implement IStartup interface:
public class Startup : IStartup
{
public Startup(IHostingEnvironment env)
{
// constructor as usual
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void Configure(IApplicationBuilder app) {
app.UseMvc();
// resolve services from container
var env = (IHostingEnvironment) app.ApplicationServices.GetService(typeof(IHostingEnvironment));
var logger = (ILoggerFactory)app.ApplicationServices.GetService(typeof(ILoggerFactory));
logger.AddConsole(Configuration.GetSection("Logging"));
logger.AddDebug();
// etc
}
public IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddMvc();
// etc
// return provider
return services.BuildServiceProvider();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With