2011-10-21 142 views
0

我在C#中有大量的測試類(NUnit Test scripts,在Mono上編譯)。像往常一樣,我不想將所有的單元測試編譯成一個大的程序集,而是想將各個類文件編譯成單獨的程序集。要做到這一點,我想做一個依賴分析,所以我可以自動生成單獨的程序集。如何查找C#類文件的所有依賴項(類文件)

我正在尋找的是類似的,其存在Java

+1

請用實例說明問題。目前還不清楚是否要在Windows上編譯Mono Unit Tests;你想'爲每個依賴項生成一個DLL'(依賴關係通常是DLL)... – sehe

+0

你是對的,它很難理解這個senario。我已經寫過我想構建單個類文件,這意味着我不想爲整個NUnit測試項目創建一個dll,但是我想爲每個NUnit測試項目的測試類文件創建一個dll。說實話, –

+0

我認爲這只是措辭。無論如何,我已發佈我的答案 – sehe

回答

0

看看莫諾塞西爾。

該庫能夠在實際裝配圖像上「反映」(不是一個很好的名字)以進行分析。這假定你願意編譯成一個'大'程序集,以便使用Mono.Cecil運行依賴關係分析。

編輯事實上,你可以簡單地使用塞西爾同時過濾掉它的部分複製的「大」集會。這樣一來,編譯單獨程序集的複雜程度就會降低;請看CecilRoundtrip sample查看如何在Cecil中往返(讀 - >操作 - >保存)程序集的示例。

我以前發表的如何使用單絲絲的 '先進' 的搜索(靜態調用樹搜索,在本質上)相當廣泛的例子:

對您最有用的絕對最低限度可能是:

var types = assemblies 
    .SelectMany(assembly => assembly.MainModule.Types.Cast<TypeDefinition>()); 

var dependencies = types.ToDictionary(
    key => key, 
    typedef => new HashSet<string>(typedef.Methods.Cast<MethodDefinition>() 
       .Where(method => null != method.Body) // ignore abstracts and generics 
       .SelectMany(method => method.Body.Instructions.Cast<Instruction>()) 
       .Select(instr => instr.Operand) 
       .OfType<TypeReference>().Distinct() 
      // .Where(type => !type.Namespace.StartsWith("System")) 
       .Select(type => type.Name))); 

foreach (var entry in dependencies) 
{ 
    Console.WriteLine("{0}\t{1}", entry.Key.Name, string.Join(", ", entry.Value.ToArray())); 
} 

注意註釋行可以從框架(System.String,System.Char等)中選擇性地過濾掉東西。

這將列出每種聲明類型所需的類型。要列出使用的類型,簡單地查找到集名稱標籤:第一類

   .Select(type => type.Module.Assembly.Name.Name))); 

樣本輸出(需要類型):

SegmentSoortKenmerk  SegmentSoortKenmerk 
OperatorValue 
Koppelpad  Koppelpad, CodeLeidendVolgend 
RedenWaarschuwing 
RelExceptions 
GecontroleerdDocument GecontroleerdDocument, GecontroleerdDocument[] 
OwiExtraKenmerk OwiExtraKenmerk, Gegeven, BackofficeRelatie 
Entiteit  Entiteit, SleutelSysteemObject[], EniteitType 

類似的查詢,但使用該組件名稱查找:

SegmentSoortKenmerk  Lspo.Business 
OperatorValue 
Koppelpad  Lspo.Business 
RedenWaarschuwing 
RelExceptions 
GecontroleerdDocument Lspo.Business 
OwiExtraKenmerk Lspo.Business 
Entiteit  Lspo.Business 
+0

添加鏈接到[cecil-roundtrip.cs](https://github.com/mono/cecil/tree/master/tools)作爲額外的靈感 – sehe

0

假設你想運行在單NUnit的測試類依賴分析,這應該只是正常工作,(我愉快地使用NUnit的2.5和2.4單聲道2.10.6)。

一個常見的錯誤是隻複製或跟蹤包含測試的.dll文件。像任何程序一樣,測試依賴於你的情況,它們至少是nunit.framework.dll加上你想測試的類/程序集(以及它的任何依賴關係)

如果你只想找到程序集定的DLL引用(它需要運行的東西),你可以做到這一點很容易:

using System.Reflection; 

void PrintRefs(string dllfile){ 
    var asm = Assembly.ReflectionOnlyLoad (dllfile); 

    foreach (var aname in asm.GetReferencedAssemblies()){ 
    Console.WriteLine(aname.Name); 
    } 
} 

當心,這樣只會發現組件程序或庫編譯時使用的名字沒有什麼,這可能動態地加載運行。