如何引導和創建 .NET 項目

已發表: 2022-03-11

創建 .NET 項目

從頭開始創建 .NET 項目就像使用 Visual Studio 嚮導一樣簡單。 轉到File => New Project ,或Add New Project到現有解決方案。 創建新項目後,您可以立即開始編碼。 然而,由嚮導生成的默認項目設置對於專業團隊來說很難接受,因為它們對質量的標准設置得太低了。 此外,沒有嚮導可以知道您需要在特定開發環境中執行的其他設置步驟。

在本文中,我將引導您完成在創建新項目後應立即啟用的幾個重要設置,這對於最大程度地減少未來的技術債務非常重要。 此外,我們還將回顧許多 .NET 開發人員在構建解決方案和新項目時採用的一些常見做法。 即使您沒有應用其中的一些想法,學習並大致了解大多數團隊所做的事情也是很好的。

結構

擁有明確定義的結構對於復雜的項目至關重要。 這可以改善新人加入團隊時的入職體驗,並在支持舊項目時讓您的生活更輕鬆。 良好的結構有兩個關鍵指標:

  • 使用解決方案和項目文件夾
  • 一致的命名

文件夾

解決方案文件夾,有時稱為虛擬文件夾,是一種非常方便的工具來對您的項目進行分組。 在解決方案資源管理器視圖中,只需右鍵單擊並選擇Add => New Solution Folder ,然後將任何現有項目拖放到這個新文件夾中。 這些文件夾不會在文件系統中鏡像,讓您保持物理結構不變,因此將項目從一個解決方案文件夾移動到另一個不會物理移動它們。

解決方案資源管理器窗口顯示項目結構,其中包含文件夾“1 - Common”、“2 - Data”、“3 - Server”和“4 - Client”。

不需要有編號的前綴,但它使文件夾在解決方案資源管理器窗口中顯示為正確的順序。

Visual Studio 可以通過利用分區的單一解決方案或多解決方案模型同時處理多個解決方案。 它們很少使用,所以我不會在本文中介紹它們。

解決方案文件夾不同,項目文件夾與物理文件夾結構相匹配,因此作為磁盤上的真實文件夾存在。 此外,包含 C# 代碼的項目文件夾應與項目的命名空間匹配。 這使得導航非常自然。 您甚至可以啟用 ReSharper 規則來警告此類不匹配。

命名

與命名相關的推薦規則很少:

  • 使用駱駝案例。
  • 項目名稱應與其輸出程序集名稱匹配。
  • 包含自動化測試的項目應具有後綴.Tests
  • 所有項目名稱都應該有一個共同的前綴,例如Company.Product

與以前相同的項目,但有一個新文件夾“4.1 - Tests”,其中包含 MyCompany.MyProduct.Windows.Controls.Tests。

