Skip to main content

shiny-reflector

Generate code using Shiny Reflector for AOT-compliant, source-generated property access, JSON serialization, and assembly info generation in .NET applications

Ir para a instalação

Informações da origem

Repositório
shinyorg/skills
Última atividade na origem
15 de agosto de 2026 às 17:13
Idioma detectado do SKILL.md
inglês
Estrelas
4
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
3 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
shiny-reflector
description
Generate code using Shiny Reflector for AOT-compliant, source-generated property access, JSON serialization, and assembly info generation in .NET applications
auto_invoke
true
triggers
["reflector","reflection","ReflectorAttribute","IReflectorClass","IHasReflectorClass","GetReflector","PropertyGeneratedInfo","ReflectorJsonConverter","assembly info","AssemblyInfo","ReflectorItem","Shiny.Extensions.Reflector","source generated reflection","property access"]
# Shiny Reflector 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. ## When to Use This Skill Invoke this skill when the user wants to: - Add source-generated reflection to classes or records - Access properties dynamically without runtime reflection - Generate assembly info static classes from build properties - Use JSON serialization with source-generated reflectors - Integrate Shiny Reflector with MVVM Community Toolkit - Migrate from traditional .NET reflection to source-generated reflection - Configure MSBuild properties for Shiny Reflector ## Library Overview **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: - **AOT compliant** - No runtime reflection introspection needed - **Fast and zero-allocation** - Uses switch statements instead of reflection - **Easy to use** - Just add `[Reflector]` attribute and mark class as `partial` ### Core Concepts | 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 | ### Critical: Partial Class Requirement Classes and records using the `[Reflector]` attribute **must be declared as `partial`**. Without `partial`, you'll get compiler error `SHINYREFL001`: ```csharp [Reflector] public partial class MyClass // partial required! { public string Name { get; set; } public int Age { get; set; } } ``` This applies to records as well: ```csharp [Reflector] public partial record MyRecord(string Name, int Age); ``` ### Basic Setup **Install NuGet Package:** ```bash dotnet add package Shiny.Extensions.Reflector ``` The NuGet package includes both the runtime library and the source generator. No additional package is needed. ## Code Generation Instructions When generating code using Shiny Reflector, follow these conventions: ### 1. Reflector Classes Always mark classes as `partial` and apply `[Reflector]`: ```csharp using Shiny.Extensions.Reflector; [Reflector] public partial class MyModel { public string Name { get; set; } public int? Age { get; set; } public DateTime CreatedAt { get; set; } } ``` ### 2. Using the Generated Reflector Access properties through the generated reflector: ```csharp 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; ``` ### 3. Fallback to True Reflection For objects without `[Reflector]`, use the fallback: ```csharp var reflector = someObject.GetReflector(fallbackToTrueReflection: true); ``` ### 4. JSON Serialization Use `ReflectorJsonConverter` for reflection-free JSON: ```csharp // 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); ``` ### 5. Assembly Info Generation Configure in the project file: ```xml <Project> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> </PropertyGroup> <ItemGroup> <ReflectorItem Include="MyCustomVar" Value="Hello World" Visible="false" /> </ItemGroup> </Project> ``` This generates: ```csharp 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: ```csharp Console.WriteLine("Version: " + AssemblyInfo.Version); Console.WriteLine("Custom: " + AssemblyInfo.MyCustomVar); ``` ### 6. MVVM Community Toolkit Integration When using CommunityToolkit.Mvvm source generation with partial properties: ```xml <PropertyGroup> <LangVersion>preview</LangVersion> </PropertyGroup> ``` ```csharp [Reflector] public partial class MyViewModel : ObservableObject { [ObservableProperty] public partial string MyProperty { get; set; } } ``` ### 7. File Organization - Models: Place in `Models/` or domain-appropriate folders - Keep `[Reflector]` classes focused - one per file when possible ## Usage Examples **Property enumeration:** ```csharp var reflector = myObject.GetReflector(); foreach (var prop in reflector.Properties) { var value = reflector[prop.Name]; Console.WriteLine($"{prop.Name}: {value}"); } ``` **Safe property access:** ```csharp 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:** ```csharp 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]); } ``` ## Best Practices 1. **Always use `partial`** - Required for source generation; without it you get `SHINYREFL001` 2. **Prefer source-generated reflectors** - Only use `fallbackToTrueReflection` when working with unattributed types 3. **Use typed access** - Prefer `GetValue<T>()` and `SetValue<T>()` over indexers for type safety 4. **Property names are case-insensitive** - `reflector["name"]` and `reflector["Name"]` are equivalent 5. **Records work too** - Both classes and records support `[Reflector]`, but records must use `partial` keyword 6. **Use `ReflectorJsonConverter` factory** - Register `new ReflectorJsonConverter()` (non-generic) for broad coverage 7. **Assembly info is auto-generated** - Common properties (Company, Version, TargetFramework, etc.) are captured by default ## MSBuild Configuration | 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 | ## Reference Files For detailed templates and examples, see: - `reference/templates.md` - Code generation templates for reflector classes - `reference/api-reference.md` - Full API surface, interfaces, and configuration
Ver no GitHub