Help us improve
Share bugs, ideas, or general feedback.
From shiny-extensions
Generates AOT-compliant, source-generated reflection code for .NET. Provides dynamic property access, JSON serialization, and assembly info without runtime overhead. Activates on reflection-related queries.
npx claudepluginhub shinyorg/extensions --plugin shiny-extensionsHow this skill is triggered — by the user, by Claude, or both
Slash command
/shiny-extensions:shiny-reflectorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert in Shiny Reflector, a high-performance reflection library for .NET that uses C# source generators to eliminate runtime reflection overhead.
Creates p5.js generative art with seeded randomness, noise fields, and interactive parameter exploration. Use for algorithmic art, flow fields, or particle systems.
Share bugs, ideas, or general feedback.
You are an expert in Shiny Reflector, a high-performance reflection library for .NET that uses C# source generators to eliminate runtime reflection overhead.
Invoke this skill when the user wants to:
Repository: https://github.com/shinyorg/reflector
NuGet: Shiny.Extensions.Reflector
Namespace: Shiny.Extensions.Reflector
Shiny Reflector gives you the power of reflection without the actual reflection. It is:
[Reflector] attribute and mark class as partial| Concept | Description |
|---|---|
[Reflector] attribute | Marks a class/record for source generation |
IReflectorClass | Interface for accessing properties dynamically |
IHasReflectorClass | Marker interface auto-implemented on attributed classes |
PropertyGeneratedInfo | Metadata record for each property (Name, Type, HasSetter) |
ReflectorJsonConverter | System.Text.Json converter using reflectors |
| Assembly Info Generation | Auto-generates static class with build constants |
Classes and records using the [Reflector] attribute must be declared as partial. Without partial, you'll get compiler error SHINYREFL001:
[Reflector]
public partial class MyClass // partial required!
{
public string Name { get; set; }
public int Age { get; set; }
}
This applies to records as well:
[Reflector]
public partial record MyRecord(string Name, int Age);
Install NuGet Package:
dotnet add package Shiny.Extensions.Reflector
The NuGet package includes both the runtime library and the source generator. No additional package is needed.
When generating code using Shiny Reflector, follow these conventions:
Always mark classes as partial and apply [Reflector]:
using Shiny.Extensions.Reflector;
[Reflector]
public partial class MyModel
{
public string Name { get; set; }
public int? Age { get; set; }
public DateTime CreatedAt { get; set; }
}
Access properties through the generated reflector:
var model = new MyModel { Name = "Hello", Age = 25 };
var reflector = model.GetReflector();
// Enumerate properties
foreach (var prop in reflector.Properties)
{
Console.WriteLine($"{prop.Name} ({prop.Type.Name}) HasSetter={prop.HasSetter}");
}
// Typed access
var name = reflector.GetValue<string>("Name");
// Indexer access (case-insensitive)
var age = reflector["age"];
// Set values
reflector.SetValue("Name", "Updated");
reflector["Age"] = 30;
For objects without [Reflector], use the fallback:
var reflector = someObject.GetReflector(fallbackToTrueReflection: true);
Use ReflectorJsonConverter for reflection-free JSON:
// Generic converter for a specific type
var options = new JsonSerializerOptions();
options.Converters.Add(new ReflectorJsonConverter<MyModel>());
// Or factory converter for all types
options.Converters.Add(new ReflectorJsonConverter());
var json = JsonSerializer.Serialize(model, options);
var deserialized = JsonSerializer.Deserialize<MyModel>(json, options);
Configure in the project file:
<Project>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ReflectorItem Include="MyCustomVar"
Value="Hello World"
Visible="false" />
</ItemGroup>
</Project>
This generates:
public static class AssemblyInfo
{
public const string Company = "MyCompany";
public const string Version = "1.0.0";
public const string TargetFramework = "net9.0";
public const string MyCustomVar = "Hello World";
}
Usage:
Console.WriteLine("Version: " + AssemblyInfo.Version);
Console.WriteLine("Custom: " + AssemblyInfo.MyCustomVar);
When using CommunityToolkit.Mvvm source generation with partial properties:
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
[Reflector]
public partial class MyViewModel : ObservableObject
{
[ObservableProperty]
public partial string MyProperty { get; set; }
}
Models/ or domain-appropriate folders[Reflector] classes focused - one per file when possibleProperty enumeration:
var reflector = myObject.GetReflector();
foreach (var prop in reflector.Properties)
{
var value = reflector[prop.Name];
Console.WriteLine($"{prop.Name}: {value}");
}
Safe property access:
var reflector = myObject.GetReflector();
if (reflector.TryGetValue<string>("Name", out var name))
Console.WriteLine($"Name = {name}");
if (reflector.HasProperty("Email"))
reflector["Email"] = "new@example.com";
Dynamic property copying:
var source = sourceObject.GetReflector();
var target = targetObject.GetReflector();
foreach (var prop in source.Properties)
{
if (target.HasProperty(prop.Name))
target.TrySetValue(prop.Name, source[prop.Name]);
}
partial - Required for source generation; without it you get SHINYREFL001fallbackToTrueReflection when working with unattributed typesGetValue<T>() and SetValue<T>() over indexers for type safetyreflector["name"] and reflector["Name"] are equivalent[Reflector], but records must use partial keywordReflectorJsonConverter factory - Register new ReflectorJsonConverter() (non-generic) for broad coverage| Property | Default | Purpose |
|---|---|---|
ShinyReflectorUseInternalAccessors | false | Generate internal vs public accessors |
ShinyReflectorGenerateAssemblyInfo | true | Enable/disable AssemblyInfo generation |
ShinyReflectorAssemblyInfoClassName | AssemblyInfo | Class name for generated constants |
ShinyReflectorAssemblyInfoNamespace | Root namespace | Namespace for generated AssemblyInfo |
For detailed templates and examples, see:
reference/templates.md - Code generation templates for reflector classesreference/api-reference.md - Full API surface, interfaces, and configuration