Menu
CoddyTech

Atribut dan Reflection

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C# di Coddy. Pelajaran 44 dari 70.

Attributes adalah tag metadata yang kamu pasang pada elemen kode seperti class, method, atau property. Tag ini tidak mengubah cara kode dijalankan secara langsung, tetapi memberikan informasi yang dapat dibaca saat runtime. Reflection adalah mekanisme yang membaca metadata ini.

Kamu menerapkan atribut dengan menempatkannya di dalam tanda kurung siku di atas elemen target:

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

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

Kamu dapat membuat atribut kustom dengan mewarisi Attribute:

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

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

Reflection memungkinkan kamu memeriksa tipe dan membaca atribut saat runtime menggunakan namespace System.Reflection:

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

Kamu juga bisa menemukan method dan property, lalu memanggilnya secara dinamis:

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

Atribut dan refleksi mendukung banyak framework. Library serialisasi menggunakannya untuk mengatur output JSON, framework pengujian menggunakannya untuk menemukan method pengujian, dan container injeksi dependensi menggunakannya untuk menghubungkan layanan secara otomatis.

challenge icon

Tantangan

Mudah

Mari kita bangun sistem penemuan plugin yang menggunakan atribut kustom dan reflection untuk menemukan serta mendeskripsikan class yang ditandai sebagai plugin secara otomatis. Sistem ini mirip dengan cara framework sungguhan menemukan komponen, method pengujian, atau endpoint API saat program berjalan.

Kamu akan mengatur kodemu dalam tiga file:

  • PluginAttribute.cs: Buat atribut kustom bernama PluginAttribute dalam namespace PluginSystem. Atributmu harus:
    • Mewarisi Attribute
    • Memiliki dua property hanya-baca: Name (string) dan Version (string)
    • Menerima kedua nilai melalui constructornya
  • Plugins.cs: Buat beberapa class plugin dalam namespace PluginSystem. Beberapa class harus diberi atribut PluginAttribute, dan satu class tidak boleh diberi atribut:
    • ImageProcessor, ditandai dengan [Plugin("Image Processor", "1.0")]
    • DataExporter, ditandai dengan [Plugin("Data Exporter", "2.5")]
    • HelperUtility, tidak ditandai dengan atribut apa pun (ini hanya class biasa)
    Setiap class boleh kosong. Kita hanya tertarik menemukan metadata class tersebut melalui reflection.
  • Program.cs: Dalam file utamamu, gunakan reflection untuk menemukan semua class yang memiliki PluginAttribute. Untuk setiap plugin yang ditemukan, cetak informasinya. Kamu perlu:
    • Mendapatkan semua tipe dari assembly saat ini
    • Memeriksa setiap tipe untuk mengetahui apakah memiliki PluginAttribute
    • Mengekstrak dan menampilkan property Name dan Version dari atribut tersebut

Gunakan System.Reflection untuk memeriksa tipe dan mengambil atribut kustom. Method GetCustomAttribute<T>() mengembalikan null jika atribut tidak ada, jadi kamu dapat menggunakannya untuk memfilter class yang benar-benar merupakan plugin.

Cetak setiap plugin yang ditemukan dengan format berikut, satu per baris:

Plugin: {Name} (v{Version})

Plugin harus dicetak dengan urutan: ImageProcessor terlebih dahulu, lalu DataExporter. Class HelperUtility tidak boleh muncul dalam output karena tidak memiliki atribut tersebut.

Output yang diharapkan:

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

Tantangan ini menunjukkan cara framework menggunakan atribut sebagai penanda dan reflection untuk menemukannya. Teknik yang sama digunakan oleh container dependency injection, library serialisasi, dan framework pengujian!

Coba sendiri

using System;
using System.Reflection;
using PluginSystem;

class Program
{
    public static void Main(string[] args)
    {
        // TODO: Ambil semua tipe dari assembly saat ini
        // Petunjuk: Gunakan Assembly.GetExecutingAssembly().GetTypes()
        
        // TODO: Lakukan perulangan pada setiap tipe dan periksa apakah tipe tersebut memiliki PluginAttribute
        // Petunjuk: Gunakan type.GetCustomAttribute<PluginAttribute>()
        
        // TODO: Jika atribut tersebut ada, cetak informasi plugin dengan format:
        // Plugin: {Name} (v{Version})
        
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler C# online