CodeBlanks Logo Icon CodeBlanks

Summary - Attributes

C# course · Advanced · Lesson 54/83

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

  1. Which class does a custom attribute derive from?

    • MemberInfo
    • Attribute
    • Type
    • MethodInfo
    Show answer

    Attribute — Correct. A custom attribute derives from Attribute.

  2. Match the element to its purpose

    AttributeUsage
    Target restriction
    GetCustomAttribute
    Reads
    Obsolete
    Marks as deprecated
    Conditional
    Call condition

All lessons in Advanced