com.IvanMurzak.ReflectorNet
5.4.0
dotnet add package com.IvanMurzak.ReflectorNet --version 5.4.0
NuGet\Install-Package com.IvanMurzak.ReflectorNet -Version 5.4.0
<PackageReference Include="com.IvanMurzak.ReflectorNet" Version="5.4.0" />
<PackageVersion Include="com.IvanMurzak.ReflectorNet" Version="5.4.0" />
<PackageReference Include="com.IvanMurzak.ReflectorNet" />
paket add com.IvanMurzak.ReflectorNet --version 5.4.0
#r "nuget: com.IvanMurzak.ReflectorNet, 5.4.0"
#:package com.IvanMurzak.ReflectorNet@5.4.0
#addin nuget:?package=com.IvanMurzak.ReflectorNet&version=5.4.0
#tool nuget:?package=com.IvanMurzak.ReflectorNet&version=5.4.0
ReflectorNet
ReflectorNet is a .NET reflection toolkit for dynamic automation, AI-assisted tooling, testing, and runtime inspection. It can serialize live objects with type metadata, deserialize them back, modify existing instances in place, inspect object graphs by path or pattern, generate JSON Schema, and discover or invoke methods from partial runtime descriptions.
The main entry point is Reflector. The central data model is SerializedMember, a JSON-friendly representation of a .NET value that preserves the member name, resolved type, fields, properties, and raw JSON value payload.
Index
- ReflectorNet
Why ReflectorNet
Standard reflection is powerful, but it is low-level. ReflectorNet wraps reflection in higher-level operations that are useful when the caller does not have a compiled, strongly typed integration path.
Key capabilities:
- Type-preserving serialization through
SerializedMember. - Full object reconstruction with flexible type resolution.
- In-place object modification without replacing the root reference.
- Path-based reads and writes for fields, properties, list items, array items, and dictionary entries.
- JSON Merge Patch style updates for multi-field modifications.
- Regex-based object graph search with
Grep. - JSON Schema generation for types, method arguments, and method return values.
- Fuzzy method discovery and dynamic invocation through
MethodRefandMethodCall. - Extensible reflection and JSON converter registries.
- Optional type blacklisting for excluding unsafe, irrelevant, or expensive types from reflection workflows.
Installation
dotnet add package com.IvanMurzak.ReflectorNet
Target Frameworks
The library targets:
netstandard2.1net8.0net9.0
The test suite targets net8.0 and net9.0.
Quick Start
using System.Collections.Generic;
using com.IvanMurzak.ReflectorNet;
using com.IvanMurzak.ReflectorNet.Model;
using com.IvanMurzak.ReflectorNet.Utils;
var reflector = new Reflector();
var player = new PlayerState
{
Name = "Ada",
Level = 7,
Inventory = new Inventory
{
Items = new List<ItemStack>
{
new ItemStack { ItemId = "health_potion", Quantity = 3 }
}
}
};
SerializedMember snapshot = reflector.Serialize(player);
PlayerState? copy = reflector.Deserialize<PlayerState>(snapshot);
object? liveObject = player;
var logs = new Logs();
reflector.TryModifyAt<int>(
ref liveObject,
"Inventory/Items/[0]/Quantity",
10,
logs: logs);
reflector.TryReadAt(
liveObject,
"Inventory/Items/[0]/Quantity",
out SerializedMember? quantity);
Console.WriteLine(quantity?.GetValue<int>(reflector));
public sealed class PlayerState
{
public string Name { get; set; } = string.Empty;
public int Level { get; set; }
public Inventory Inventory { get; set; } = new Inventory();
}
public sealed class Inventory
{
public List<ItemStack> Items { get; set; } = new List<ItemStack>();
}
public sealed class ItemStack
{
public string ItemId { get; set; } = string.Empty;
public int Quantity { get; set; }
}
Core Features
Type-Preserving Serialization
Reflector.Serialize turns a live object into a SerializedMember. For complex objects, fields and properties are represented as nested SerializedMember entries. Primitive and converter-backed values are stored in the value JSON payload.
var data = reflector.Serialize(player, name: "player");
string json = reflector.JsonSerializer.Serialize(data);
Reflector.Deserialize reconstructs the object from that representation.
var restored = reflector.Deserialize<PlayerState>(data);
ReflectorNet also tracks visited objects during serialization and can emit $ref entries for repeated references, helping avoid endless recursion in cyclic object graphs.
In-Place Modification
TryModify applies a SerializedMember onto an existing object instance.
object? target = player;
var patch = new SerializedMember
{
typeName = typeof(PlayerState).GetTypeId()
};
patch.SetPropertyValue(reflector, "Level", 8);
bool ok = reflector.TryModify(ref target, patch, logs: logs);
This is useful for stateful systems such as games, editors, services, and test harnesses where keeping object identity matters.
Path Syntax
Path-based APIs use slash-delimited paths:
| Segment | Meaning | Example |
|---|---|---|
Name |
Field or property | Inventory |
[0] |
Array or IList index |
Items/[0] |
[key] |
Dictionary key | Settings/[timeout] |
A leading #/ is accepted and stripped, which makes paths compatible with SerializationContext reference paths.
Object Inspection
TryReadAt
TryReadAt navigates to one value and serializes only that target.
if (reflector.TryReadAt(player, "Inventory/Items/[0]/ItemId", out var itemId))
{
Console.WriteLine(itemId!.GetValue<string>(reflector));
}
Invalid paths return false and write details into Logs when supplied.
View
View returns a serialized tree for the whole object or a navigated subtree, with optional filters.
SerializedMember? view = reflector.View(player, new ViewQuery
{
Path = "Inventory",
NamePattern = "Item|Quantity",
MaxDepth = 3
});
ViewQuery supports:
| Option | Description |
|---|---|
Path |
Navigate before serialization. |
MaxDepth |
Limit the returned tree depth. 0 returns only the root envelope. |
NamePattern |
Case-insensitive .NET regex matched against field and property names. |
TypeFilter |
Keep branches whose resolved type is assignable to the supplied Type. |
When filters match nothing, View keeps the root envelope so callers still know what object type was inspected.
Grep
Grep searches the live object graph for matching field or property names and returns flat path/value matches.
IReadOnlyList<ViewMatch> matches = reflector.Grep(player, "^Quantity$");
foreach (var match in matches)
{
Console.WriteLine($"{match.Path}: {match.Value.GetValue<int>(reflector)}");
}
Use Grep when you need to search inside arrays or lists. View filters the serialized tree; Grep walks the live object graph.
Object Modification
TryModifyAt
TryModifyAt changes one target path without touching sibling values.
object? target = player;
reflector.TryModifyAt<int>(
ref target,
"Inventory/Items/[0]/Quantity",
12,
logs: logs);
The same path syntax works for object members, lists, arrays, and dictionaries. For dictionaries, missing keys can be added when the key can be converted to the dictionary key type.
You can also apply a partial SerializedMember to a complex node:
var itemPatch = new SerializedMember
{
typeName = typeof(ItemStack).GetTypeId()
};
itemPatch.SetPropertyValue(reflector, "Quantity", 20);
reflector.TryModifyAt(
ref target,
"Inventory/Items/[0]",
itemPatch,
logs: logs);
TryPatch
TryPatch applies a JSON Merge Patch style document. It is useful when multiple values need to be updated in one call.
reflector.TryPatch(ref target, """
{
"Level": 9,
"Inventory": {
"Items": {
"[0]": {
"Quantity": 15
}
}
}
}
""", logs: logs);
Patch behavior:
- JSON object keys navigate into fields, properties, array/list indexes, or dictionary keys.
- JSON scalar values set the current value.
nullsets the current value tonullwhen the target type allows it.$typecan request a compatible subtype replacement before applying the remaining keys.- Invalid JSON, unknown members, incompatible type hints, read-only properties, and failed key conversions return
falseand are reported throughLogs.
Dynamic Method Workflows
Find Methods
FindMethod searches loaded assemblies for methods matching a MethodRef. Matching can be exact or fuzzy.
using com.IvanMurzak.ReflectorNet.Model;
var filter = new MethodRef
{
Namespace = typeof(PlayerCommands).Namespace,
TypeName = "PlayerCommands",
MethodName = "GrantItem"
};
var methods = reflector.FindMethod(
filter,
knownNamespace: true,
typeNameMatchLevel: 6,
methodNameMatchLevel: 6);
String match levels:
| Level | Match |
|---|---|
6 |
Exact, case-sensitive |
5 |
Exact, case-insensitive |
4 |
Prefix, case-sensitive |
3 |
Prefix, case-insensitive |
2 |
Contains, case-sensitive |
1 |
Contains, case-insensitive |
0 |
Disabled |
Parameter matching can also be enabled with parametersMatchLevel.
Invoke Methods
MethodCall combines method discovery, parameter deserialization, target instance handling, invocation, and JSON result formatting.
var args = new SerializedMemberList
{
reflector.Serialize("health_potion", name: "itemId"),
reflector.Serialize(2, name: "quantity")
};
string result = reflector.MethodCall(
reflector,
new MethodRef
{
TypeName = "PlayerCommands",
MethodName = "GrantItem"
},
inputParameters: args,
executeInMainThread: false);
For instance methods, pass targetObject as a serialized object. If no target is supplied, ReflectorNet attempts to create an instance of the declaring type.
JSON Schema Generation
ReflectorNet can generate JSON Schema for types and methods. This is especially useful for AI function calling, tooling UIs, runtime validation, and API documentation.
using System.Reflection;
var typeSchema = reflector.GetSchema<PlayerState>();
var typeRef = reflector.GetSchemaRef<PlayerState>();
MethodInfo method = typeof(PlayerCommands).GetMethod(nameof(PlayerCommands.GrantItem))!;
var inputSchema = reflector.GetArgumentsSchema(method);
var outputSchema = reflector.GetReturnSchema(method);
Schema generation supports:
- Fields and properties discovered through the reflection converter chain.
- Primitive, collection, dictionary, generic, and nested types.
$defsreuse for complex types.- Nullable and optional method parameter handling.
- Return type unwrapping for
Task<T>andValueTask<T>. - Descriptions from
DescriptionAttribute. - Custom schema output through
IJsonSchemaConverter.
Converters and Extensibility
ReflectorNet uses a priority-based converter registry. Each IReflectionConverter reports how well it can handle a type, and the registry selects the highest-priority converter.
Default reflection converters include:
PrimitiveReflectionConverterfor primitive and common value types.ArrayReflectionConverterfor arrays and list-like collections.GenericReflectionConverter<object>for ordinary classes and structs.TypeReflectionConverterforSystem.Type.AssemblyReflectionConverterforSystem.Reflection.Assembly.
Register a reflection converter when a type needs custom object traversal, creation, or mutation behavior:
using com.IvanMurzak.ReflectorNet.Converter;
reflector.Converters.Add(new MyReflectionConverter());
Register a JSON converter when a type needs custom JSON transport or schema behavior:
reflector.JsonSerializer.AddConverter(new MyJsonConverter());
Useful built-in extension points:
GenericReflectionConverter<T>for normal custom object handling.LazyGenericReflectionConverterfor optional runtime dependencies resolved by type name.IgnoreFieldsAndPropertiesReflectionConverter<T>for treating selected types as shallow or read-only.IJsonSchemaConverterandJsonSchemaConverter<T>for custom JSON Schema definitions.
Types can be excluded from reflection processing through the registry blacklist:
reflector.Converters.BlacklistType(typeof(ExpensiveRuntimeType));
reflector.Converters.BlacklistTypes("Some.Namespace.InternalType");
reflector.Converters.BlacklistTypeInAssembly("MyCompany.Game", "MyCompany.Game.SecretState");
Blacklist checks include inheritance, implemented interfaces, arrays, and generic type arguments.
Project Layout
ReflectorNet/
ReflectorNet/ Main library project
ReflectorNet.Tests/ xUnit tests
ReflectorNet.Tests.OuterAssembly/ Cross-assembly test models
ConsoleApp/ Manual schema and behavior checks
docs/ Maintainer notes and architecture documentation
commands/ Release and version helper scripts
Important library areas:
src/Reflector/contains theReflectorpartial class split by responsibility.src/Model/containsSerializedMember,SerializedMemberList,MethodRef,MethodData,Logs, and view models.src/Converter/Reflection/contains the reflection converter chain.src/Converter/Json/contains System.Text.Json converters and schema-aware converters.src/Utils/Json/contains JSON serialization and schema generation utilities.
Development
Restore and build:
dotnet restore
dotnet build ReflectorNet.sln
Run tests:
dotnet test ReflectorNet.sln
Create a NuGet package locally:
dotnet pack ReflectorNet/ReflectorNet.csproj -c Release
License
ReflectorNet is licensed under the Apache License 2.0. See LICENSE for details.
Copyright (c) Ivan Murzak.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.Extensions.Logging (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Microsoft.Extensions.Logging (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
-
net9.0
- Microsoft.Extensions.Logging (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
NuGet packages (14)
Showing the top 5 NuGet packages that depend on com.IvanMurzak.ReflectorNet:
| Package | Downloads |
|---|---|
|
com.IvanMurzak.McpPlugin.Common
McpPlugin common code for McpPlugin and McpPlugin.Server projects. It is .NET Library project for integration MCP server features into any dotnet application. It connects automatically with MCP server and exposes it's API over TCP connection in runtime. When MCP server interacts with AI. |
|
|
com.IvanMurzak.McpPlugin
McpPlugin is a .NET Library project for integration MCP server features into any dotnet application. It connects automatically with MCP server and exposes it's API over TCP connection in runtime. When MCP server interacts with AI. This library maintains a local application. |
|
|
com.IvanMurzak.McpPlugin.Server
MCP Server dotnet. Model Context Protocol server that interacts with MCP Plugin integrated into any dotnet application. |
|
|
com.IvanMurzak.Unity.MCP.Common
Shared code between Unity-MCP-Plugin and Unity-MCP-Server projects. |
|
|
com.IvanMurzak.Godot.MCP.PhantomCamera
AI MCP tools for Godot PhantomCamera. |
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on com.IvanMurzak.ReflectorNet:
| Repository | Stars |
|---|---|
|
IvanMurzak/Unity-MCP
AI Skills, MCP Tools, and CLI for Unity Engine. Full AI develop and test loop. Use cli for quick setup. Efficient token usage, advanced tools. Any C# method may be turned into a tool by a single line. Works with Claude Code, Gemini, Copilot, Cursor and any other absolutely for free.
|
|
|
IvanMurzak/Godot-MCP
Godot-MCP — Model Context Protocol (MCP) integration for the Godot Engine. AI tools for the Godot Editor in C#, with cloud connection to ai-game.dev. Apache-2.0.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 5.4.0 | 3,260 | 7/28/2026 |
| 5.3.3 | 367 | 7/27/2026 |
| 5.3.2 | 9,470 | 7/11/2026 |
| 5.3.1 | 20,646 | 6/2/2026 |
| 5.3.0 | 417 | 6/2/2026 |
| 5.2.0 | 3,603 | 5/27/2026 |
| 5.1.2 | 2,586 | 5/21/2026 |
| 5.1.1 | 8,943 | 4/29/2026 |
| 5.1.0 | 457 | 4/29/2026 |
| 5.0.0 | 6,948 | 4/16/2026 |
| 4.1.0 | 1,096 | 3/25/2026 |
| 4.0.0 | 2,354 | 3/3/2026 |
| 3.12.1 | 1,480 | 2/12/2026 |
| 3.12.0 | 722 | 1/31/2026 |
| 3.11.0 | 624 | 1/20/2026 |
| 3.10.0 | 545 | 1/19/2026 |
| 3.9.0 | 527 | 1/18/2026 |
| 3.8.1 | 508 | 1/18/2026 |
| 3.8.0 | 520 | 1/18/2026 |
| 3.7.1 | 564 | 1/17/2026 |