載入組件,遍歷所有型別與方法,找出標記 [DefectTrack] 的項目並輸出屬性值:
public static void DisplayDefectTrack(string assemblyName)
{
Assembly asm = Assembly.Load(assemblyName);
Type[] types = asm.GetTypes();
foreach (Type t in types)
{
Console.WriteLine("*======================*");
Console.WriteLine("TYPE:\t" + t);
Console.WriteLine("*=====================*");
object[] attrs = t.GetCustomAttributes(typeof(DefectTrackAttribute), false);
if (attrs.Length > 0) Console.WriteLine("\nMod/Fix Log:");
foreach (Attribute a in attrs)
{
DefectTrackAttribute dta = (DefectTrackAttribute)a;
Console.WriteLine("----------------------");
Console.WriteLine("Defect ID:\t" + dta.DefectID);
Console.WriteLine("Date:\t\t" + dta.ModificationDate);
Console.WriteLine("Developer ID:\t" + dta.DeveloperID);
Console.WriteLine("Origin:\t\t" + dta.Origin);
Console.WriteLine("Comment:\n" + dta.FixComment);
}
MethodInfo[] methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (methods.Length > 0) Console.WriteLine("\nMethods:");
foreach (MethodInfo mi in methods)
{
Console.WriteLine("\n\t" + mi);
object[] mattrs = mi.GetCustomAttributes(typeof(DefectTrackAttribute), false);
if (mattrs.Length > 0) Console.WriteLine("\n\t\tMod/Fix Log:");
foreach (Attribute a in mattrs)
{
DefectTrackAttribute dta = (DefectTrackAttribute)a;
Console.WriteLine("\t\t----------------");
Console.WriteLine("\t\tDefect ID:\t" + dta.DefectID);
Console.WriteLine("\t\tDeveloper ID:\t" + dta.DeveloperID);
Console.WriteLine("\t\tOrigin:\t\t" + dta.Origin);
Console.WriteLine("\t\tComment:\n\t\t" + dta.FixComment);
}
}
Console.WriteLine("\n\n");
}
}
Assembly.Load、GetTypes:載入組件並取得所有型別。GetCustomAttributes(typeof(T), false):取得指定屬性,false 表示不搜尋繼承鏈。object[],需轉型為強型別屬性才能存取屬性值。MethodInfo.GetMethods 搭配 BindingFlags 過濾目標方法。自訂屬性最大價值在於「你可以用它做什麼」:將中繼資料嵌入組件,執行期透過反射讀取,實現文件化、追蹤、AOP 等多樣化應用。