Net4x.InjectModuleInitializer 1.3.0.26250

dotnet add package Net4x.InjectModuleInitializer --version 1.3.0.26250
                    
NuGet\Install-Package Net4x.InjectModuleInitializer -Version 1.3.0.26250
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Net4x.InjectModuleInitializer" Version="1.3.0.26250">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Net4x.InjectModuleInitializer" Version="1.3.0.26250" />
                    
Directory.Packages.props
<PackageReference Include="Net4x.InjectModuleInitializer">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Net4x.InjectModuleInitializer --version 1.3.0.26250
                    
#r "nuget: Net4x.InjectModuleInitializer, 1.3.0.26250"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Net4x.InjectModuleInitializer@1.3.0.26250
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Net4x.InjectModuleInitializer&version=1.3.0.26250
                    
Install as a Cake Addin
#tool nuget:?package=Net4x.InjectModuleInitializer&version=1.3.0.26250
                    
Install as a Cake Tool

Net4x.InjectModuleInitializer

Runs a method of your choosing once, automatically, before anything else in your assembly is touched — the CLR's module initializer.

C# has no syntax for one on the frameworks this package targets ([ModuleInitializer] arrived in C# 9 and only works on .NET 5+). The CLI does support it, though: every module may carry a <Module>::.cctor, and the runtime guarantees it runs exactly once, before the first access to any type in that module. This package adds that method to your compiled assembly after the build, so the feature is available all the way back to .NET Framework 3.5.

It is a build-time tool. Nothing from this package ends up as a dependency of your assembly.

Getting started

Install the package:

dotnet add package Net4x.InjectModuleInitializer

Add a class named ModuleInitializer with a method named Run anywhere in the project:

internal static class ModuleInitializer
{
    internal static void Run()
    {
        // Runs once, before any type in this assembly is first used.
    }
}

Build. That is the whole setup — the package brings an MSBuild targets file that runs after every successful build and rewrites the output assembly in place.

The method it looks for

By default the tool looks for a type called ModuleInitializer in any namespace and a method on it called Run. The method must be:

Requirement Why
public or internal private and protected are not callable from <Module>::.cctor
static there is no instance to call it on
void the module constructor has nowhere to put a return value
no parameters the runtime calls it with no arguments

Break one of those and the build fails with a message naming the rule.

What it does to your assembly

Given ModuleInitializer.Run, the tool adds this to the module:

.method private static specialname rtspecialname void .cctor() cil managed
{
    call void ModuleInitializer::Run()
    ret
}

Debug symbols are read and rewritten alongside the assembly, so stepping through the build output still works. Portable, embedded and classic Windows PDBs are all preserved.

Command line

The MSBuild targets call the tool for you. If you want to run it yourself — over an assembly you did not build, say — it is under tools/ in the package:

InjectModuleInitializer.exe [/m:<method>] [/k:<keyfile>] <assembly>
Option Meaning
/m:, /moduleinitializer: Use a specific method instead of the ModuleInitializer.Run convention, written Full.Type.Name::MethodName — e.g. /m:My.Startup.Bootstrap::Initialize. The type name is the full name including namespace; the separator is two colons.
/k:, /keyfile: Re-sign the assembly with this strong name key after injecting. Needed whenever the assembly was signed, because rewriting it invalidates the existing signature.
/?, /h, /help Print usage.

Exit code is 0 on success and 1 on any failure, with the reason on standard error.

Strong-named assemblies

If your project sets SignAssembly and AssemblyOriginatorKeyFile, the targets file passes the key through automatically — there is nothing to configure. Signing is a .NET Framework capability, so it works when the tool runs on .NET Framework, which is the case for every assembly the MSBuild integration selects.

What is in the package

build/
  Net4x.InjectModuleInitializer.props      sets InjectModuleInitializerTool for your target framework
  Net4x.InjectModuleInitializer.targets    the AfterBuild target that runs it
tools/
  net35/  net40/  net45/  netstandard2.0/  the tool, with Mono.Cecil alongside it

The props file picks the tool by the framework your project targets: net35 for net35, net40 for net40, and the net45 build for everything else. That build is a .NET Framework executable, so the MSBuild integration expects a Windows build host with .NET Framework available.

The InjectModuleInitializer target is incremental — it is skipped when the assembly has not been rebuilt — and registers its stamp file for Clean.

Credits

Originally written by Einar Egilsson; this package repackages it for the Net4x set. Assembly rewriting is done with Mono.Cecil.

MIT licensed.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.0.26250 104 9/7/2026
1.1.0 578 8/27/2023