Reflector
Reflection is awesome and super powerful, but also very slow and non-AOT compliant. Using source generators, we look to solve some of those pain points. This library gives you the power of reflection… without the actual reflection!
Features
Section titled “Features”- List Properties as well as what have getters and setters
- Read/Write Values using string keys and object values
- Easy property indexer for loose typing access (ie. myreflector[“MyProperty”] = 123)
- Fallback to reflection when a
reflector
is not available - Generate build variables of your choice into a static class for easy access
- Works with the MVVM Community Toolkit source generation
Using the following attribute and marking your class as partial
[Shiny.Reflector.ReflectorAttribute]public partial class MyClass{ public int MyProperty { get; set; } public string Message { get; set;}}
Just that attribute allows you to do this:
var myClass = new MySampleClass{ Name = "Hello World", Age = null};
// NOTE: the use of GetReflector - a reflector class is generated for each class marked with the ReflectorAttributevar reflector = myClass.GetReflector();foreach (var prop in reflector.Properties){ var objValue = reflector[prop.Name]; Console.WriteLine($"Property: {prop.Name} ({prop.Type}) - Current Value: {objValue}");}
// generics for type castingvar name = reflector.GetValue<string>("Name");Console.WriteLine("Reflector Name: " + name);
// indexers for loose typingConsole.WriteLine("Reflector Value: " + reflector["age"]);
// set with genericsreflector.SetValue("Age", 99);
// or just an object on the indexerreflector["name"] = "Something Else";Console.WriteLine("Reflector Name Value: " + reflector["NaMe"]);Console.WriteLine("Reflector Age Value: " + reflector["NaMe"]);
- Install the NuGet package
- Add the following
[Reflector]
attribute to your class and make sure it is marked aspartial
:[Shiny.Reflector.ReflectorAttribute]public partial class MyClass { ... } - Now you can use the
GetReflector()
(available on all objects) to get a reflector for that class (falls back to reflection if the reflector is not available):var reflector = myClass.GetReflector();
Assembly Info Generation
Section titled “Assembly Info Generation”You can also generate assembly information for your project by adding the following attribute to your AssemblyInfo.cs
file:
In your project file, you can add the following property to enable the generation of assembly info:
<Project> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <MyCustomVar>Hello World</MyCustomVar> </PropertyGroup>
<ItemGroup> <ReflectorItem Include="MyReflectorItem" Value="This is a sample value" Visible="false" />
<!--capture a build variable that we don't look for--> <ReflectorItem Include="PropertyGroupMyCustomVar" Value="$(MyCustomVar)" Visible="false" /> </ItemGroup></Project>
And a new AssemblyInfo static class with constants will be generated for you (NOTE: it grabbed defaulted variables like Company
, Version
, etc. from the project file):
public static class AssemblyInfo{ public const string Company = "Samples"; public const string Version = "1.0.0"; public const string TargetFramework = "net9.0"; public const string TargetFrameworkVersion = "v9.0"; public const string Platform = "AnyCPU"; public const string MyReflectorItem = "This is a sample value"; public const string PropertyGroupMyCustomVar = "Hello World";}
and now you can do easy things like this:
Console.WriteLine("Target Framework: " + AssemblyInfo.TargetFramework);Console.WriteLine("My Custom Var: " + AssemblyInfo.PropertyGroupMyCustomVar);
Using Reflector with the MVVM Community Toolkit
Section titled “Using Reflector with the MVVM Community Toolkit”If you are using the Community Toolkit MVVM and more specifically, the source generation that it uses. You need to do the following Reflector detects your properties.
-
In your
csproj
file, add the following:<PropertyGroup><LangVersion>preview</LangVersion></PropertyGroup> -
In your
ObservableObject
class, you can use theReflector
attribute. Note properties use the newer C# partial properties keyword.[Shiny.Reflector.ReflectorAttribute]public partial class MyObservableObject : ObservableObject{[ObservableProperty]public partial string MyProperty { get; set; }}