Menu
Coddy logo textTech

어트리뷰트와 리플렉션

Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 44번째.

어트리뷰트(Attributes)는 클래스, 메서드 또는 속성과 같은 코드 요소에 첨부하는 메타데이터 태그입니다. 이는 코드가 실행되는 방식에 직접적인 영향을 주지는 않지만, 런타임에 읽을 수 있는 정보를 제공합니다. 리플렉션(Reflection)은 이러한 메타데이터를 읽는 메커니즘입니다.

대상 요소 위의 대괄호 안에 속성을 배치하여 적용합니다:

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Serializable]
public class Person
{
    public string Name { get; set; }
}

Attribute를 상속받아 사용자 정의 특성을 만들 수 있습니다:

public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}

[Author("John")]
public class Calculator { }

리플렉션(Reflection)을 사용하면 System.Reflection 네임스페이스를 사용하여 런타임에 타입을 검사하고 특성(attribute)을 읽을 수 있습니다:

Type type = typeof(Calculator);
var attr = type.GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(attr.Name);  // John

또한 메서드, 속성을 검색하고 동적으로 호출할 수 있습니다:

MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
    Console.WriteLine(method.Name);

애트리뷰트(Attributes)와 리플렉션(reflection)은 많은 프레임워크를 구동하는 힘입니다. 직렬화 라이브러리는 이를 사용하여 JSON 출력을 제어하고, 테스트 프레임워크는 이를 사용하여 테스트 메서드를 찾아내며, 의존성 주입(dependency injection) 컨테이너는 이를 사용하여 서비스를 자동으로 연결합니다.

challenge icon

챌린지

쉬움

커스텀 어트리뷰트(custom attributes)와 리플렉션(reflection)을 사용하여 플러그인으로 표시된 클래스들을 자동으로 찾고 설명하는 플러그인 검색 시스템을 구축해 보겠습니다. 이는 실제 프레임워크가 런타임에 컴포넌트, 테스트 메서드 또는 API 엔드포인트를 검색하는 방식과 유사합니다.

코드는 세 개의 파일로 구성됩니다:

  • PluginAttribute.cs: PluginSystem 네임스페이스에 PluginAttribute라는 커스텀 어트리뷰트를 생성합니다. 어트리뷰트의 조건은 다음과 같습니다:
    • Attribute를 상속받아야 합니다.
    • 두 개의 읽기 전용 속성 Name (string)과 Version (string)을 가져야 합니다.
    • 생성자를 통해 두 값을 모두 전달받아야 합니다.
  • Plugins.cs: PluginSystem 네임스페이스에 여러 플러그인 클래스를 생성합니다. 일부는 PluginAttribute로 장식되어야 하며, 하나는 장식되지 않아야 합니다:
    • ImageProcessor - [Plugin("Image Processor", "1.0")]로 표시
    • DataExporter - [Plugin("Data Exporter", "2.5")]로 표시
    • HelperUtility - 어떠한 어트리뷰트도 표시하지 않음 (일반 클래스)
    각 클래스는 비어 있어도 됩니다. 리플렉션을 통해 메타데이터를 검색하는 것이 목적입니다.
  • Program.cs: 메인 파일에서 리플렉션을 사용하여 PluginAttribute가 있는 모든 클래스를 검색합니다. 검색된 각 플러그인에 대해 정보를 출력합니다. 다음 작업이 필요합니다:
    • 현재 어셈블리에서 모든 타입을 가져옵니다.
    • 각 타입에 PluginAttribute가 있는지 확인합니다.
    • 어트리뷰트의 NameVersion 속성을 추출하여 표시합니다.

타입을 검사하고 커스텀 어트리뷰트를 검색하려면 System.Reflection을 사용하세요. GetCustomAttribute<T>() 메서드는 어트리뷰트가 존재하지 않으면 null을 반환하므로, 이를 사용하여 실제 플러그인인 클래스를 필터링할 수 있습니다.

검색된 각 플러그인을 다음 형식으로 한 줄에 하나씩 출력하세요:

Plugin: {Name} (v{Version})

플러그인은 ImageProcessor가 먼저 출력되고, 그 다음에 DataExporter가 출력되어야 합니다. HelperUtility 클래스는 어트리뷰트가 없으므로 출력에 나타나지 않아야 합니다.

예상 출력:

Plugin: Image Processor (v1.0)
Plugin: Data Exporter (v2.5)

이 챌린지는 프레임워크가 어트리뷰트를 마커로 사용하고 리플렉션을 통해 이를 검색하는 방법을 보여줍니다. 이 기술은 의존성 주입(dependency injection) 컨테이너, 직렬화 라이브러리, 테스트 프레임워크 등에서 핵심적으로 사용됩니다!

치트 시트

특성(Attributes)은 코드 요소 위의 대괄호 안에 배치되는 메타데이터 태그입니다. 이는 런타임에 읽을 수 있는 정보를 제공합니다:

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Serializable]
public class Person
{
    public string Name { get; set; }
}

Attribute를 상속받아 사용자 정의 특성을 만듭니다:

public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}

[Author("John")]
public class Calculator { }

리플렉션(Reflection)을 사용하면 System.Reflection 네임스페이스를 사용하여 런타임에 타입을 검사하고 특성을 읽을 수 있습니다:

Type type = typeof(Calculator);
var attr = type.GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(attr.Name);  // John

메서드와 속성을 동적으로 검색합니다:

MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
    Console.WriteLine(method.Name);

GetCustomAttribute<T>() 메서드는 특성이 존재하지 않으면 null을 반환하므로, 특성 존재 여부에 따라 타입을 필터링할 수 있습니다.

직접 해보기

using System;
using System.Reflection;
using PluginSystem;

class Program
{
    public static void Main(string[] args)
    {
        // TODO: 현재 어셈블리에서 모든 타입을 가져옵니다.
        // 힌트: Assembly.GetExecutingAssembly().GetTypes()를 사용하세요.
        
        // TODO: 각 타입을 루프하며 PluginAttribute가 있는지 확인합니다.
        // 힌트: type.GetCustomAttribute<PluginAttribute>()를 사용하세요.
        
        // TODO: 특성(attribute)이 존재하면, 다음 형식으로 플러그인 정보를 출력합니다:
        // Plugin: {Name} (v{Version})
        
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