.NET Core 2 Injecting Code Before Executing the Main Method

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Insert
> Step 2: And Like the video. BONUS: You can also share it!

In .NET Core 2.2, you can use a startup hook to inject code before running an application's Main method.

  • Startup hooks make it possible for a host to customize the behavior of applications after they have been deployed without needing to recompile or change the application.
  • We expect hosting providers to define custom configuration and policy, including settings that potentially influence the load behavior of the main entry point, such as the System.Runtime.Loader.AssemblyLoadContext behavior.
  • The hook can be used to set up tracing or telemetry injection, to set up callbacks for handling, or to define other environment-dependent behavior.
  • The hook is separate from the entry point so that the user code does not need to be modified.

This could be used with AssemblyLoadContext APIs to resolve dependencies, not on the TPA list from a shared location, similar to the GAC on a full framework.

  • It could also be used to forcibly preload assemblies that are on the TPA list from a different location.
  • Future changes to AssemblyLoadContext could make this easier to use by making the default load context or TPA list modifiable.

The StartupHook type is internal and in the global namespace, and the signature of the Initialize method is public static void Initialize().

internal class StartupHook
    public static void Initialize()
        AssemblyLoadContext.Default.Resolving += SharedHostPolicy.SharedAssemblyResolver.LoadAssemblyFromSharedLocation;

namespace SharedHostPolicy
    class SharedAssemblyResolver
        public static Assembly LoadAssemblyFromSharedLocation(AssemblyLoadContext context, AssemblyName assemblyName)
            string sharedAssemblyPath = ""; // find assemblyName in shared location...
            if (sharedAssemblyPath != null)
                return AssemblyLoadContext.Default.LoadFromAssemblyPath(sharedAssemblyPath);
            return null;

Got any .NET Core 2 Question?