因為讀 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>