EmitToolbox 0.2.4

EmitToolbox

Using System.Reflection.Emit to dynamically create types and methods at runtime is prone to errors and can be quite complex. To effectively emit dynamic IL code, one must have a deep understanding of the Common Intermediate Language (CIL) and the .NET runtime. The EmitToolbox library aims to simplify this process by providing a set of high-level abstractions and utilities.

Framework

Contexts:

  • AssemblyBuildingContext - Context for building dynamic assemblies.
  • TypeBuildingContext - Context for building dynamic types.
  • MethodBuildingContext - Context for building dynamic methods.
  • ActionMethodBuildingContext - Context for building dynamic methods that does not have a return value.
  • FuncMethodBuildingContext - Context for building dynamic methods that has a return value.
  • FieldBuildingContext - Context for building fields of the dynamic types.
  • PropertyBuildingContext - Context for building properties of the dynamic types.

Usage

Basic Usage

using EmitToolbox;

// Define an context for an executable (and cannot be saved) assembly.
var assemblyContext = AssemblyBuildingContext
            .CreateExecutableContextBuilder("SampleDynamicAssembly")
            .Build();
            
// Define a context for a class type within the assembly.
var typeContext = assemblyContext.DefineClass("SampleClass"); 

// Define a field.
var fieldContext = typeContext.Fields.Instance<int>("_value", FieldAttributes.Private);

// Define a method.
var methodContext = typeContext.Functors.Instance("AddAndSet", 
            [ParameterDefinition.Value<int>()], ResultDefinition.Value<int>());
var argumentSymbol = methodContext.Argument<int>(1)
var fieldSymbol = fieldContext.Symbol(methodContext.This);
var resultSymbol = fieldSymbol.Add(argumentSymbol);
fieldSymbol.Assign(resultSymbol);
methodContext.Return(resultSymbol);

// Generate the type.
typeContext.Build();

// Create an instance of the generated type.
var instance = Activator.CreateInstance(typeContext.BuildingType);

var result1 = methodContext.BuildingMethod.Invoke(null, [1])
Console.WriteLine(result1); // Output: 1
var result2 = methodContext.BuildingMethod.Invoke(null, [2])
Console.WriteLine(result2); // Output: 3

Create a symbol for an argument: methodContext.Argument<int>(0).

Create a local variable: methodContext.Variable<int>().

Create a symbol for a literal value: methodContext.Value(123).

Supported literal types:

  • Integers: byte, sbyte, short, ushort, int, uint, long, ulong;
  • Floating points: float, double, decimal;
  • bool, char, string;
  • null for reference types.
  • Enumeration values.
  • Metadata: Type, FieldInfo, PropertyInfo, ConstructorInfo, MethodInfo;

Array Facade

// Use .AsArray() to convert a symbol of an array type to an array facade.
var array = methodContext.Argument<int[]>(0).AsArray();

var elementFromLiteralIndex = array[0]; // Get an element using a literal index.
var elementFromSymbolIndex = array[methodContext.Argument<int>(1)]; // Get an element using a index symbol.

If-Else

Following code can generate a method which is equal to (bool condition) => condition ? 1 : 0:

var methodContext = typeContext.Functors.Static("Test",
    [ParameterDefinition.Value<bool>()], ResultDefinition.Value<int>());
var argument = methodContext.Argument<bool>(0);
methodContext.If(argument,
    () =>
    {
        methodContext.Return(methodContext.Value(1));
    },
    () =>
    {
        methodContext.Return(methodContext.Value(0)); 
    });
methodContext.Return(methodContext.Value(-1));

Loop

For C# code like below:

int method(int arg)
{
    while (arg != 0)
    {
        arg -= 1;
    }
    return arg;
}

Corresponding code to generate such method is:

var methodContext = typeContext.Functors.Static("Test",
    [ParameterDefinition.Value<int>()], ResultDefinition.Value<int>());
var argument = methodContext.Argument<int>(0);
methodContext.While(
    methodContext.Expression(() =>
        argument.IsEqualTo(methodContext.Value(0)).Negate()),
    () => argument.SelfSubtract(1));
