EmitToolbox 0.2.3
dotnet add package EmitToolbox --version 0.2.3
NuGet\Install-Package EmitToolbox -Version 0.2.3
<PackageReference Include="EmitToolbox" Version="0.2.3" />
<PackageVersion Include="EmitToolbox" Version="0.2.3" />
<PackageReference Include="EmitToolbox" />
paket add EmitToolbox --version 0.2.3
#r "nuget: EmitToolbox, 0.2.3"
#:package EmitToolbox@0.2.3
#addin nuget:?package=EmitToolbox&version=0.2.3
#tool nuget:?package=EmitToolbox&version=0.2.3
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);
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- JetBrains.Annotations (>= 2025.2.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on EmitToolbox:
Package | Downloads |
---|---|
InjectionExpert
A dependency injection library based on dynamic IL weaving. |
GitHub repositories
This package is not used by any popular GitHub repositories.