13. Attributes & Reflection


Part 1: Understanding the Metadata System

The Big Picture


┌────────────────────────────────────────────────────┐
│ METADATA SYSTEM                                    │
│                                                    │
│ ┌──────────────┐         ┌──────────────┐          │
│ │ ATTRIBUTES   │────────>│ REFLECTION   │          │
│ │ (Add data)   │         │ (Read data)  │          │
│ └──────────────┘         └──────────────┘          │
│        │                        │                  │
│        │                        │                  │
│        v                        v                  │
│  [Validation]         GetCustomAttribute()         │
│  [Route("api")]       GetProperties()              │
│  [Obsolete]           GetMethods()                 │
│  [Serializable]       Activator.CreateInstance()   │
│                                                    │
└────────────────────────────────────────────────────┘

What Are Attributes?

Simple Definition: Tags you put on code (classes, methods, properties) to add metadata

Think of it like: Sticky notes on code that frameworks can read later

Key Point: Attributes do NOTHING by themselves. Something else (framework or your code) must READ them using Reflection.

What Is Reflection?

Definition: Examining and manipulating code at runtime

Common Uses:

  • Read attributes

  • Get type information

  • Create instances dynamically

  • Invoke methods dynamically

  • Access private members (testing)

Namespace: System.Reflection


Part 2: Built-in Attributes

1. [Obsolete] - Mark Old Code

2. [Serializable] - Allow Serialization

3. [DllImport] - Call Native Code

4. [CallerMemberName] - Get Caller Info

5. [Flags] - Enum as Bit Flags

6. [Conditional] - Conditional Compilation


Part 3: Creating Custom Attributes

Step 1: Define Attribute Class

Rules:

  1. Must inherit from System.Attribute

  2. Name should end with "Attribute" (convention)

  3. Add [AttributeUsage] to specify where it can be used

Step 2: Control Where Attribute Can Be Used

AttributeTargets Options

Step 3: Using Custom Attributes


Part 4: Reflection Basics

Getting Type Information

Reflection Classes


Part 5: Reading Attributes

Understanding Attribute Retrieval Methods

Method
Returns
Use When

GetCustomAttribute<T>()

Single T or null

Expect ONE attribute

GetCustomAttributes<T>()

IEnumerable

Expect MULTIPLE attributes

GetCustomAttributes(type, inherit)

object[]

Legacy, needs casting

IsDefined(type, inherit)

bool

Just checking existence

Single Attribute on Class

Multiple Attributes on Class

Attributes on Properties

Attributes on Methods

Attributes on Parameters


Part 6: Attribute Filtering Patterns

Pattern 1: Find All Classes with Specific Attribute

Pattern 2: Find Classes Where Attribute Matches Condition

Pattern 3: Get All Attribute Values Across All Classes

Pattern 4: Group Classes by Attribute Value

Pattern 5: Complex Filtering (Version Range)


Part 7: Common Mistakes & Best Practices

❌ Mistake 1: Forgetting to Cast (Legacy Method)

❌ Mistake 2: Using Singular Method for Multiple Attributes

❌ Mistake 3: Not Checking for Null/Empty

✅ Best Practice: Use Generic Methods


Part 8: Real-World Patterns

Pattern 1: Validation Framework

Pattern 2: Simple ORM (Object-Relational Mapping)

Pattern 3: API Route Registration


Part 9: Working with Types

Creating Instances Dynamically

Invoking Methods Dynamically

Getting/Setting Properties Dynamically

Working with Generic Types


Part 10: Performance Considerations

Reflection is SLOW

Caching Pattern


Part 11: Common Reflection Methods Reference

Type Information

Attributes

Constructors

Properties

Methods

Fields

Assemblies


Quick Reference Summary

When to Use Attributes

Use for:

  • Validation rules

  • API routing

  • Database mapping

  • Serialization control

  • Testing metadata

  • Configuration

Don't use for:

  • Business logic (use methods)

  • Performance-critical paths

When to Use Reflection

Use for:

  • Framework/library code

  • Plugin systems

  • ORM implementation

  • Dependency injection

  • Test frameworks

  • Code generation tools

Don't use for:

  • Application code (usually)

  • Tight loops (cache results)

How Frameworks Use This

ASP.NET Core:

  • Reads [HttpGet] to register routes

  • Reads [Required] to validate

Entity Framework:

  • Reads [Table], [Column] to generate SQL

Dependency Injection:

  • Uses reflection to create instances


Guide Complete! You now have a comprehensive Attributes & Reflection reference! 🏷️

Last updated