EmitToolbox 0.3.0-dev09082132

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