Summary - Attributes
Combine custom attribute and reflection to write a command handler.
Summary - Attributes
In this group you learned attribute basics, writing custom attributes, reading them with reflection, positional and named parameters and built-in attributes. By writing a custom attribute and reading it with reflection, you can build behavioral systems like a command handler.
Now you will combine these to write a command handler: first define a [Command] attribute and apply it to a method, then read the attribute via reflection and invoke the method.
Exercise Find a method by Command attribute
Define the CommandAttribute class below: mark it with [AttributeUsage(AttributeTargets.Method)], derive from Attribute, add a Name property and a constructor taking string name. Apply [Command("hello")] to the Hello method in Handler. In Main, iterate each method with Attribute.GetCustomAttribute(m, typeof(CommandAttribute)) as CommandAttribute and when the attribute is present print Console.WriteLine(attr.Name).
Show example solution
[AttributeUsage(AttributeTargets.Method)] public class CommandAttribute : Attribute { public string Name { get; set; } public CommandAttribute(string name) { Name = name; } }. Add [Command("hello")] to Hello. In Main: foreach (var m in typeof(Handler).GetMethods()) { var attr = Attribute.GetCustomAttribute(m, typeof(CommandAttribute)) as CommandAttribute; if (attr != null) { Console.WriteLine(attr.Name); } }
Example solution:
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method)]
public class CommandAttribute : Attribute
{
public string Name { get; set; }
public CommandAttribute(string name) { Name = name; }
}
class Handler
{
[Command("hello")]
public void Hello() { }
}
class Program
{
static void Main()
{
foreach (var m in typeof(Handler).GetMethods())
{
var attr = Attribute.GetCustomAttribute(m, typeof(CommandAttribute)) as CommandAttribute;
if (attr != null)
{
Console.WriteLine(attr.Name);
}
}
}
}
Exercise Invoke a command method
Apply [Command("hello")] to the Hello method in the Handler class below. In Main, create Handler h = new Handler();. Iterate with GetMethods; when attr.Name == "hello" call m.Invoke(h, null) to invoke the method.
Show example solution
foreach (var m in typeof(Handler).GetMethods()) { var attr = Attribute.GetCustomAttribute(m, typeof(CommandAttribute)) as CommandAttribute; if (attr != null && attr.Name == "hello") { m.Invoke(h, null); } }
Example solution:
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method)]
public class CommandAttribute : Attribute
{
public string Name { get; set; }
public CommandAttribute(string name) { Name = name; }
}
class Handler
{
[Command("hello")]
public void Hello() => Console.WriteLine("Hello world!");
}
class Program
{
static void Main()
{
Handler h = new Handler();
foreach (var m in typeof(Handler).GetMethods())
{
var attr = Attribute.GetCustomAttribute(m, typeof(CommandAttribute)) as CommandAttribute;
if (attr != null && attr.Name == "hello")
{
m.Invoke(h, null);
}
}
}
}
Test yourself
-
Which class does a custom attribute derive from?
- MemberInfo
- Attribute
- Type
- MethodInfo
Show answer
Attribute — Correct. A custom attribute derives from Attribute.
-
Match the element to its purpose
- AttributeUsage
- Target restriction
- GetCustomAttribute
- Reads
- Obsolete
- Marks as deprecated
- Conditional
- Call condition