Comment démarrer et créer des projets .NET
Publié: 2022-03-11Créer un projet .NET
Créer un projet .NET à partir de zéro est aussi simple que d'utiliser l'assistant Visual Studio. Allez dans File => New Project
ou Add New Project
à une solution existante. Une fois qu'un nouveau projet a été créé, vous pouvez commencer à coder immédiatement. Cependant, les paramètres de projet par défaut produits par les assistants sont difficilement acceptables pour les équipes professionnelles, car ils fixent une barre de qualité trop basse. De plus, aucun assistant ne peut connaître les autres étapes de configuration que vous devez effectuer dans votre environnement de développement particulier.
Dans cet article, je vais vous guider à travers plusieurs paramètres importants que vous devez activer dès que vous créez un nouveau projet, ce qui est important pour minimiser une future dette technique. Nous passerons également en revue certaines pratiques courantes que de nombreux développeurs .NET appliquent lorsqu'ils structurent des solutions et de nouveaux projets. Même si vous n'appliquez pas certaines de ces idées, il est agréable d'apprendre et d'avoir un aperçu de ce que font la plupart des équipes.
Structure
Avoir une structure bien définie est vital pour les projets complexes. Cela améliore l'expérience d'intégration lorsque de nouveaux arrivants rejoignent une équipe et vous facilite la vie lorsque vous soutenez d'anciens projets. Il y a deux indicateurs clés d'une bonne structure :
- Utilisation des dossiers de solution et de projet
- Dénomination cohérente
Dossiers
Les dossiers de solutions, parfois appelés dossiers virtuels , sont un instrument très pratique pour regrouper vos projets. Dans la vue Explorateur de solutions , cliquez simplement avec le bouton droit de la souris et sélectionnez Add => New Solution Folder
, puis faites glisser et déposez l'un des projets existants dans ce nouveau dossier. Ces dossiers ne sont pas mis en miroir dans le système de fichiers, ce qui vous permet de conserver la structure physique inchangée. Par conséquent, le déplacement des projets d'un dossier de solution à un autre ne les déplace pas physiquement.
Il n'est pas nécessaire d'avoir des préfixes numérotés, mais les dossiers apparaissent ordonnés directement dans la fenêtre de l' Explorateur de solutions .
Visual Studio peut fonctionner avec plusieurs solutions en même temps en tirant parti des modèles de solutions uniques partitionnées ou de solutions multiples . Ils sont rarement utilisés, je ne les couvrirai donc pas dans cet article.
Contrairement aux dossiers de solution , les dossiers de projet correspondent à la structure des dossiers physiques et persistent donc en tant que dossiers réels sur le disque. De plus, les dossiers de projet contenant un code C# doivent correspondre à l'espace de noms du projet. Cela rend la navigation assez naturelle. Vous pouvez même activer une règle ReSharper pour avertir de telles incohérences.
Appellation
Il existe quelques règles recommandées à appliquer concernant la dénomination :
- Utilisez CamelCase.
- Un nom de projet doit correspondre à son nom d'assembly de sortie.
- Un projet contenant des tests automatisés doit avoir le suffixe
.Tests
. - Tous les noms de projet doivent avoir un préfixe commun, comme
Company.Product
.
Il existe également quelques règles raisonnables. Vous devez décider vous-même quand les appliquer en fonction du bon sens (et de la grammaire anglaise, bien sûr) :
- Utilisez les sujets au pluriel lorsqu'un conteneur (projet ou dossier) contient plusieurs instances du même type (par exemple,
Tests
ouSystem.Collections
). - Utilisez la forme singulière lorsque l'ensemble du conteneur contient du code concernant une seule entité (par exemple, System.Collections.ObjectModel`).
- Pour les abréviations courtes, utilisez des majuscules comme le fait
System.IO
. - Pour les abréviations longues, utilisez CamelCase comme
Modules.Forex.
.
Une règle d'or : une courte abréviation ne doit pas dépasser trois caractères.
Configuration de la solution
La configuration d'une solution est aussi simple que de fournir tous les fichiers d'infrastructure dont vous avez besoin pour votre environnement. Bien que certains d'entre eux puissent être ajoutés ultérieurement (comme les fichiers d'intégration CI), il est préférable d'avoir quelques fichiers au tout début.
Paramètres ReSharper
Si vous êtes un développeur .NET professionnel, vous utilisez très probablement ReSharper. ReSharper est très flexible dans la gestion de ses paramètres. En tant que chef d'équipe, vous pouvez créer et distribuer des paramètres partagés par l'équipe qui seront utilisés par d'autres développeurs. Les paramètres partagés par l'équipe sont stockés dans un fichier avec l'extension .DotSettings
. ReSharper sélectionne automatiquement ces paramètres si le nom du fichier correspond au nom de la solution Visual Studio :
MyCompany.MyProduct.sln MyCompany.MyProduct.sln.DotSettings
Par conséquent, vous devez créer ce fichier au tout début si vous souhaitez finalement appliquer certains paramètres à toute l'équipe. Un bon exemple serait la règle d'utilisation (ou de non-utilisation) du mot-clé var
. Votre fichier de paramètres Team Shared ne peut avoir qu'une seule règle, tandis que d'autres sont la préférence des développeurs. Il convient de mentionner que les paramètres de ReSharper peuvent être définis de la même manière au niveau de chaque projet, car vous pouvez avoir du code hérité que vous ne pouvez pas modifier (par exemple, changer pour utiliser le mot-clé var
).
Si vous avez correctement nommé ce fichier, comme indiqué dans l'exemple, toute nouvelle instance de Visual Studio avec une nouvelle configuration de ReSharper sélectionnera automatiquement ce fichier et appliquera les règles. N'oubliez pas de valider ce fichier dans le contrôle de source.
Règles StyleCop
Comme pour les paramètres ReSharper, vous pouvez partager les paramètres StyleCop. Si vous utilisez ReSharper, vous avez probablement installé un plug-in d'intégration qui tirera parti de StyleCop de ReSharper. Cependant, StyleCop stocke ses paramètres indépendamment dans des fichiers nommés Settings.StyleCop
. De même, vous pouvez avoir ce fichier avec le fichier de solution et les fichiers de projet.
Si vous utilisez StyleCop, n'oubliez pas d'exécuter l'outil de configuration StyleCop et de désactiver les vérifications que vous ne souhaitez pas effectuer. Par défaut, toutes les vérifications sont activées. Enregistrez les nouveaux paramètres dans ce fichier et validez dans le contrôle de code source.
Fichiers texte
Si vous créez un produit public et que vous allez publier le code source, n'oubliez pas de créer et de valider également ces fichiers :
README.md LICENSE
Je recommande d'utiliser le format Markdown pour le fichier README.md
, car il est devenu une norme industrielle et pris en charge par des services publics de contrôle de source comme GitHub, ainsi que par des serveurs internes comme BitBucket (anciennement Stash).
Spécifications NuGet
Si vous construisez une bibliothèque qui doit être distribuée sur NuGet Gallery, vous devrez très probablement créer des fichiers de spécification de package, comme MyProject.nuspec
. Je préfère créer ces fichiers manuellement et les valider dans le contrôle de code source. Les packages sont généralement publiés par l'un de vos travaux d'intégration continue (CI en abrégé), mais vous pouvez également à tout moment créer et publier un package manuellement à partir de la console comme suit :
nuget.exe pack MyLibrary.nuspec
N'oubliez pas d'incrémenter la version du package avant d'exécuter cette commande.
Fichiers spécifiques CI
Nous utilisons tous différents serveurs CI, et ils ont tous des scripts de configuration et des paramètres différents. Je mentionnerais simplement certains des ajouts courants que vous pourriez envisager d'ajouter :
- Paramètres NUnit , qui spécifient quels assemblys contiennent des tests à exécuter sur le serveur CI pour des travaux particuliers. Tous les tests sont pratiquement divisés en quelques catégories. Il existe des tests unitaires qui doivent être exécutés sur chaque version, des tests de performances qui sont exécutés la nuit et des tests d' intégration qui sont exécutés par version.
- Paramètres NCover , qui spécifient quels assemblages de test doivent être analysés pour la couverture de test.
- Les paramètres SonarQube , qui déterminent les métriques logicielles, seront collectés.
- Scripts de travail , tels que NAnt, PowerShell ou simplement des fichiers batch Windows.
Configuration des projets
Les fichiers de projet, à savoir .csproj
ou .vbpro
, contiennent tous les paramètres utilisés par Visual Studio et MSBuild. Cependant, tous ne sont pas disponibles à partir de la fenêtre Propriétés du projet. Pour modifier manuellement ces fichiers dans Visual Studio, vous devez procéder comme suit :
- Cliquez avec le bouton droit sur un projet dans la vue Explorateur de solutions.
- Sélectionnez Décharger le projet .
- Cliquez à nouveau avec le bouton droit pour choisir l'action Modifier xyz.csproj .
- Édition complète.
- Cliquez à nouveau avec le bouton droit sur le projet et choisissez Recharger le projet .
Vous pouvez également ouvrir un fichier de projet dans votre éditeur de texte préféré, le modifier et l'enregistrer. Lorsque vous revenez à la fenêtre Visual Studio, vous serez invité à recharger le projet modifié.
Contrôle des avertissements
Construire un logiciel de haute qualité vous oblige à ne jamais ignorer les avertissements de construction. Par conséquent, vous devez activer le niveau d'avertissement maximal et traiter tous les avertissements comme des erreurs. Notez que vous devez le faire pour toutes les configurations de build que vous avez, telles que Debug et Release. La meilleure façon de procéder consiste à écrire les paramètres suivants dans le groupe de propriétés communes :
<WarningLevel>4</WarningLevel> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Et assurez-vous que vous n'avez pas les mêmes paramètres dans d'autres groupes de propriétés. Sinon, elles remplaceront les propriétés correspondantes du groupe commun.
FxCop
Exécuter FxCop est simplement pratique à faire sur chaque version. La plupart des équipes préfèrent exécuter FxCop de temps en temps (généralement avant une version) pour s'assurer qu'aucune erreur grave n'a été introduite. Cependant, si vous souhaitez effectuer une vérification ultime sur chaque build, ajoutez cette option :
<RunCodeAnalysis>true</RunCodeAnalysis>
Notez que FxCop, comme StyleCop, a ses propres paramètres qui peuvent être placés dans le dossier racine et ajoutés au contrôle de source. Ces paramètres sont probablement utilisés lors de l'exécution de FxCop sur des serveurs CI.
Documentation
Cette partie concerne XmlDoc. Si vous créez une API publique, vous devez créer et maintenir la documentation de l'API. La plupart des développeurs commencent par le développement d'API (codage réel) et, juste avant une version, ils activent le paramètre de projet Build / XML documentation file
. Naturellement, après une autre reconstruction, un tas d'erreurs apparaît, car chaque XmlDoc manquant entraîne une erreur de construction. Pour éviter cela, vous devez activer l'option mentionnée au tout début.
Si vous êtes trop paresseux pour écrire une documentation appropriée, ou si vous n'aimez pas taper trop de texte, essayez des instruments qui automatisent ce processus tels que GhostDoc.
Contrats de code
Code Contracts est un excellent framework de Microsoft Research, qui vous permet d'exprimer des préconditions, des postconditions et des invariants d'objet dans votre code pour la vérification de l'exécution, l'analyse statique et la documentation. Je l'ai utilisé dans de nombreux projets critiques, et cela m'a beaucoup aidé, alors je vous encourage à l'essayer.

