Метод Main — это точка входа приложения C#. (Библиотекам и службам точка входа в виде метода Main не требуется.) Когда приложение запускается, первым вызывается именно метод Main.

Официальная Документация

На самом деле метод Main может быть не первым методом сборки, который будет выполняться при запуске приложения. Существуют различные методы, которые могут выполняться перед методом Main. В этом посте я покажу вам различные способы выполнения кода перед методом Main. Я не говорю, что так нужно делать, только то, что это возможно 😃

Статический конструктор

Статический конструктор используется для инициализации любых статических данных или для выполнения определенного действия, которое необходимо выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или обращением к любым статическим элементам. Итак, статический конструктор вызывается перед методом Main.

class Program
{
    static Program() => Console.WriteLine("Main еще не написали");
    static void Main() => Console.WriteLine("Привет мир!");
}

Инициализаторы модулей

Инициализаторы модулей позволяют библиотекам выполнять активную однократную инициализацию при загрузке без необходимости явного вызова пользователем чего-либо. Когда среда выполнения загружает модуль (DLL), она вызывает методы инициализации модуля перед выполнением любого кода из этого модуля.

using System.Runtime.CompilerServices;
class Initializer
{
    // Статический конструктор запускается перед инициализатором модуля
    static Initializer() => Console.WriteLine("Статический конструктор.");
    [ModuleInitializer]
    public static void Init1() => Console.WriteLine("Инициализатор модуля 1");
    [ModuleInitializer]
    public static void Init2() => Console.WriteLine("Инициализатор модуля 2");
}
class Program
{
    static void Main() => Console.WriteLine("Привет мир!");
}

Хуки Startup

Переменная среды DOTNET_STARTUP_HOOKS может использоваться для указания списка управляемых сборок, содержащих тип StartupHook с общедоступным методом static void Initialize(). Каждый из этих методов будет вызываться в указанном порядке перед точкой входа Main.

class StartupHook
{
    static StartupHook() => Console.WriteLine("Статический конструктор.");

    // Запустите приложение с переменной окружения
    // DOTNET_STARTUP_HOOKS=myapp.dll (используйте полный путь к сборке)
    public static void Initialize() => Console.WriteLine("Startup хук");
}

class Program
{
    static void Main() => Console.WriteLine("Привет мир!");
}

Перевод статьи «Executing code before Main()«