2016-11-04 3 views
0

Я работаю над проектом по очистке устаревшего кода и должен программно находить все ссылки, вызывающие определенные веб-методы SOAP в ссылках на службы .NET 4.5 (например, файлы Reference.cs), поэтому Я могу выводить на текстовые файлы или Excel (в основном, ссылки, перечисленные с функциями CodeLens). Я решил, что для этой задачи я бы использовал библиотеку Mono.Cecil.Список всех ссылок, вызывающих метод с использованием Mono.Cecil

У меня есть методы для указанных сборок и классов, работающих отлично, так как я могу распечатать список всех методов для просмотра. Но любые мысли о том, как я могу получить список ссылок для конкретного метода?

// assemblyName is the file path for the specific dll 
public static void GetReferencesList(string assemblyName) 
    { 
     AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyName); 

     foreach (ModuleDefinition module in assembly.Modules) 
     { 
      foreach (TypeDefinition type in module.Types) 
      { 
       if (type.Name.ToLowerInvariant() == "classname") 
       { 
        foreach (MethodDefinition method in type.Methods) 
        { 
         if (method.Name.Substring(0, 4) != "get_" && 
          method.Name.Substring(0, 4) != "set_" && 
          method.Name != ".ctor" && 
          method.Name != ".cctor" && 
          !method.Name.Contains("Async")) 
         { 
          //Method name prints great here 
          Console.WriteLine(method.Name); 

          // Would like to collect the list of referencing calls here 
          // for later output to text files or Excel 
         } 
        } 
       } 
      } 
     } 
    } 
} 

ответ

1

Я делаю это так:

static HashSet<string> BuildDependency(AssemblyDefinition ass, MethodReference method) 
     { 
      var types = ass.Modules.SelectMany(m => m.GetTypes()).ToArray(); 
      var r = new HashSet<string>(); 

      DrillDownDependency(types, method,0,r); 

      return r; 
     } 

    static void DrillDownDependency(TypeDefinition[] allTypes, MethodReference method, int depth, HashSet<string> result) 
    { 
     foreach (var type in allTypes) 
     { 
      foreach (var m in type.Methods) 
      { 
       if (m.HasBody && 
        m.Body.Instructions.Any(il => 
        { 
         if (il.OpCode == Mono.Cecil.Cil.OpCodes.Call) 
         { 
          var mRef = il.Operand as MethodReference; 
          if (mRef != null && string.Equals(mRef.FullName,method.FullName,StringComparison.InvariantCultureIgnoreCase)) 
          { 
           return true; 
          } 
         } 
         return false; 
        })) 
       { 
        result.Add(new string('\t', depth) + m.FullName); 
        DrillDownDependency(allTypes,m,++depth, result); 
       } 
      } 
     } 
    } 
Смежные вопросы