2018年8月9日 星期四

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

markdown

# 需求描述
因為要做重構,需要找出有哪些邏輯是藏在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