methodContext.Return(argument);

Showing the top 20 packages that depend on EmitToolbox.

Packages Downloads
InjectionExpert
A dependency injection library based on dynamic IL weaving.
5
SnapshotExpert
A library for automatic BSON/JSON snapshot serailization, with built-in support for reference tracking.
5
SnapshotExpert
A library for automatic BSON/JSON snapshot serailization, with built-in support for reference tracking.
4
InjectionExpert
A dependency injection library based on dynamic IL weaving.
3
InjectionExpert
A dependency injection library based on dynamic IL weaving.
2
InjectionExpert
A dependency injection library based on dynamic IL generation. It supports constructor injection and member injection.
2
SnapshotExpert
A library for automatic BSON/JSON snapshot serailization, with built-in support for reference tracking.
2
SnapshotExpert.Proxying
This package provides extensions for SnapshotExpert to serialize and deserialize calls. It provides generators for call-proxies which serialize calls, and call-handlers which deserialize calls and redirect it to the proxied method. This pacakge also includes serializers for CancellationToken, Task<T>, ValueTask<T>, etc.
2
InjectionExpert
A dependency injection library based on dynamic IL weaving.
1

.NET 9.0

Version Downloads Last updated
0.3.0-dev11212044 2 11/21/2025
0.3.0-dev11202301 2 11/20/2025
0.3.0-dev11201652 2 11/20/2025
0.3.0-dev11191711 2 11/19/2025
0.3.0-dev11191643 0 11/19/2025
0.3.0-dev11181957 0 11/18/2025
0.3.0-dev11172154 3 11/17/2025
0.3.0-dev11171854 2 11/17/2025
0.3.0-dev11171702 3 11/17/2025
0.3.0-dev11160018 3 11/15/2025
0.3.0-dev11141658 2 11/14/2025
0.3.0-dev11141604 1 11/14/2025
0.3.0-dev11140351 1 11/13/2025
0.3.0-dev11132343 2 11/13/2025
0.3.0-dev11132246 1 11/13/2025
0.3.0-dev11132222 1 11/13/2025
0.3.0-dev11132202 1 11/13/2025
0.3.0-dev11132140 1 11/13/2025
0.3.0-dev11122231 2 11/12/2025
0.3.0-dev11122058 1 11/12/2025
0.3.0-dev11122011 1 11/12/2025
0.3.0-dev11121942 1 11/12/2025
0.3.0-dev11121654 1 11/12/2025
0.3.0-dev11121458 0 11/12/2025
0.3.0-dev11120243 2 11/11/2025
0.3.0-dev11120233 1 11/11/2025
0.3.0-dev11120158 1 11/11/2025
0.3.0-dev11112101 2 11/11/2025
0.3.0-dev11112051 1 11/11/2025
0.3.0-dev11112024 1 11/11/2025
0.3.0-dev11111958 1 11/11/2025
0.3.0-dev11111926 1 11/11/2025
0.3.0-dev11111726 0 11/11/2025
0.3.0-dev11111655 1 11/11/2025
0.3.0-dev11111541 1 11/11/2025
0.3.0-dev11102348 1 11/10/2025
0.3.0-dev11100042 0 11/09/2025
0.3.0-dev09102111 6 09/10/2025
0.3.0-dev09101844 1 09/10/2025
0.3.0-dev09101818 1 09/10/2025
0.3.0-dev09101758 1 09/10/2025
0.3.0-dev09092305 2 09/09/2025
0.3.0-dev09092254 0 09/09/2025
0.3.0-dev09082132 2 09/08/2025
0.3.0-dev09082126 1 09/08/2025
0.3.0-dev09082103 1 09/08/2025
0.3.0-dev09062358 2 09/06/2025
0.2.4 3 09/03/2025
0.2.4-dev09060129 0 09/05/2025
0.2.4-dev09042030 4 09/04/2025
0.2.4-dev0904 1 09/04/2025
0.2.3 0 09/02/2025