Comment démarrer et créer des projets .NET

Publié: 2022-03-11

Cré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.

Fenêtre de l'Explorateur de solutions affichant la structure du projet avec les dossiers « 1 - Common », « 2 - Data », « 3 - Server » et « 4 - Client ».

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 .

Le même projet qu'avant, mais avec un nouveau dossier, "4.1 - Tests" contenant MyCompany.MyProduct.Windows.Controls.Tests.

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 ou System.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.
Un projet correctement amorcé réduit la dette technique future et rend le code source du produit lisible et d'aspect professionnel.
Tweeter

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

Une capture d'écran de Visual Studio montrant six lignes, toutes entourées de crochets, dans lesquelles chacune commence par "assembly: ". Chaque ligne possède l'un des attributs répertoriés ci-dessus et un exemple de chaîne de texte correspondante entre parenthèses et guillemets. Par exemple, le dernier est "1.0.0.0".

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 :

[![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 - Tableau des tests unitaires, affichant un badge "build pass" dans chaque cellule. Les lignes sont stabilisation, master, future-stabilisation, future et hotfix ; les colonnes sont Linux et Mac OSX. Il y a aussi un badge "gitter join chat" dans le coin inférieur gauche après le tableau.

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.

En relation : .NET Core - Going Wild et Open Source. Microsoft, qu'est-ce qui vous a pris si longtemps ? !