Reputation: 7340
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.
Upvotes: 7
Views: 3519
Reputation: 101593
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();
}
}
Upvotes: 11