也很少有合理的規則。 您應該根據常識(當然還有英語語法)自行決定何時應用它們:

  • 當容器(項目或文件夾)包含多個相同類型的實例(例如TestsSystem.Collections )時,使用複數形式的主題。
  • 當整個容器包含關於單個實體的代碼(例如 System.Collections.ObjectModel`)時,使用單數形式。
  • 對於簡短的縮寫,像System.IO一樣使用大寫字母。
  • 對於長縮寫,使用像Modules.Forex. .

經驗法則:簡短的縮寫不應超過三個字符。

配置解決方案

配置解決方案就像提供環境所需的所有基礎架構文件一樣簡單。 雖然其中一些可以稍後添加(例如 CI 集成文件),但最好在一開始就添加一些文件。

ReSharper 設置

如果您是專業的 .NET 開發人員,那麼您很可能會使用 ReSharper。 ReSharper 在管理其設置方面非常靈活。 作為團隊負責人,您可以創建和分發將由其他開發人員使用的團隊共享設置。 團隊共享設置存儲在擴展名為.DotSettings的文件中。 如果文件名與 Visual Studio 解決方案名稱匹配,ReSharper 將自動選擇這些設置:

 MyCompany.MyProduct.sln MyCompany.MyProduct.sln.DotSettings

因此,如果您最終希望將某些設置應用於整個團隊,則應在最開始時創建此文件。 一個很好的例子是使用(或不使用) var關鍵字的規則。 您的團隊共享設置文件可以只有這一條規則,而其他規則是開發人員的偏好。 值得一提的是,可以在每個項目級別上設置 ReSharper 設置的相同方式,因為您可能有一些無法修改的遺留代碼(例如更改為使用var關鍵字)。

如果您正確命名此文件(如示例中所示),則任何具有全新 ReSharper 設置的 Visual Studio 新實例都將自動選擇此文件並強制執行規則。 不要忘記將此文件提交到源代碼管理。

StyleCop 規則

與 ReSharper 設置相同,您可以共享 StyleCop 設置。 如果您使用 ReSharper,那麼您可能安裝了集成插件,該插件將利用 ReSharper 的 StyleCop。 但是,StyleCop 將其設置獨立存儲在名為Settings.StyleCop的文件中。 同樣,您可以將此文件與解決方案文件和項目文件一起使用。

如果您正在使用 StyleCop,請不要忘記運行 StyleCop 配置工具並禁用您不想執行的檢查。 默認情況下,啟用所有檢查。 將新設置保存到此文件並提交到源代碼管理。

文本文件

如果您正在構建一個公共產品並準備發布源代碼,請不要忘記創建並提交這些文件:

 README.md LICENSE

我建議對README.md文件使用 markdown 格式,因為它已成為行業標準,並受到 GitHub 等公共源代碼控制服務以及 BitBucket(前 Stash)等內部服務器的支持。

NuGet 規範

如果您正在構建要在 NuGet Gallery 上分發的庫,那麼您很可能需要創建包規範文件,例如MyProject.nuspec 。 我更喜歡手動創建這些文件並將它們提交到源代碼管理。 包通常由您的持續集成(簡稱 CI)工作之一發布,但您也可以隨時從控制台手動構建和發布包,如下所示:

 nuget.exe pack MyLibrary.nuspec

只是不要忘記在執行此命令之前增加包版本。

CI 特定文件

我們都使用不同的 CI 服務器,它們都有不同的配置腳本和設置。 我只想提一些您可能會考慮添加的常見添加:

  • NUnit設置,它指定哪些程序集包含要在 CI 服務器上為特定作業執行的測試。 所有測試實際上都分為幾類。 有應該在每個構建上運行的單元測試,每晚執行的性能測試,以及在每個版本的基礎上執行的集成測試。
  • NCover設置,指定應分析哪些測試程序集以進行測試覆蓋。
  • 將收集確定軟件指標的SonarQube設置。
  • 作業腳本,例如 NAnt、PowerShell 或簡單的 Windows 批處理文件。
一個適當引導的項目可以減少未來的技術債務,並使產品源代碼具有可讀性和專業外觀。
鳴叫

配置項目

項目文件,即.csproj.vbpro ,包含 Visual Studio 和 MSBuild 使用的所有設置。 但是,並非所有這些都可以從“項目屬性”窗口中獲得。 要在 Visual Studio 中手動編輯這些文件,您應該執行以下操作:

  • 右鍵單擊解決方案資源管理器視圖中的項目。
  • 選擇卸載項目
  • 再次右鍵單擊以選擇操作Edit xyz.csproj
  • 完成編輯。
  • 再次右鍵單擊該項目,然後選擇Reload Project

或者,您可以在您喜歡的文本編輯器中打開一個項目文件,對其進行編輯並保存。 當您切換回 Visual Studio 窗口時,系統會提示您重新加載更改的項目。

警告控制

構建高質量的軟件要求您永遠不要忽略構建警告。 因此,您應該啟用最大警告級別並將任何警告視為錯誤。 請注意,您應該為您擁有的所有構建配置執行此操作,例如調試和發布。 最好的方法是將以下設置寫入公共屬性組:

 <WarningLevel>4</WarningLevel> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>

並確保您在其他屬性組中沒有相同的設置。 否則,它們將覆蓋公共組中的相應屬性。

FxCop

運行 FxCop 只是對每個構建都實用。 大多數團隊更喜歡不時運行 FxCop(通常在發布之前)以確保沒有引入嚴重錯誤。 但是,如果您想對每個構建執行最終檢查,請添加此選項:

 <RunCodeAnalysis>true</RunCodeAnalysis>

請注意,FxCop 與 StyleCop 一樣,有自己的設置,可以放置在根文件夾中並添加到源代碼管理中。 在 CI 服務器上運行 FxCop 時可能會使用這些設置。

文檔

這部分是關於 XmlDoc 的。 如果您正在構建公共 API,那麼您應該創建和維護 API 文檔。 大多數開發人員從 API 開發(實際編碼)開始,就在發布之前,他們啟用項目設置Build / XML documentation file 。 自然地,在重新構建之後會出現一堆錯誤,因為每個缺少的 XmlDoc 都會導致構建錯誤。 為避免這種情況,您應該在一開始就啟用提到的選項。

如果您懶得編寫適當的文檔,或者您不喜歡輸入太多文本,請嘗試自動執行此過程的工具,例如 GhostDoc。

代碼合同

Code Contracts 是 Microsoft Research 的一個優秀框架,它允許您在代碼中表達前置條件、後置條件和對像不變量,以用於運行時檢查、靜態分析和文檔。 我在許多關鍵項目中都使用了它,它幫助很大,所以我鼓勵你嘗試一下。

如果您決定使用代碼契約,那麼在剛創建新項目時,一開始就啟用契約很重要。 在開發過程中添加合同是可能的,但需要通過許多類進行更改,以使聯繫人相互匹配。 因此,不要忘記啟用所有必需的設置(至少CodeContractsEnableRuntimeChecking )並確保這些設置出現在公共屬性組中。

StyleCop 執法

之前我們談到了開發時間的 StyleCop 配置。 但是,當您的項目在 CI 服務器上構建時,ReSharper 在那裡不起作用,因此我們應該啟用 StyleCop 驗證以與 MSBuild 一起運行。

這通常通過手動修改項目文件來完成。 您需要在 Visual Studio 中卸載項目,編輯項目文件,然後重新加載項目:

 <PropertyGroup> <!— add this to the common property group (common to Debug/Release/etc) —> <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings> </PropertyGroup> <!— add this Import in the very bottom —> <Import Project="$(ProgramFiles)\MSBuild\Microsoft\StyleCop\v4.3\Microsoft.StyleCop.targets">

設置StyleCopTreatErrorsAsWarnings會按照它所說的那樣做:它會破壞任何違反 StyleCop 規則的構建。 MSBuild 需要 import 元素才能將 StyleCop 任務添加到構建鏈。

您可能已經註意到Program Files的路徑。 由於開發人員可能安裝了不同的 StyleCop 版本,一些團隊更喜歡在源代碼控制下保留相同 StyleCop 安裝的私有副本。 在這種情況下,路徑將是相對的。 這也使 CI 機器的設置更容易,因為您不需要在本地安裝 StyleCop。

裝配信息

由 Visual Studio 嚮導創建的每個 .NET 項目都會自動填充AssemblyInfo.cs文件(請參閱Properties子文件夾),其中包含一些Assembly屬性,但沒有嚮導可以為您填充所有Assembly屬性。 確保您至少填充了以下屬性:

  • AssemblyTitle
  • AssemblyDescription
  • AssemblyCompany
  • AssemblyProduct
  • AssemblyCopyright
  • AssemblyVersion

Visual Studio 的屏幕截圖,顯示六行,全部用方括號括起來,每行都以“assembly:”開頭。每一行都有上面列出的屬性之一以及括號和引號中的相應示例文本字符串。例如,最後一個是“1.0.0.0”。

您要分發的任何程序集都需要這個最低限度。 這背後的一個實際原因是 NuGet:如果您使用從所選程序集文件自動創建 NuGet 規範,該工具將從這些屬性中獲取所需信息。

您還可以在一開始就填充另一個屬性:

 InternalsVisibleTo

此屬性使內部類和接口對指定程序集可見。 這通常用於您將為項目創建的自動化測試。

連接字符串

如何管理連接字符串是 Stack Overflow 上一個非常流行的問題。 問題是如何使每個開發人員或 CI 作業的連接字符串唯一,而不是在發布源代碼時公開連接細節。

App.config (用於桌面應用程序)或Web.config (用於 Web 應用程序)中,進行以下設置,該設置將在運行時加載user.config文件。 將此保留在您的源代碼控制之下:

 <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings configSource="user.config"></connectionStrings> </configuration>

顯然, user.config文件應該從源代碼控制中排除,並且每個開發人員都應該擁有該文件的本地副本,從而保護連接字符串的隱私:

 <connectionStrings> <add name="test" connectionString="Server=.;Database=...;"/> </connectionStrings>

.gitignore

對於那些使用 Git 作為源代碼控制的人來說,在.gitignore文件中添加一些文件模式很重要。 但是,我們的智能社區已經建立了一個通用文件,可以在這裡找到:github.com/github/gitignore/blob/master/VisualStudio.gitignore。

您應該將其作為參考.gitignore文件,並簡單地添加您可能還需要的自定義排除項。

GitHub 徽章

您可能已經在README項目的頁面上看到了漂亮的徽章。 如果您在 GitHub 上發布您的項目,請考慮將您的項目連接到公共服務:

  • 構建:顯示構建失敗或通過。
  • 測試:顯示測試覆蓋率和測試執行狀態。
  • 發布:顯示最新的 NuGet 包版本。

可以在 shields.io 上找到徽章和相關服務的完整列表。 您可能會發現許多對開源項目有益的有趣徽章。

使用選定的服務註冊項目後,您將獲得一個指向圖像的鏈接和一個完整的 markdown-syntax 鏈接,您可以將其添加到您的README.md文件中。 順便說一句,這是您應該更喜歡自述文件的降價的原因之一。

示例 Markdown 徽章,來自 Roslyn 項目:

[![Build Status]([http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/badge/icon)](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/)](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/badge/icon)](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/)) [![Join the chat at [https://gitter.im/dotnet/roslyn](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)](https://gitter.im/dotnet/roslyn](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge))

Linux/Mac - 單元測試表,在每個單元格中顯示“構建通過”徽章。行是 stable、master、future-stabilization、future 和 hotfix;列是 Linux 和 Mac OSX。桌子後的左下角還有一個“gitter join chat”徽章。

自動解決方案結構驗證

即使您已經設置了我們在本文中討論的所有設置,您的開發人員遲早會更改它們並將更改提交到源代碼管理。 有時這是錯誤發生的,而且這些更改通常不會在代碼審查期間被發現。 除了這些事故之外,我們還應該注意以下常見錯誤:

  • 錯誤引用:當有人引用其他人可能沒有的本地程序集時,或者當有人從磁盤中刪除文件時,而指向該文件的鏈接仍保留在.csproj文件中。 這肯定會破壞構建,但是一旦推送更改並且其他人取消更改,它可能會發生得太晚。 這對於您無法在構建期間驗證的靜態 Web 文件尤其重要。
  • 命名一致性:StyleCop 等工具可以控制 C# 源代碼,但沒有工具可以強制執行項目文件或程序集屬性的規則。 一個很好的例子是:我們想要命名項目以匹配輸出程序集名稱,並且我們希望項目名稱具有像MyCompany.MyProduct這樣的公共前綴。

我發現在代碼審查中觀察這些錯誤很容易出錯,應該自動化。 所以我編寫了一個簡單的工具來執行這些和許多其他檢查以驗證解決方案的一致性。 認識解決方案檢查員。 這是開源的,並在 MIT 許可下分發。 您可以從源代碼構建它或從 NuGet 安裝:

 Install-Package SolutionInspector

該工具遍歷整個解決方案結構並應用許多驗證規則。 規則由 XML 文件配置,與其他解決方案文件一起放置。 要控制每個項目的設置,您只需將具有不同設置的相同文件添加到相應的項目文件夾即可。

默認情況下不需要配置文件。 在這種情況下,該工具將應用所有可用規則並將所有問題提交給控制台。

下面是配置文件示例:

 <?xml version="1.0" encoding="utf-8"?> <Settings xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">](http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">) <SolutionSettings> <MinSolutionFormatVersion>12.00</MinSolutionFormatVersion> <MaxSolutionFormatVersion>12.00</MaxSolutionFormatVersion> <DetectMissingFiles>true</DetectMissingFiles> <ProjectNamePrefix>MyCompany.MyProduct.</ProjectNamePrefix> <ProjectNameIsFileName>true</ProjectNameIsFileName> <IgnoredProjects> AVerySpecialProject1; AVerySpecialProject2; </IgnoredProjects> </SolutionSettings> <ProjectSettings> <DetectMissingFiles>true</DetectMissingFiles> <AllowBuildEvents>true</AllowBuildEvents> <AssemblyNameIsProjectName>true</AssemblyNameIsProjectName> <RootNamespaceIsAssemblyName>true</RootNamespaceIsAssemblyName> <RequiredImports>StyleCop.MSBuild.Targets</RequiredImports> <Properties> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings> </Properties> </ProjectSettings> </Settings>

儘管這些設置相當具有描述性,但我將解釋其中的一些:

  • MinSolutionFormatVersion / MaxSolutionFormatVersion將阻止您的開發人員切換 Visual Studio 版本。
  • DetectMissingFiles對於添加到解決方案或項目的靜態 Web 內容或其他非代碼文件非常有用。
  • AllowBuildEvents可以防止添加自定義構建事件,這可能會做不必要的事情。
  • Properties是最靈活的元素:您可以根據所需值檢查任何屬性,無論是已知屬性還是自定義屬性。

結論

我們回顧了一些標準實踐、配置文件和項目設置,您可以在開始新項目時應用。 一開始就這樣做會減少未來的技術債務,並使您的產品源代碼看起來既漂亮又專業。 對於開源項目,這一點尤為重要,因為任何貢獻者都會通過檢查解決方案配置和項目文件來了解您的期望。

相關: .NET Core - 走向狂野和開源。 微軟,你怎麼花了這麼長時間?!