2014年10月19日 星期日

開發團隊的基礎建設 Code Snippet for C#

在 Visual Studio 中撰寫 C# 時,在編輯視窗打上 prop 加 2 個 tab 可以快速建立產生新 property 的程式碼片段,輸入 for 加 2 個 tab 也可以快速產生 for 迴圈的程式碼片段,這些是 Visual Studio 內建的 Code Snippet 功能,在安裝目錄下可以找到所有的 .snippet 檔案,也可以透過功能列的 Tools / Code Snippets Manager 查看各程式語言有哪些內建的片段,當然也可以自行新增,此篇即是記錄如何為 C# 建立 Code Snippet 以提高撰寫程式碼時的帥氣度。

以我自己安裝的 Visual Studio 2013 為例,C# 的內鍵 Snippet 檔案放在 D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC#\Snippets\1033\Visual C# 這個位置,我們隨意打開一個列常用的 for.snippet 可以發現內容是使用 XML 描述的如下

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>for</Title>
<Shortcut>for</Shortcut>
<Description>Code snippet for 'for' loop</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>index</ID>
<Default>i</Default>
<ToolTip>Index</ToolTip>
</Literal>
<Literal>
<ID>max</ID>
<Default>length</Default>
<ToolTip>Max length</ToolTip>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++)
{
$selected$ $end$
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

內容非常的簡單,即便不看文件,大致上可以歸納出幾重點,Shortcut 的部份定義程式碼片段的縮寫,Snippet 內的 Declarations 中有數個 Literal 定義程式碼片段的 "變數",而變數可以設定是否開放編輯,以 Editable="false" 屬性做控制。

自行製作 Code Snippet 的方式很簡單,大致上你需要建立一個資料夾,裡面放著數個自行編寫的 .snippet 檔案,在功能表列的 Tools / Code Snippets Manager 視窗中選擇 C# 並且 Add 剛才建立的資料夾即可,舉例來說我產生了一個資料夾,並加入 param.snippet 與 newtable.snippet 兩個檔案如下,並且在 Code Snippets Manager 選擇這個資料夾即可,未來有新的 .snippet 檔只需要直接丟到這個資料夾即可使用,不必再操作 Visual Studio 做加入的流程,非常適合團隊共同維護一個 Git Repository 來貢獻程式碼片段。


接下來講講我建立的這兩個 snippet 檔案,首先 params.snippet 這個需求的產生是在於我們常常使用 Dictionary<String, String> 這個物件來串接要丟到 REST API 的 Get 參數,所以寫了一個 snippet 來幫助我們快速產生以下片段,並且產生後用戶可以使用 tab 改變 param 及 value 兩個值

Dictionary<String, String> param = new Dictionary<String, String>();
param.Add("param", "value");

這個 Snippet 檔的內容如下

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>params</Title>
<Shortcut>params</Shortcut>
<Description>Code snippet for Dictionary Params</Description>
<Author>Ascii</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>param</ID>
<Default>param</Default>
<ToolTip>param key</ToolTip>
</Literal>
<Literal>
<ID>value</ID>
<Default>value</Default>
<ToolTip>param value</ToolTip>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[Dictionary<String, String> param = new Dictionary<String, String>();
param.Add("$param$", "$value$");]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

接下來 newtable.snippet 這個是在建立 ORM 使用的類別時,可以快速產生類別及基本的 attribute 與 primary key 欄位,並讓撰寫程式的開發者可以利用 tab 更改欄位、類別、屬性的名稱

[Table("member_table")]
public class MemberTable
{
    public MemberTable()
    {
    }

    [PrimaryKey, Column("member_id")]
    public Integer MemberId { get; set; }
}

這個 newtable.snippet 的內容如下

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>newtable</Title>
<Shortcut>newtable</Shortcut>
<Description>Code snippet for Create a ORM Class</Description>
<Author>Ascii</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>table_name</ID>
<Default>table_name</Default>
<ToolTip>Table Name</ToolTip>
</Literal>
<Literal>
<ID>class_name</ID>
<Default>class_name</Default>
<ToolTip>ORM Class Name</ToolTip>
</Literal>
<Literal>
<ID>p_key_name</ID>
<Default>p_key_name</Default>
<ToolTip>Primary Key table column</ToolTip>
</Literal>
<Literal>
<ID>p_key_property</ID>
<Default>p_key_property</Default>
<ToolTip>Primary Key Property</ToolTip>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[[Table("$table_name$")]
    public class $class_name$
    {
        public $class_name$()
        {
        }

        [PrimaryKey, Column("$p_key_name$")]
        public Integer $p_key_property$ { get; set; }
    }]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

更詳細的資訊可以參考官方文件:Visual C# Code Snippets



沒有留言:

張貼留言