Search code examples
c#asp.net-coreasp.net-core-mvconion-architecture

Best Way to Decouple Startup Configuration from Web Project in ASP.NET 5 and MVC 6


Using MVC5, it has been very easy to create a bootstrapper project that had references to all layers, thus decoupling the UI layer from references to, lets say, infrastructure logic. The project would contain startup configuration logic, such as setting up the IoC container.

The way to do this was to define a startup class:

public class Startup
{
    public static void Start()
    {
        // startup configuration (IoC etc) goes here
    }
}

And then add a line in AssemblyInfo.cs:

[assembly: PreApplicationStartMethod(typeof(Startup), "Start")]

Unfortunatelly, this approach no longer works with asp.net 5. I had a brief look at the documentation but all I found out was that the framework looks for a class named Startup within the Web project.

I also had a look within the Microsoft.AspNet.Hosting source code which seems to be responsible for finding the Startup class. I can see some references to the configuration class, so there is a chance that the assembly can be loaded by using some kind of configuration setting, but I couldn't confirm this or determine which setting.

Also, if this is true, how could the Startup class be determined by using the config.json file, when the file itself is being loaded within the Startup class? Are there different options for configuring the startup assembly, like for example using an environment variable?


Solution

  • You can change the assembly where the WebHostBuilder will look for the startup type.

    Add an INI config file with the name Microsoft.AspNet.Hosting.ini to your wwwroot folder with the following contents:

    [Hosting]
    Application = App.Bootstrapper
    

    Where App.Bootstrapper is the namespace of your application bootstrapper project.

    The startup class will have to look the same though, e.g. with ConfigureServices and Configure:

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // ...
        }
    
        public void Configure(IApplicationBuilder app)
        {
            // ...
        }
    }
    

    If you're curious, you can see the logic for determining the startup type here. If we specify the Hosting:Application key in the INI file, it will use that value in stead of appEnvironment.ApplicationName.