[NET] 自訂Attribute的設計考量到了 "底層 (Base layer)"與"客戶端 (Client)"

會需要自訂Attribute的設計,要考量到的層次最少參與到了「底層 (Base layer)"與"客戶端 (Client)」

希望在該篇文章中弄一個最簡單的課題,好讓自己失意後能夠快速想起。

備註:

  • Custom 發音為「ㄎㄚ 死 ㄊㄣˇ」 中文翻譯為「自訂」,這會是底層開發才用到的單字
  • CustomAttribute 以後可能會關係到AOP,但目前還沒整理好定義,所以目前照舊歸類在「反射技巧運用」

 

自訂Attribute的設計考量到了底層 (Base layer)客戶端 (Client)

在此將模擬一個考題,假設目前需求如下:

  • 自訂一個CustomAttribute只能被Methiod或是Class使用
  • 自訂 MyForm 需要繼承 System.Windows.Forms
  • 在建構 MyForm 被建構時,能夠記錄所有被標記CustomAttribute的Method 至 IList<MethodInfo> CustomAttributeMethods { get; }

也許這樣的需求有些人認為很抽象,但可以試著想想你的系統有很多的Form,而每次在建構的程序上有很多共同點,何不考慮貼個標籤讓父類別處理,而不是每次子類別都寫一次

CustomAttribute


namespace My.System
{
    [AttributeUsage(
        AttributeTargets.Method |
        AttributeTargets.Class, //只能標記在方法或類別上
        AllowMultiple = true //一個目標可以使用標記多次
    )]
    public class CustomAttribute : Attribute
    {
        public CustomAttribute(object value)
        {
            
        }
    } 
}

Client


public partial class Form1 : MyForm
{
    public Form1()
    {
        InitializeComponent();
    }

    [Custom(1)]
    [Custom("1")]
    [Custom(true)]
    public void CustomMthod()
    {

    }
}

底層


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace My.System.Windows.Forms
{
    public class MyFormsBase : Form
    {
        public IList CustomAttributeMethods { get; }

        public MyFormsBase()
        {
            this.CustomAttributeMethods = this.LoadCustomAttributeMethods();

        }

        // 載入MyForm中所有被標記的Method
        private IList LoadCustomAttributeMethods()
        {
            MethodInfo[] methods = this.GetType().GetMethods();
            Type CustomAttributeType = typeof(CustomAttribute);

            //MethodInfo 條件函式
            Func methodInfoPredicate = (methodIfno) =>
            {
                return methodIfno.IsDefined(CustomAttributeType);
            };

            return methods.Where(methodInfoPredicate).ToList();
        }
    }
}

結果


相關文章:

參考: