如何引导和创建 .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 - 走向狂野和开源。 微软,你怎么花了这么长时间?!