Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting reference of Startup.cs object

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.

like image 546
user2727195 Avatar asked Feb 05 '17 13:02

user2727195


People also ask

What configure () method does in startup CS?

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.

What is Startup CS file?

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.

What is Startup Cs in ASP.NET Core?

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.

Which is called first configure or ConfigureServices?

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.

What is the use of startup class in C?

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 ?

How do I name a startup class in Visual Studio?

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.

How to name the startup class in ASP NET Core?

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

How to name the startup class as 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.


1 Answers

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();
    }
}
like image 97
Evk Avatar answered Oct 09 '22 00:10

Evk