2018年8月9日 星期四

找出某個namespace下所有類別裡面有哪些類別的哪些屬性不是單純的get set | find out class that have not simple getter setter property in specific name space



需求描述

因為要做重構,需要找出有哪些邏輯是藏在DTO裡面的,
但DTO類別檔又很多,不想一個個找
所以就想寫個console程式來撈

做法

首先把要撈的DLL跟他相依的DLL都複製到要執行的排程執行檔輸出資料夾(通常是bin\debug)

以下程式碼:

public class Worker
{
    public void DoWork()
    {
        System.Reflection.Assembly service = Assembly.LoadFile(@"<你要找的namespace所在的dll的絕對路徑>.dll");
        Type[] typelist = service.GetTypes();
        var nameHaveDtoTypes = typelist.Where(x => x.Name.ToUpper().EndsWith("DTO"));//你的類別名稱的特徵,例如找DTO就結尾是DTO
        foreach (var typeitem in nameHaveDtoTypes)
        {
            if(typeitem.GetProperties().Any(prop=> !MightBeCouldBeMaybeAutoGeneratedInstanceProperty(prop)))
            {
                foreach (var prop in typeitem.GetProperties().Where(prop => !MightBeCouldBeMaybeAutoGeneratedInstanceProperty(prop)))
                {
                    //印到畫面跟輸出視窗
                    Console.WriteLine($"{typeitem.Name},{prop.Name}");
                    System.Diagnostics.Debug.WriteLine($"{typeitem.Name},{prop.Name}");
                }
            }
        }
    }

    public bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(PropertyInfo info)
    {
        bool mightBe = info.GetGetMethod()
                           .GetCustomAttributes(
                               typeof(CompilerGeneratedAttribute),
                               true
                           )
                           .Any();
        if (!mightBe)
        {
            return false;
        }


        bool maybe = info.DeclaringType
                         .GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                         .Where(f => f.Name.Contains(info.Name))
                         .Where(f => f.Name.Contains("BackingField"))
                         .Where(
                             f => f.GetCustomAttributes(
                                 typeof(CompilerGeneratedAttribute),
                                 true
                             ).Any()
                         )
                         .Any();

        return maybe;
    }
}



參考:
1.LINE群大神指點關鍵字CompilerGeneratedAttribute
這個是指在編譯成DLL時,單純getter setter的屬性上面會有這個tag
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilergeneratedattribute.aspx

2.How to find out if a property is an auto-implemented property with reflection?
https://stackoverflow.com/questions/2210309/how-to-find-out-if-a-property-is-an-auto-implemented-property-with-reflection?lq=1


沒有留言:

張貼留言