EmitToolbox 0.2.4-dev09042030
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;nullfor 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
- JetBrains.Annotations (>= 2025.2.0)