因為讀 Patrick Smacchia 的這篇文章 Introduction to C# Anonymous Methods 而發現 NDepend (Mike Clark 之前就已經為 Java 實作了 JDepend) :
NDepend analyses .NET assemblies of an application and generates design quality metrics. NDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability and maintainability to effectively manage and control the assemblies’ dependencies of your .NET applications. Moreover, NDepend helps you to get a thorough view of the topology of your application, at component at type and at member level.
這類工具的理論基礎通常源自於 Robert C. Martin 於 1994 年的這篇文章 Object Oriented Design Quality Metrics: an analysis,但是我自己對於這類 OOD 的靜態分析 (static analysic) 工具的實用性通常是抱持懷疑的態度,畢竟軟體設計的品質很難簡單用幾個數字就能評定。雖然如此,有些分析的結果還是頗具參考性,例如 cyclic dependency 的偵測。
想當然爾,這類的靜態分析是最適合搭配 Continuous Integration 來實行。查了一下,似乎沒有相對應的 NAnt Task 可以執行 NDepend,只好拐個彎用 exec Task 來執行:
<target name="ndepend" depends="build">
<copy file="PViewer.NDepend.xml" todir="${destdir}" />
<attrib file="${destdir}/PViewer.NDepend.xml" readonly="false" />
<xmlpoke file="${destdir}/PViewer.NDepend.xml" xpath="/NDepend/Dirs/Dir" value="${path::get-full-path(destdir)}" />
<exec program="ndepend.console.exe" commandline="PViewer.NDepend.xml" workingdir="${destdir}" />
</target>
PViewer.NDepend.xml 是 NDepend 的設定檔,因為裡面所有的路徑設定需要是絕對路徑,為了讓共用的設定檔可以在每個人的機器上執行,需要動一點手腳:copy 原始設定檔、移除唯讀設定、利用 path::get-full-path 拿到絕對路徑、用 xmlpoke 更改 /NDepend/Dirs/Dir 節點中的路徑。
下面是我的原始 PViewer.NDepend.xml:
<?xml version="1.0" encoding="utf-8" ?>
<NDepend AppName="PViewer">
<Dirs>
<Dir>dir</Dir>
</Dirs>
<Assemblies>
<Name Warn="True">PViewer.Imaging</Name>
</Assemblies>
<FrameworkAssemblies>
<Name>WeifenLuo.WinFormsUI</Name>
</FrameworkAssemblies>
</NDepend>