Si vous décidez d'utiliser les contrats de code, il est important d'activer les contrats au tout début, lorsque vous venez de créer un nouveau projet. L'ajout de contrats au milieu du développement est possible, mais nécessitera des modifications dans de nombreuses classes, pour que les contacts correspondent les uns aux autres. N'oubliez donc pas d'activer tous les paramètres requis (au moins CodeContractsEnableRuntimeChecking
) et assurez-vous que ces paramètres apparaissent dans le groupe de propriétés communes.
Application de StyleCop
Auparavant, nous avons parlé de la configuration de StyleCop pour le temps de développement. Cependant, lorsque votre projet est construit sur un serveur CI, ReSharper n'y a aucun effet et nous devons donc activer la validation StyleCop pour qu'elle s'exécute avec MSBuild.
Cela se fait généralement par modification manuelle du fichier de projet. Vous devez décharger le projet dans Visual Studio, modifier le fichier projet, puis recharger le projet :
<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">
Le paramètre StyleCopTreatErrorsAsWarnings
fera ce qu'il dit : il cassera votre construction en cas de violation de la règle StyleCop. L'élément d'importation est requis pour que MSBuild ajoute la tâche StyleCop à la chaîne de génération.
Vous avez peut-être remarqué le chemin vers Program Files
. Étant donné que les développeurs peuvent avoir différentes versions de StyleCop installées, certaines équipes préfèrent conserver une copie privée de la même installation de StyleCop sous contrôle de code source. Dans ce cas, le chemin sera relatif. Cela facilite également la configuration des machines CI, car vous n'avez pas besoin d'installer StyleCop localement.
AssemblyInfo
Chaque projet .NET créé par l'assistant Visual Studio aura le fichier AssemblyInfo.cs
rempli automatiquement (voir le sous-dossier Properties ) qui contient certains des attributs d' Assembly
, mais aucun assistant ne peut remplir tous les attributs d' Assembly
pour vous. Assurez-vous d'avoir au moins ces attributs renseignés :
-
AssemblyTitle
-
AssemblyDescription
-
AssemblyCompany
-
AssemblyProduct
-
AssemblyCopyright
-
AssemblyVersion
Ce strict minimum est requis pour tous les assemblys que vous allez distribuer. Une raison pratique derrière cela est NuGet : si vous utilisez la création automatique de spécifications NuGet à partir du fichier d'assemblage sélectionné, cet outil dérivera les informations nécessaires à partir de ces propriétés.
Vous pouvez également remplir une autre propriété au tout début :
InternalsVisibleTo
Cette propriété rend les classes internes et les interfaces visibles pour l'assembly spécifié. Ceci est généralement utilisé pour les tests automatisés que vous allez créer pour votre projet.
Chaînes de connexion
Comment gérer les chaînes de connexion est une question très populaire sur le Stack Overflow. Le problème est de savoir comment rendre les chaînes de connexion uniques pour chaque développeur ou un travail CI, et ne pas exposer les détails de connexion lors de la publication du code source.
Dans App.config
(pour les applications de bureau) ou Web.config
(pour les applications Web), définissez le paramètre suivant qui chargera le fichier user.config
lors de l'exécution. Gardez ceci sous votre contrôle de code source :
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings configSource="user.config"></connectionStrings> </configuration>
Apparemment, le fichier user.config
devrait être exclu du contrôle de source, et chaque développeur devrait avoir une copie locale de ce fichier, préservant la confidentialité de la chaîne de connexion :
<connectionStrings> <add name="test" connectionString="Server=.;Database=...;"/> </connectionStrings>
.gitignore
Pour ceux qui utilisent Git comme contrôle de source, il est important d'ajouter des modèles de fichiers au fichier .gitignore
. Cependant, notre communauté intelligente a déjà construit un fichier généralisé, qui peut être trouvé ici : github.com/github/gitignore/blob/master/VisualStudio.gitignore.
Vous devez le prendre comme fichier .gitignore
de référence et ajouter simplement vos exclusions personnalisées dont vous pourriez avoir besoin en plus.
Insignes GitHub
Vous avez peut-être vu de jolis badges apparaître sur la page du projet README
. Si vous publiez votre projet sur le GitHub, envisagez de connecter votre projet à des services publics pour :
- Construction : pour montrer qu'une construction échoue ou réussit.
- Tests : pour afficher la couverture des tests et l'état d'exécution des tests.
- Publication : pour afficher la dernière version du package NuGet.
Une liste complète des badges et des services associés est disponible sur shields.io. Vous pouvez trouver de nombreux badges intéressants qui conviennent aux projets Open Source.
Une fois que vous avez enregistré votre projet auprès d'un service sélectionné, vous recevrez un lien vers l'image et un lien complet de syntaxe de démarquage, que vous pouvez ajouter à votre fichier README.md
. Soit dit en passant, c'est l'une des raisons pour lesquelles vous devriez préférer le démarquage pour les fichiers Lisezmoi .
Exemples de badges de démarquage, du projet Roslyn :
[](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/)) [](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))
Validation automatique de la structure de la solution
Même si vous avez défini tous les paramètres dont nous avons parlé dans cet article, tôt ou tard, l'un de vos développeurs peut les modifier et valider les modifications dans le contrôle de code source. Parfois, cela se produit par erreur, et souvent ces modifications ne sont pas prises en compte lors de la révision du code. Outre ces accidents, nous devrions surveiller les erreurs courantes suivantes :
- Mauvaises références : lorsque quelqu'un fait référence à une assemblée locale que d'autres n'ont peut-être pas, ou lorsque quelqu'un a supprimé un fichier du disque, alors que le lien vers ce fichier reste dans le fichier
.csproj
. Cela cassera la construction à coup sûr, mais cela peut arriver trop tard une fois que le changement est poussé et que d'autres l'ont retiré. Ceci est particulièrement crucial pour les fichiers Web statiques, que vous ne pouvez pas vérifier lors de la construction. - Cohérence de nommage : les outils comme StyleCop peuvent contrôler le code source C#, mais aucun outil ne peut appliquer des règles pour les fichiers de projet ou les propriétés d'assemblage. Un bon exemple est le suivant : nous voulons nommer les projets pour qu'ils correspondent au nom de l'assembly de sortie, et nous voulons que les noms de projet aient un préfixe commun comme
MyCompany.MyProduct
.
J'ai trouvé que la surveillance de ces erreurs dans les revues de code est sujette aux erreurs et devrait être automatisée. J'ai donc écrit un outil simple qui effectue ces vérifications et bien d'autres pour vérifier la cohérence de la solution. Découvrez SolutionInspector. Ceci est Open Source et distribué sous licence MIT. Vous pouvez le créer à partir du code source ou l'installer à partir de NuGet :
Install-Package SolutionInspector
L'outil parcourt toute la structure de la solution et applique de nombreuses règles de validation. Les règles sont configurées par des fichiers XML, placés avec d'autres fichiers de solution. Pour contrôler les paramètres projet par projet, il vous suffit d'ajouter le même fichier avec des paramètres différents au dossier de projet correspondant.
Aucun fichier de configuration n'est requis par défaut. Dans ce cas, l'outil appliquera toutes les règles disponibles et rapportera tous les problèmes à la console.
Voici l'exemple de fichier de configuration :
<?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>
Bien que les paramètres soient plutôt descriptifs, je vais en expliquer certains :
-
MinSolutionFormatVersion
/MaxSolutionFormatVersion
empêchera vos développeurs de changer de version de Visual Studio. -
DetectMissingFiles
est très utile pour le contenu Web statique ou d'autres fichiers non codés ajoutés à la solution ou à un projet. -
AllowBuildEvents
peut empêcher l'ajout d'événements de génération personnalisés, qui peuvent faire des choses inutiles. - Les
Properties
sont l'élément le plus flexible : vous pouvez vérifier toutes les propriétés par rapport aux valeurs souhaitées, qu'il s'agisse de propriétés connues ou personnalisées.
Conclusion
Nous avons passé en revue plusieurs pratiques standard, fichiers de configuration et paramètres de projet que vous pouvez appliquer lors du démarrage d'un nouveau projet. Faire cela au tout début réduirait la dette technique future et donnerait à votre code source de produit un aspect agréable et professionnel. Pour les projets Open Source, cela revêt une importance particulière, car tout contributeur connaîtrait vos attentes en examinant les configurations de la solution et les fichiers du projet.