Immerse a library inside another library.
Immersive is an IL weaver that substitutes types and methods from a referenced assembly with implementations from an "immerse" assembly. At compile time, it rewrites IL so that the target assembly uses the substitute types and method bodies — without changing source code.
Automatically weaves your assembly after compilation:
dotnet add package Allors.Immersive.MSBuild
For standalone weaving from the command line:
dotnet tool install -g Allors.Immersive.Tool
dotnet add package Allors.Immersive # Weaving engine API
dotnet add package Allors.Immersive.Attributes # SubstituteClass/SubstituteMethod attributes
dotnet add package Allors.Immersive.Winforms # WinForms substitute types and testers
Three assemblies are involved:
- Referenced assembly — the library your code depends on (e.g.
AssemblyReferenced) - Immerse assembly — provides substitute types/methods annotated with
[SubstituteClass]and[SubstituteMethod](e.g.AssemblyToImmerse) - Target assembly — your project that references both; after weaving, all references to types in the referenced assembly are rewritten to use the substitutes
The target assembly signals which immerse assembly to use via a marker class:
#if(DEBUG)
public class ImmersiveMarker : AssemblyToImmerse.Marker
{
}
#endifThe weaver discovers the immerse assembly from the marker's base type, then rewrites the target's IL accordingly.
Reference the Allors.Immersive.MSBuild package in your project. It includes a .targets file that runs the weaver automatically after compilation:
<Target Name="Immersive" AfterTargets="Compile">
<ImmersiveTask AssemblyPath="$(TargetPath)" SearchDirectories="@(ReferencePath)" />
</Target>immerse <assembly-path> [options]
Arguments:
<assembly-path> Path to the assembly to weave
Options:
-s, --search-dir <dir> Search directory for assemblies (repeatable)
-v, --verbose Print weaver info messages
-h, --help Show this help
If no search directories are specified, the directory containing the assembly is used.
The Allors.Immersive.Attributes package provides two attributes for the immerse assembly.
Applied to a class in the immerse assembly. Two modes:
Base substitution — no arguments. The class to substitute is inferred from the base type:
[SubstituteClass]
public class Form : AssemblyReferenced.Form
{
// All references to AssemblyReferenced.Form in the target
// will be rewritten to use this type's members
}Explicit substitution — pass the type to substitute:
[SubstituteClass(typeof(AssemblyReferenced.Button))]
public class MyButton
{
// Substitutes AssemblyReferenced.Button
}Applied to a method. Substitutes a specific method on a specific type:
[SubstituteMethod(typeof(AssemblyReferenced.Form), "ShowDialog")]
public string AllorsShowDialog()
{
return "Substitute: " + ShowDialog();
}The first argument is the type containing the method to substitute. The second (optional) argument is the method name — if omitted, the decorated method's own name is used.
AssemblyReferenced (the library):
public class Form
{
public string ShowDialog() => "Referenced: ShowDialog()";
}AssemblyToImmerse (the substitutions):
[SubstituteClass]
public class Form : AssemblyReferenced.Form
{
[SubstituteMethod(typeof(AssemblyReferenced.Form), "ShowDialog")]
public string AllorsShowDialog()
{
return "Substitute: " + ShowDialog();
}
}AssemblyToProcess (the target — before weaving):
public class TestForm : AssemblyReferenced.Form
{
public string CallShowDialog() => this.ShowDialog();
}After weaving, TestForm inherits from the substitute Form and CallShowDialog() invokes the substituted method body.
The project uses Nuke as its build system.
./build.cmd Compile # restore + build
./build.cmd Test # run tests
./build.cmd Pack # create NuGet packages in output/
./build.cmd Clean Compile # clean then build
| Project | Description |
|---|---|
src/Allors.Immersive |
Weaving engine (dnlib-based IL rewriting) — standalone NuGet package |
src/Allors.Immersive.Attributes |
Attribute definitions (SubstituteClassAttribute, SubstituteMethodAttribute) |
src/Allors.Immersive.MSBuild |
MSBuild task that invokes the weaver after compilation |
src/Allors.Immersive.Tool |
CLI global tool for standalone weaving |
src/Allors.Immersive.Winforms |
WinForms substitute types and testers |
test/AssemblyReferenced |
Test fixture — the referenced library |
test/AssemblyToImmerse |
Test fixture — substitute implementations |
test/AssemblyToProcess |
Test fixture — target assembly to weave |
test/Tests |
Integration tests validating the weaving results |
LGPL-3.0