Skip to content

Runtime

How does a Suite Application come to life?

The Runtime Packages handle the composition and bootstrapping of Suite Applications.

The Bootstrapping Process

When a vanilla .NET application start, the IHostBuilder is used to build an IHost, which is in charge of managing the lifetime of IHostedServices. These services are built on-top of .NET infrastructure (like DI, Configuration, Logging, etc), and they can be any long lived process like an HTTP Server. Enter ASP.NET Core.

Vanilla ASP.NET Core application are built on top of .NET 5 applications. It uses the infra of .NET apps, mainly adding the middleware pipeline and all ASP.Net related stuff (like ApiControllers, etc).

The middleware pipeline, which is the entry-point for all ASP.NET Core stuff, is, unsurprisingly, an IHostedService on top of .NET Core's Generic Host. This service, in essence, builds the middleware pipeline and executes it.

Suite Applications are built on top of .NET 5 applications, and beautifully integrates with ASP.NET Core as well.

In a Suite Application, functionality is divided in Suite Modules. These modules may in turn depend on other modules to form a topological dependency graph. The main entry-point for Suite applications is the Root Module. The root module is just a regular Suite Module which is used to compose the app based on other modules that provide features or utilities.

The Suite's Bootstrapping Process is hooked up with .NET's Generic Host through extension methods on the IHostBuilder.

Generic Host Integration

The IHostBuilder is used to configure the IHost to be created. When an app is configured, services, configuration, and IHostedServices can be added through the host builder before IHostBuilder.Build is called.

When the IHost is built, the following actions take place in the specified order each depending on the previous step in order to succeed.

  1. The Host Configuration is built.
  2. The Host Environment is built.
  3. The App Configuration is built, extending from the Host Config.
  4. The Application Services are built.
  5. Hosted Services are started.

The Suite's bootstrapping process happens after all services are registered, but before the actual IServiceProvider is built and hosted services are started. In a Suite Application, the bootstrapping process is as following:

  1. The Host Configuration is built.
  2. The Host Environment is built.
  3. The App Configuration is built, extending from the Host Config.
  4. Suite Bootstrap Starts
    1. Bootstrap Services are created.
    2. The IModuleLifetimeManager is resolved through them.
    3. Modules are discovered and instantiated; SetupModule is called.
    4. Module Options provided at SetupModule step are built.
    5. Module's ConfigureServices is called, receiving the application's IServiceCollection
  5. Application Services are built.
  6. Hosted Services are started.
    1. In a Suite ASP.NET Core app, Modules ConfigureMiddlewares is called receiving an instance if the app's IApplicationBuilder.

This is all encapsulated by the following lines of code:

C#
using ITsynch.Suite.Application.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace BasicSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureSuiteWebAppForRootModule<BasicSampleModule>();
    }
}

The Root Module

Suite Applications are bootstrapped from a Root Module. The Root Module is just an ISuiteModule which depends on all the "top-level" modules that compose the app.

The Root Module will most likely only depend on "feature modules", meaning modules from the application that implement a particular feature; and perhaps some high level "framework modules" like Localization.

Note

All Suite Applications will try to discover modules from a directory in the app's execution context. You can read more here.

Bootstrap Services

In a Suite Application, a "sidecar" IServiceCollection is used to resolve the symbols needed for the bootstrapping process. This allows consumers to extend the process and to compose it by using DI. This collection is known as the Bootstrap Services.

The Bootstrap Services are built before the application services, and they do not get promoted to application services at all. The bootstrap services are mainly used to resolve the ILifetimeManager, and to resolve ISuiteModules with DI.

This last part is quite handy, since it allows modules to inject stuff.

The host.config.json file

Every Suite Application will add an IConfigurationSource to the App's configuration called the host.config.json file, which will be obtained from the well known paths. In most common scenarios that would be C:/ITsynch or /etc/itsynch/ for Windows and GNU/Linux respectively.

Note that in order for changes in this file to be reflected in applications, an app restart is needed since the file is loaded at startup. This is by design, since we do not expect the default environment to change often.

For example, we can configure logging for all applications running on a single host by providing a host.config.json file with the following contents.

JSON
1
2
3
4
5
6
{
"Serilog": {
        "MinimumLevel": {
            "Default": "Information"
        },
}