EmitToolbox 0.3.0-dev11171702

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.

Concepts

  • 'DynamicAssembly': Builder for defining dynamic assemblies. It can define classes and structs.
  • 'DynamicType': Builder for defining dynamic types. Use it to create DynamicMethod, DynamicField and DynamicProperty instances.
  • 'DynamicMethod': Builder for defining the code of dynamic methods. This framework provides extensions methods to
  • 'DynamicField': Builder for defining dynamic fields.
  • 'DynamicProperty': Builder for defining dynamic properties and corresponding setters and getters.

Usage

Create a Dynamic Assembly

Use the following code to create an executable dynamic assembly:

var assembly = DynamicAssembly.DefineExecutable("SampleAssembly");

Or you can create an assembly that can be exported to a file but cannot be executed directly:

var assembly = DynamicAssembly.DefineExportable("SampleAssembly");

// ...

assemly.Export("./MyDynamicAssembly.dll");

Basic Example

using EmitToolbox.Framework;
using EmitToolbox.Framework.Extensions;
using EmitToolbox.Framework.Symbols;

var assembly = DynamicAssembly.DefineExecutable("SampleAssembly");
var type = assembly.DefineClass("SampleClass");

// Define an instance field named 'Backing' of type 'int'
var backingField = type.FieldFactory.DefineInstance(typeof(int), "Backing");
// Define an instance property named 'Value' of type 'int'
var valueProperty = type.PropertyFactory.DefineInstance<int>("Value");

// Define and bind getter accessor for the property
var getter = type.MethodFactory.Instance.DefineFunctor<int>(
    "get_Value", [], hasSpecialName: true);

// Get the 'this' instance symbol.
// This symbol is used to access the instance field in the method body.
var thisSymbol = getter.This();
// Convert the dynamic field into a symbol than can be used in the method building context
// by binding it to the 'getter' method and 'this' instance.
var fieldSymbol = backingField.SymbolOf<int>(getter, thisSymbol);

// Return the value of the field + 1.
// Here, extension operator '+' for 'ISymbol<int>' is used.
// Use the namespace 'EmitToolbox.Framework.Extensions' to access these extension methods.
// 'getter.Value(1)' is to create a literal symbol that represents the value 1.
getter.Return(fieldSymbol + getter.Value(1));

// Bind the 'getter' method as the getter accessor of this property.
valueProperty.BindGetter(getter);
// After building this type, the type and its methods, fields, and properties can be used.
type.Build();

// Following example is about to use this type throw reflection.
// Usually, the built types implement interfaces, and they should be used as interfaces for better performance.
// This part is only for demonstration purpose.

// Instantiate an instance of the built type.
var instance = Activator.CreateInstance(type.BuildingType)!;
// Create a functor from the getter accessor of the property.
var functor = valueProperty.Getter!.BuildingMethod.CreateDelegate<Func<int>>(testInstance);

// Using reflection to set the value of the backing field to 1.
backingField.BuildingField.SetValue(instance, 1);
// Then invoke the functor, the result should be 3.
var result = functor(2);

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

[Version 0.3.0]

This version introduces a new framework which is not compatible to previous version. It relies more on interfaces rather than abstract classes to describe symbols.

Meanwhile, we realized that only providing support at a high abstraction level is not enough (generic symbols and methods), even though it significantly reduces the risk of wrong usage. Therefore, this framework has more support for low-level constructs:

  • Most symbols and methods now support non-generic symbols.
  • Infrastructures of 'System.Runtime.Emit' (e.g., 'TypeBuilder', 'MethodBuilder') are now publicly accessible.

Breaking Changes:

  • '...BuildingContext' classes are now renamed as 'Dynamic...'.
  • 'ValueType' of symbols are now renamed to 'ContentType'; it now represents the actual type of that a symbol holds, thus, it can be a reference type.

Problem Fixes:

  • Code for loading/storing references is now fixed.
  • Now overriding methods with 'out' parameters no longer causes exceptions to signature mismatching.

.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