Cum să bootstrap și să creezi proiecte .NET

Publicat: 2022-03-11

Creați un proiect .NET

Pentru a crea un proiect .NET de la zero este la fel de simplu ca folosirea expertului Visual Studio. Accesați File => New Project sau Add New Project la o soluție existentă. Odată ce un nou proiect a fost creat, puteți începe imediat codificarea. Cu toate acestea, setările implicite ale proiectului produse de vrăjitori sunt cu greu acceptabile pentru echipele profesionale, deoarece stabilesc un standard prea scăzut pentru calitate. În plus, niciun vrăjitor nu poate ști despre alți pași de configurare pe care trebuie să îi efectuați în mediul dumneavoastră de dezvoltare particular.

În acest articol, vă voi ghida prin câteva setări importante pe care ar trebui să le activați de îndată ce creați un nou proiect, ceea ce este important pentru a minimiza o viitoare datorie tehnică. De asemenea, vom trece în revistă câteva practici comune pe care mulți dezvoltatori .NET le aplică atunci când structurează soluții și proiecte noi. Chiar dacă nu aplicați unele dintre aceste idei, este plăcut să învățați și să obțineți o imagine de ansamblu asupra a ceea ce fac majoritatea echipelor.

Structura

A avea o structură bine definită este vitală pentru proiectele complexe. Acest lucru îmbunătățește experiența de îmbarcare atunci când noii veniți se alătură unei echipe și vă face viața mai ușoară atunci când susțineți proiecte vechi. Există doi indicatori cheie ai unei structuri bune:

  • Utilizarea folderelor de soluții și proiecte
  • Denumirea consecventă

Foldere

Dosarele cu soluții, denumite uneori foldere virtuale , sunt un instrument foarte util pentru a vă grupa proiectele. În vizualizarea Solution Explorer , faceți clic dreapta și selectați Add => New Solution Folder , apoi trageți și plasați oricare dintre proiectele existente în acest nou folder. Aceste foldere nu sunt reflectate în sistemul de fișiere, permițându-vă să păstrați structura fizică neschimbată, astfel încât mutarea proiectelor dintr-un folder de soluții în altul nu le mută fizic.

Fereastra Solution Explorer care arată structura proiectului cu folderele „1 - Common”, „2 - Data”, „3 - Server” și „4 - Client”.

Nu este necesar să aveți prefixe numerotate, dar face ca folderele să apară ordonate chiar în fereastra Solution Explorer .

Visual Studio poate lucra cu mai multe soluții în același timp, utilizând o singură soluție partiționată sau modele cu soluții multiple . Sunt rar folosite, așa că nu le voi acoperi în acest articol.

Spre deosebire de folderele Solution , folderele Project se potrivesc cu structura fizică a folderelor și, prin urmare, persistă ca foldere reale pe disc. Mai mult, folderele Project care conțin un cod C# ar trebui să se potrivească cu spațiul de nume al proiectului. Acest lucru face navigarea destul de naturală. Puteți chiar să activați o regulă ReSharper pentru a avertiza cu privire la astfel de nepotriviri.

Denumire

Există câteva reguli recomandate de aplicat legate de denumire:

  • Utilizați CamelCase.
  • Numele unui proiect trebuie să se potrivească cu numele ansamblului său de ieșire.
  • Un proiect care conține teste automatizate ar trebui să aibă sufixul .Tests .
  • Toate numele proiectelor ar trebui să aibă un prefix comun, cum ar fi Company.Product .

Același proiect ca înainte, dar cu un folder nou, „4.1 - Teste” care conține MyCompany.MyProduct.Windows.Controls.Tests.

Există și puține reguli rezonabile. Ar trebui să decideți singur când să le aplicați pe baza bunului simț (și a gramaticii engleze, desigur):

  • Folosiți subiecte la plural atunci când un container (proiect sau folder) conține mai multe instanțe de același fel (de ex. Tests sau System.Collections ).
  • Utilizați forma singulară atunci când întregul container conține cod despre o singură entitate (de exemplu, System.Collections.ObjectModel`).
  • Pentru abrevieri scurte, utilizați majuscule, așa cum o face System.IO .
  • Pentru abrevieri lungi, utilizați CamelCase precum Modules.Forex. .

O regulă generală: o abreviere scurtă nu trebuie să depășească trei caractere.

Soluție de configurare

Configurarea unei soluții este la fel de simplă ca furnizarea tuturor fișierelor de infrastructură de care aveți nevoie pentru mediul dumneavoastră. Deși unele dintre ele pot fi adăugate mai târziu (cum ar fi fișierele de integrare CI), puține fișiere pe care le-ați avea mai bine la început.

Setări ReSharper

Dacă sunteți un dezvoltator profesionist .NET, atunci foarte probabil că utilizați ReSharper. ReSharper este foarte flexibil în gestionarea setărilor sale. În calitate de lider de echipă, puteți crea și distribui setări Team Shared care vor fi folosite de alți dezvoltatori. Setările Team Shared sunt stocate într-un fișier cu extensia .DotSettings . ReSharper va alege automat aceste setări dacă numele fișierului se potrivește cu numele soluției Visual Studio:

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

Prin urmare, ar trebui să creați acest fișier chiar de la început, dacă în cele din urmă doriți să aplicați unele setări întregii echipe. Un bun exemplu ar fi regula de a folosi (sau de a nu folosi) cuvântul cheie var . Fișierul dvs. de setări Team Shared poate avea doar această regulă, în timp ce altele sunt preferința dezvoltatorilor. Este demn de menționat că, în același mod, setările ReSharper pot fi setate la nivel de proiect, deoarece este posibil să aveți un cod moștenit pe care nu îl puteți modifica (de exemplu, modificați pentru a utiliza cuvântul cheie var ).

Dacă ați denumit corect acest fișier, așa cum se arată în exemplu, atunci orice instanță nouă a Visual Studio cu o nouă configurare ReSharper va alege automat acest fișier și va aplica regulile. Nu uitați să trimiteți acest fișier în controlul sursei.

Regulile StyleCop

La fel ca și setările ReSharper, puteți partaja setările StyleCop. Dacă utilizați ReSharper, probabil că aveți instalat un plugin de integrare care va folosi StyleCop de la ReSharper. Cu toate acestea, StyleCop își stochează setările în mod independent în fișierele numite Settings.StyleCop . În mod similar, puteți avea acest fișier împreună cu fișierul de soluție și fișierele de proiect.

Dacă utilizați StyleCop, nu uitați să rulați instrumentul de configurare StyleCop și să dezactivați verificările pe care nu doriți să le efectuați. În mod implicit, toate verificările sunt activate. Salvați setările noi în acest fișier și trimiteți-vă la controlul sursei.

Fișiere text

Dacă construiți un produs public și intenționați să publicați codul sursă, nu uitați să creați și să comiteți și aceste fișiere:

 README.md LICENSE

Recomand să folosiți formatul markdown pentru fișierul README.md , deoarece a devenit un standard industrial și a fost susținut de servicii publice de control sursă precum GitHub, precum și de servere interne precum BitBucket (fostul Stash).

Specificații NuGet

Dacă construiți o bibliotecă care urmează să fie distribuită în NuGet Gallery, atunci foarte probabil trebuie să creați fișiere de specificații ale pachetului, cum ar fi MyProject.nuspec . Prefer să creez aceste fișiere manual și să le commit la controlul sursei. Pachetele sunt de obicei eliberate de unul dintre joburile dvs. de Integrare continuă (CI pe scurt), dar, de asemenea, în orice moment puteți construi și publica un pachet manual din consolă, după cum urmează:

 nuget.exe pack MyLibrary.nuspec

Doar nu uitați să creșteți versiunea pachetului înainte de a executa această comandă.

fișiere specifice CI

Cu toții folosim servere CI diferite și toate au scripturi și setări de configurare diferite. Aș menționa doar câteva dintre completările comune pe care ați putea să vă gândiți să le adăugați:

  • Setările NUnit , care specifică ce ansambluri conțin teste care trebuie executate pe serverul CI pentru anumite joburi. Toate testele sunt practic împărțite în câteva categorii. Există teste unitare care ar trebui să fie rulate pe fiecare versiune, teste de performanță care sunt executate noaptea și testele de integrare sunt executate pe fiecare lansare.
  • Setările NCover , care specifică ce ansambluri de testare trebuie analizate pentru acoperirea testului.
  • Vor fi colectate setările SonarQube , care determină valorile software.
  • Scripturi de job , cum ar fi NAnt, PowerShell sau pur și simplu fișiere batch Windows.
Un proiect bootstrap corespunzător reduce datoria tehnică viitoare și face codul sursă al produsului lizibil și cu aspect profesional.
Tweet

Configurarea proiectelor

Fișierele de proiect, și anume .csproj sau .vbpro , conțin toate setările utilizate de Visual Studio și MSBuild. Cu toate acestea, nu toate sunt disponibile din fereastra Proprietăți proiect. Pentru a edita manual aceste fișiere în Visual Studio, ar trebui să faceți următoarele:

  • Faceți clic dreapta pe un proiect în vizualizarea Solution Explorer.
  • Selectați Descărcați proiectul .
  • Faceți clic dreapta din nou pentru a alege acțiunea Editare xyz.csproj .
  • Editare completă.
  • Faceți clic dreapta pe proiect din nou și alegeți Reîncărcați proiectul .

Alternativ, puteți deschide un fișier proiect în editorul de text preferat, îl puteți edita și salva. Când reveniți la fereastra Visual Studio, vi se va solicita să reîncărcați proiectul modificat.

Controlul avertismentelor

Construirea unui software de înaltă calitate necesită să nu ignorați niciodată avertismentele de construcție. Prin urmare, ar trebui să activați nivelul maxim de avertismente și să tratați orice avertismente ca erori. Rețineți că ar trebui să faceți acest lucru pentru toate configurațiile de compilare pe care le aveți, cum ar fi Debug și Release. Cel mai bun mod de a face acest lucru este să scrieți următoarele setări în grupul de proprietăți comun:

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

Și asigurați-vă că nu aveți aceleași setări în alte grupuri de proprietăți. În caz contrar, vor suprascrie proprietățile corespunzătoare din grupul comun.

FxCop

Rularea FxCop este pur și simplu practică pentru fiecare construcție. Majoritatea echipelor preferă să ruleze FxCop din când în când (de obicei înainte de lansare) pentru a se asigura că nu au fost introduse erori grave. Cu toate acestea, dacă doriți să efectuați verificarea finală pentru fiecare construcție, adăugați această opțiune:

 <RunCodeAnalysis>true</RunCodeAnalysis>

Rețineți că FxCop, ca și StyleCop, are propriile setări care pot fi plasate în folderul rădăcină și adăugate la controlul sursă. Aceste setări sunt probabil folosite atunci când rulați FxCop pe servere CI.

Documentație

Această parte este despre XmlDoc. Dacă construiți un API public, atunci ar trebui să creați și să mențineți documentația API. Majoritatea dezvoltatorilor încep cu dezvoltarea API (codificare reală) și chiar înainte de lansare activează setarea proiectului Build / XML documentation file . Desigur, după o altă reconstrucție apar o grămadă de erori, deoarece fiecare XmlDoc lipsă duce la o eroare de compilare. Pentru a evita acest lucru, ar trebui să activați opțiunea menționată chiar de la început.

Dacă vă este prea lene să scrieți o documentație adecvată sau nu vă place să introduceți prea mult text, încercați instrumente care automatizează acest proces, cum ar fi GhostDoc.

Contracte de cod

Code Contracts este un cadru excelent de la Microsoft Research, care vă permite să exprimați precondiții, postcondiții și invarianți de obiect în cod pentru verificarea timpului de execuție, analiză statică și documentare. L-am folosit în multe proiecte critice și a ajutat foarte mult, așa că vă încurajez să încercați.

Dacă decideți să utilizați Code Contracts, atunci este important să activați Contracts chiar la început, când tocmai ați creat un nou proiect. Adăugarea de contracte în mijlocul dezvoltării este posibilă, dar va necesita modificări prin mai multe clase, pentru ca contactele să se potrivească între ele. Deci, nu uitați să activați toate setările necesare (cel puțin CodeContractsEnableRuntimeChecking ) și asigurați-vă că aceste setări apar în grupul de proprietăți comun.

Aplicarea StyleCop

Anterior am vorbit despre configurația StyleCop pentru timpul de dezvoltare. Cu toate acestea, atunci când proiectul dvs. este construit pe un server CI, ReSharper nu are niciun efect acolo și, prin urmare, ar trebui să permitem validarea StyleCop să ruleze cu MSBuild.

Acest lucru se face de obicei prin modificarea manuală a fișierului de proiect. Trebuie să descărcați proiectul în Visual Studio, să editați fișierul de proiect și apoi să încărcați proiectul înapoi:

 <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">

Setarea StyleCopTreatErrorsAsWarnings va face ceea ce spune: vă va distruge construcția pe orice încălcare a regulii StyleCop. Elementul de import este necesar pentru ca MSBuild să adauge sarcina StyleCop la lanțul de compilare.

Este posibil să fi observat calea către Program Files . Deoarece dezvoltatorii pot avea diferite versiuni de StyleCop instalate, unele echipe preferă să păstreze o copie privată a aceleiași instalări StyleCop sub controlul sursei. În acest caz, calea va fi relativă. Acest lucru facilitează, de asemenea, configurarea mașinilor CI, deoarece nu este nevoie să instalați StyleCop local.

Informații de asamblare

Fiecare proiect .NET creat de expertul Visual Studio va avea fișierul AssemblyInfo.cs populat automat (consultați subfolderul Proprietăți ) care conține unele dintre atributele Assembly , dar niciun expert nu poate completa toate atributele Assembly pentru dvs. Asigurați-vă că aveți cel puțin aceste atribute populate:

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

O captură de ecran a Visual Studio care arată șase linii, toate cuprinse între paranteze drepte, în care fiecare începe cu „asamblare:”. Fiecare linie are unul dintre atributele enumerate mai sus și un șir de text exemplu corespunzător în paranteze și ghilimele. De exemplu, ultimul este „1.0.0.0”.

Acest minim strict este necesar pentru orice ansambluri pe care urmează să le distribuiți. Un motiv practic din spatele acestui lucru este NuGet: dacă utilizați crearea automată a specificațiilor NuGet din fișierul de asamblare selectat, acest instrument va obține informațiile necesare din aceste proprietăți.

De asemenea, puteți popula încă o proprietate la început:

 InternalsVisibleTo

Această proprietate face ca clasele și interfețele interne să fie vizibile pentru ansamblul specificat. Acesta este utilizat în general pentru testele automate pe care urmează să le creați pentru proiectul dvs.

Șiruri de conexiune

Cum să gestionați șirurile de conexiune este o întrebare foarte populară în Stack Overflow. Problema este cum să faceți șirurile de conexiune unice pentru fiecare dezvoltator sau un job CI și să nu expuneți detaliile conexiunii în timpul publicării codului sursă.

În App.config (pentru aplicații desktop) sau Web.config (pentru aplicații web), faceți următoarea setare care va încărca fișierul user.config în timpul rulării. Păstrați asta sub controlul sursei dvs.:

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

Aparent, fișierul user.config ar trebui exclus din controlul sursei și fiecare dezvoltator ar trebui să aibă o copie locală a acestui fișier, păstrând confidențialitatea șirului de conexiune:

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

.gitignore

Pentru cei care folosesc Git ca control sursă, este important să adăugați câteva modele de fișiere la fișierul .gitignore . Cu toate acestea, comunitatea noastră inteligentă a construit deja un fișier generalizat, care poate fi găsit aici: github.com/github/gitignore/blob/master/VisualStudio.gitignore.

Ar trebui să îl luați ca un fișier .gitignore de referință și să adăugați pur și simplu excluderile personalizate de care ați putea avea nevoie suplimentar.

Insigne GitHub

Este posibil să fi văzut insigne frumoase care apar pe pagina proiectului README . Dacă vă publicați proiectul pe GitHub, luați în considerare conectarea proiectului la serviciile publice pentru:

  • Clădire: pentru a arăta că o construcție eșuează sau trece.
  • Testare: pentru a arăta acoperirea testului și starea de execuție a testului.
  • Publicare: pentru a afișa cea mai recentă versiune a pachetului NuGet.

O listă completă de insigne și servicii conexe poate fi găsită pe shields.io. Puteți găsi multe insigne interesante care sunt bune pentru proiecte Open Source.

După ce v-ați înregistrat proiectul cu un serviciu selectat, vi se va oferi un link către imagine și un link complet de sintaxă de markdown, pe care le puteți adăuga în fișierul README.md . Apropo, acesta este unul dintre motivele pentru care ar trebui să preferați reducerea pentru fișierele Readme .

Exemple de insigne de reducere, din proiectul 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 - Tabel de teste unitare, arătând o insignă „de trecere a construirii” în fiecare celulă. Rândurile sunt stabilizare, master, stabilizare în viitor, viitor și remediere rapidă; coloanele sunt Linux și Mac OSX. Există, de asemenea, o insignă „gitter join chat” în colțul din stânga jos după masă.

Validarea automată a structurii soluției

Chiar dacă ați setat toate setările pe care le-am discutat în acest articol, mai devreme sau mai târziu, unul dintre dezvoltatorii dvs. le poate modifica și să comite modificările controlului sursă. Uneori, acest lucru se întâmplă din greșeală și adesea aceste modificări nu sunt surprinse în timpul revizuirii codului. În afară de aceste accidente, ar trebui să fim atenți la următoarele erori comune:

  • Referințe greșite : când cineva face referire la un ansamblu local pe care alții poate nu îl au sau când cineva a șters un fișier de pe disc, în timp ce linkul către acel fișier rămâne în fișierul .csproj . Acest lucru va rupe construcția cu siguranță, dar se poate întâmpla prea târziu odată ce schimbarea este împinsă, iar alții au retras-o. Acest lucru este crucial în special pentru fișierele web statice, pe care nu le puteți verifica în timpul construirii.
  • Consecvența denumirii : instrumentele precum StyleCop pot controla codul sursă C#, dar niciun instrument nu poate impune reguli pentru fișierele de proiect sau proprietățile de asamblare. Un exemplu bun este acesta: dorim să denumim proiectele pentru a se potrivi cu numele ansamblului de ieșire și dorim ca numele proiectelor să aibă un prefix comun, cum ar fi MyCompany.MyProduct .

Am descoperit că urmărirea acestor erori în Code Reviews este predispusă la erori și ar trebui automatizată. Așa că am scris un instrument simplu care efectuează acestea și multe alte verificări pentru a verifica consistența soluției. Faceți cunoștință cu SolutionInspector. Acesta este Open Source și distribuit sub licență MIT. Îl puteți construi din codul sursă sau îl puteți instala din NuGet:

 Install-Package SolutionInspector

Instrumentul parcurge întreaga structură a soluției și aplică multe reguli de validare. Regulile sunt configurate prin fișiere XML, plasate împreună cu alte fișiere de soluție. Pentru a controla setările pe bază de proiect, pur și simplu adăugați același fișier cu setări diferite în folderul de proiect corespunzător.

În mod implicit, nu este necesar niciun fișier de configurare. În acest caz, instrumentul va aplica toate regulile disponibile și va transmite toate problemele consolei.

Iată un exemplu de fișier de configurare:

 <?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>

Deși setările sunt mai degrabă descriptive, voi explica câteva dintre ele:

  • MinSolutionFormatVersion / MaxSolutionFormatVersion va împiedica dezvoltatorii dvs. să schimbe versiunea Visual Studio.
  • DetectMissingFiles este foarte util pentru conținut web static sau alte fișiere fără cod adăugate la soluție sau la un proiect.
  • AllowBuildEvents poate împiedica adăugarea de evenimente personalizate, care pot face lucruri inutile.
  • Properties este cel mai flexibil element: puteți verifica orice proprietăți cu valorile dorite, indiferent dacă acestea sunt proprietăți cunoscute sau personalizate.

Concluzie

Am analizat mai multe practici standard, fișiere de configurare și setări de proiect pe care le puteți aplica atunci când începeți un nou proiect. Făcând acest lucru chiar de la început, ar reduce datoria tehnică viitoare și va face ca codul sursă al produsului să arate frumos și profesionist. Pentru proiectele cu sursă deschisă, acest lucru este de o importanță deosebită, deoarece orice colaborator ar cunoaște așteptările dumneavoastră examinând configurațiile soluției și fișierele de proiect.

Înrudit: .NET Core - Going Wild și Open Source. Microsoft, ce ți-a luat atât de mult?!