Cómo Arrancar y Crear Proyectos .NET

Publicado: 2022-03-11

Crear proyecto .NET

Crear un proyecto .NET desde cero es tan simple como usar el asistente de Visual Studio. Vaya a File => New Project o Add New Project a una solución existente. Una vez que se ha creado un nuevo proyecto, puede comenzar a codificar de inmediato. Sin embargo, la configuración predeterminada del proyecto producida por los asistentes es difícilmente aceptable para los equipos profesionales, ya que establece un nivel de calidad demasiado bajo. Además, ningún asistente puede conocer otros pasos de configuración que debe realizar en su entorno de desarrollo particular.

En este artículo, lo guiaré a través de varias configuraciones importantes que debe habilitar tan pronto como cree un nuevo proyecto, lo cual es importante para minimizar una futura deuda técnica. Además, revisaremos algunas prácticas comunes que muchos desarrolladores de .NET aplican cuando están estructurando soluciones y nuevos proyectos. Incluso si no está aplicando algunas de estas ideas, es bueno aprender y obtener una visión general de lo que hacen la mayoría de los equipos.

Estructura

Tener una estructura bien definida es vital para proyectos complejos. Esto mejora la experiencia de incorporación cuando los recién llegados se unen a un equipo y hace que su vida sea más fácil cuando apoya proyectos antiguos. Hay dos indicadores clave de una buena estructura:

  • Uso de carpetas de soluciones y proyectos
  • Denominación consistente

Carpetas

Las carpetas de soluciones, a veces denominadas carpetas virtuales , son un instrumento muy útil para agrupar sus proyectos. En la vista del Explorador de soluciones , simplemente haga clic con el botón derecho y seleccione Add => New Solution Folder , luego arrastre y suelte cualquiera de los proyectos existentes en esta nueva carpeta. Estas carpetas no se reflejan en el sistema de archivos, lo que le permite mantener la estructura física sin cambios, por lo que mover los proyectos de una carpeta de soluciones a otra no los mueve físicamente.

Ventana del Explorador de soluciones que muestra la estructura del proyecto con carpetas "1 - Común", "2 - Datos", "3 - Servidor" y "4 - Cliente".

No es necesario tener prefijos numerados, pero hace que las carpetas aparezcan ordenadas directamente en la ventana del Explorador de soluciones .

Visual Studio puede trabajar con varias soluciones al mismo tiempo aprovechando los modelos de soluciones únicas con particiones o soluciones múltiples . Rara vez se usan, por lo que no los trataré en este artículo.

A diferencia de las carpetas de soluciones, las carpetas de proyectos coinciden con la estructura de carpetas físicas y, por lo tanto, persisten como carpetas reales en el disco. Además, las carpetas de proyectos que contienen un código C# deben coincidir con el espacio de nombres del proyecto. Esto hace que la navegación sea bastante natural. Incluso puede habilitar una regla de ReSharper para advertir sobre tales discrepancias.

Denominación

Hay algunas reglas recomendadas para aplicar relacionadas con la denominación:

  • Utilice CamelCase.
  • Un nombre de proyecto debe coincidir con su nombre de ensamblado de salida.
  • Un proyecto que contenga pruebas automatizadas debe tener el sufijo .Tests .
  • Todos los nombres de proyectos deben tener un prefijo común, como Company.Product .

El mismo proyecto que antes, pero con una nueva carpeta, "4.1 - Pruebas" que contiene MyCompany.MyProduct.Windows.Controls.Tests.

Hay pocas reglas razonables también. Debes decidir por tu cuenta cuándo aplicarlos según el sentido común (y la gramática inglesa, por supuesto):

  • Utilice sujetos en forma plural cuando un contenedor (proyecto o carpeta) contiene varias instancias del mismo tipo (por ejemplo, Tests o System.Collections ).
  • Use la forma singular cuando todo el contenedor contenga código sobre una sola entidad (por ejemplo, System.Collections.ObjectModel`).
  • Para abreviaturas cortas, use mayúsculas como lo hace System.IO .
  • Para abreviaturas largas, use CamelCase como Modules.Forex. .

Una regla general: una abreviatura corta no debe tener más de tres caracteres.

Solución de configuración

Configurar una solución es tan simple como proporcionar todos los archivos de infraestructura que necesita para su entorno. Aunque algunos de ellos se pueden agregar más adelante (como los archivos de integración de CI), es mejor tener pocos archivos desde el principio.

Configuración de ReSharper

Si es un desarrollador profesional de .NET, es muy probable que utilice ReSharper. ReSharper es muy flexible en la gestión de su configuración. Como líder de equipo, puede crear y distribuir configuraciones compartidas de equipo que usarán otros desarrolladores. La configuración de Team Shared se almacena en un archivo con extensión .DotSettings . ReSharper seleccionará estas configuraciones automáticamente si el nombre del archivo coincide con el nombre de la solución de Visual Studio:

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

Por lo tanto, debe crear este archivo desde el principio si finalmente desea aplicar algunas configuraciones a todo el equipo. Un buen ejemplo sería la regla de usar (o no usar) la palabra clave var . Su archivo de configuración compartida del equipo puede tener solo esta regla, mientras que otras son las preferencias de los desarrolladores. Vale la pena mencionar que, de la misma manera, la configuración de ReSharper se puede establecer a nivel de proyecto, porque es posible que tenga algún código heredado que no pueda modificar (por ejemplo, cambie para usar la palabra clave var ).

Si nombró este archivo correctamente, como se muestra en el ejemplo, cualquier instancia nueva de Visual Studio con una configuración nueva de ReSharper seleccionará este archivo automáticamente y aplicará las reglas. No olvide enviar este archivo al control de código fuente.

Reglas de StyleCop

Al igual que la configuración de ReSharper, puede compartir la configuración de StyleCop. Si usa ReSharper, probablemente tenga instalado un complemento de integración que aprovechará StyleCop de ReSharper. Sin embargo, StyleCop almacena su configuración de forma independiente en archivos denominados Settings.StyleCop . Del mismo modo, puede tener este archivo junto con el archivo de solución y los archivos de proyecto.

Si está utilizando StyleCop, no olvide ejecutar la herramienta de configuración de StyleCop y desactive las comprobaciones que no desea realizar. De forma predeterminada, todas las comprobaciones están habilitadas. Guarde la nueva configuración en este archivo y comprométase con el control de código fuente.

Archivos de texto

Si está creando un producto público y va a publicar el código fuente, no olvide crear y confirmar estos archivos también:

 README.md LICENSE

Recomiendo usar el formato Markdown para el archivo README.md , porque se convirtió en un estándar industrial y es compatible con servicios públicos de control de fuente como GitHub, así como servidores internos como BitBucket (antes Stash).

Especificaciones NuGet

Si está creando una biblioteca que se distribuirá en NuGet Gallery, es muy probable que necesite crear archivos de especificación de paquetes, como MyProject.nuspec . Prefiero crear estos archivos manualmente y enviarlos al control de código fuente. Los paquetes generalmente son liberados por uno de sus trabajos de Integración Continua (CI para abreviar), pero también en cualquier momento puede crear y publicar un paquete manualmente desde la consola de la siguiente manera:

 nuget.exe pack MyLibrary.nuspec

Simplemente no olvide incrementar la versión del paquete antes de ejecutar este comando.

Archivos específicos de CI

Todos usamos diferentes servidores CI, y todos tienen diferentes scripts y configuraciones de configuración. Solo mencionaría algunas de las adiciones comunes que puede considerar agregar:

  • Configuración de NUnit , que especifica qué ensamblajes contienen pruebas que se ejecutarán en el servidor de CI para trabajos particulares. Todas las pruebas están prácticamente divididas en unas pocas categorías. Hay pruebas unitarias que deben ejecutarse en cada compilación, pruebas de rendimiento que se ejecutan todas las noches y pruebas de integración que se ejecutan por versión.
  • Configuración de NCover , que especifica qué ensamblajes de prueba deben analizarse para la cobertura de prueba.
  • Se recopilarán los ajustes de SonarQube , que determinan las métricas del software.
  • Scripts de trabajo , como NAnt, PowerShell o simplemente archivos por lotes de Windows.
Un proyecto iniciado correctamente reduce la deuda técnica futura y hace que el código fuente del producto sea legible y de apariencia profesional.
Pío

Configuración de proyectos

Los archivos de proyecto, a saber, .csproj o .vbpro , contienen todas las configuraciones utilizadas por Visual Studio y MSBuild. Sin embargo, no todos están disponibles en la ventana Propiedades del proyecto. Para editar estos archivos en Visual Studio manualmente, debe hacer lo siguiente:

  • Haga clic con el botón derecho en un proyecto en la vista Explorador de soluciones.
  • Seleccione Descargar proyecto .
  • Haga clic con el botón derecho nuevamente para elegir la acción Editar xyz.csproj .
  • Edición completa.
  • Vuelva a hacer clic con el botón derecho en el proyecto y seleccione Recargar proyecto .

Alternativamente, puede abrir un archivo de proyecto en su editor de texto favorito, editarlo y guardarlo. Cuando regrese a la ventana de Visual Studio, se le pedirá que vuelva a cargar el proyecto modificado.

Control de Advertencias

La creación de un software de alta calidad requiere que nunca ignore las advertencias de compilación. Por lo tanto, debe habilitar el nivel máximo de advertencias y tratar las advertencias como errores. Tenga en cuenta que debe hacer esto para todas las configuraciones de compilación que tenga, como Depurar y Liberar. La mejor manera de hacer esto es escribir la siguiente configuración en el grupo de propiedades comunes:

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

Y asegúrese de no tener la misma configuración en otros grupos de propiedades. De lo contrario, anularán las propiedades correspondientes del grupo común.

FxCop

Ejecutar FxCop es meramente práctico en cada compilación. La mayoría de los equipos prefieren ejecutar FxCop de vez en cuando (generalmente antes de un lanzamiento) para asegurarse de que no se hayan introducido errores graves. Sin embargo, si desea realizar una verificación definitiva en cada compilación, agregue esta opción:

 <RunCodeAnalysis>true</RunCodeAnalysis>

Tenga en cuenta que FxCop, como StyleCop, tiene su propia configuración que se puede colocar en la carpeta raíz y agregar al control de código fuente. Es probable que esta configuración se use cuando se ejecuta FxCop en servidores CI.

Documentación

Esta parte es sobre XmlDoc. Si está creando una API pública, debe crear y mantener la documentación de la API. La mayoría de los desarrolladores comienzan con el desarrollo de API (codificación real), y justo antes de un lanzamiento, habilitan la configuración del proyecto Build / XML documentation file . Naturalmente, después de otra reconstrucción, aparecen un montón de errores, porque cada XmlDoc que falta genera un error de compilación. Para evitar esto, debe habilitar la opción mencionada desde el principio.

Si le da pereza escribir una documentación adecuada o no le gusta escribir demasiado texto, pruebe instrumentos que automaticen este proceso, como GhostDoc.

Código de Contratos

Code Contracts es un excelente marco de Microsoft Research, que le permite expresar condiciones previas, condiciones posteriores e invariantes de objetos en su código para la verificación del tiempo de ejecución, el análisis estático y la documentación. Usé esto en muchos proyectos críticos y me ayudó mucho, así que te animo a que lo pruebes.

Si decide utilizar contratos de código, es importante habilitar los contratos desde el principio, cuando acaba de crear un nuevo proyecto. Es posible agregar contratos en medio del desarrollo, pero requerirá cambios a través de muchas clases para que los contactos coincidan entre sí. Por lo tanto, no olvide habilitar todas las configuraciones requeridas (al menos CodeContractsEnableRuntimeChecking ) y asegúrese de que estas configuraciones aparezcan en el grupo de propiedades comunes.

Cumplimiento de StyleCop

Anteriormente hablamos sobre la configuración de StyleCop para el tiempo de desarrollo. Sin embargo, cuando su proyecto se crea en un servidor CI, ReSharper no tiene ningún efecto allí y, por lo tanto, debemos habilitar la validación de StyleCop para que se ejecute con MSBuild.

Esto generalmente se hace mediante la modificación manual del archivo del proyecto. Debe descargar el proyecto en Visual Studio, editar el archivo del proyecto y luego volver a cargar el proyecto:

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

La configuración StyleCopTreatErrorsAsWarnings hará lo que dice: romperá su compilación en cualquier violación de la regla StyleCop. El elemento de importación es necesario para que MSBuild agregue la tarea StyleCop a la cadena de compilación.

Es posible que haya notado la ruta a Program Files . Debido a que los desarrolladores pueden tener instaladas diferentes versiones de StyleCop, algunos equipos prefieren mantener una copia privada de la misma instalación de StyleCop bajo control de código fuente. En este caso, la ruta será relativa. Esto también facilita la configuración de las máquinas CI, ya que no necesita instalar StyleCop localmente.

Información de ensamblaje

Cada proyecto .NET creado por el asistente de Visual Studio tendrá el archivo AssemblyInfo.cs rellenado automáticamente (consulte la subcarpeta Propiedades ) que contiene algunos de los atributos de Assembly , pero ningún asistente puede completar todos los atributos de Assembly por usted. Asegúrese de tener al menos estos atributos completos:

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

Una captura de pantalla de Visual Studio que muestra seis líneas, todas entre corchetes, dentro de las cuales cada una comienza con "ensamblaje:". Cada línea tiene uno de los atributos enumerados anteriormente y una cadena de texto de ejemplo correspondiente entre paréntesis y comillas. Por ejemplo, el último es "1.0.0.0".

Este mínimo es necesario para cualquier ensamblaje que vaya a distribuir. Una razón práctica detrás de esto es NuGet: si está utilizando la creación automática de especificaciones de NuGet a partir del archivo de ensamblaje seleccionado, esta herramienta obtendrá la información necesaria de estas propiedades.

También puede completar una propiedad más desde el principio:

 InternalsVisibleTo

Esta propiedad hace que las clases e interfaces internas sean visibles para el ensamblado especificado. Esto generalmente se usa para pruebas automatizadas que va a crear para su proyecto.

Cadenas de conexión

Cómo administrar las cadenas de conexión es una pregunta muy popular en Stack Overflow. El problema es cómo hacer que las cadenas de conexión sean únicas para cada desarrollador o trabajo de CI y no exponer los detalles de la conexión al publicar el código fuente.

En App.config (para aplicaciones de escritorio) o Web.config (para aplicaciones web), realice la siguiente configuración que cargará el archivo user.config en tiempo de ejecución. Mantenga esto bajo su control de fuente:

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

Aparentemente, el archivo user.config debe excluirse del control de fuente, y cada desarrollador debe tener una copia local de este archivo, preservando la privacidad de la cadena de conexión:

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

.gitignore

Para aquellos que usan Git como control de código fuente, es importante agregar algunos patrones de archivo al archivo .gitignore . Sin embargo, nuestra comunidad inteligente ya ha creado un archivo generalizado, que se puede encontrar aquí: github.com/github/gitignore/blob/master/VisualStudio.gitignore.

Debe tomarlo como un archivo .gitignore de referencia y simplemente agregar las exclusiones personalizadas que pueda necesitar adicionalmente.

Insignias de GitHub

Es posible que haya visto insignias bonitas que aparecen en la página del proyecto README . Si está publicando su proyecto en GitHub, considere conectar su proyecto a servicios públicos para:

  • Construcción: para mostrar que una construcción está fallando o aprobando.
  • Pruebas: para mostrar la cobertura de la prueba y el estado de ejecución de la prueba.
  • Publicación: para mostrar la última versión del paquete NuGet.

Puede encontrar una lista completa de insignias y servicios relacionados en shields.io. Puede encontrar muchas insignias interesantes que son buenas para proyectos de código abierto.

Una vez que haya registrado su proyecto con un servicio seleccionado, se le proporcionará un enlace a la imagen y un enlace completo de sintaxis de rebajas, que puede agregar a su archivo README.md . Por cierto, esta es una de las razones por las que debería preferir Markdown para los archivos Léame .

Ejemplos de insignias de rebajas, del proyecto 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: tabla de pruebas unitarias, que muestra una insignia de "construcción aprobada" en cada celda. Las filas son estabilización, maestro, estabilización futura, futuro y revisión; las columnas son Linux y Mac OSX. También hay una insignia de "gitter join chat" en la esquina inferior izquierda después de la mesa.

Validación automática de la estructura de la solución

Aunque haya establecido todas las configuraciones que discutimos en este artículo, tarde o temprano uno de sus desarrolladores puede cambiarlas y enviar los cambios al control de código fuente. A veces, esto sucede por error y, a menudo, estos cambios no se detectan durante la revisión del código. Además de estos accidentes, debemos estar atentos a los siguientes errores comunes:

  • Malas referencias : cuando alguien hace referencia a un ensamblado local que otros tal vez no tengan, o cuando alguien eliminó un archivo del disco, mientras que el enlace a ese archivo permanece en el archivo .csproj . Esto romperá la compilación con seguridad, pero puede suceder demasiado tarde una vez que se presiona el cambio y otros lo retiran. Esto es especialmente crucial para los archivos web estáticos, que no puede verificar durante la compilación.
  • Coherencia de nomenclatura : las herramientas como StyleCop pueden controlar el código fuente de C#, pero ninguna herramienta puede aplicar reglas para archivos de proyecto o propiedades de ensamblaje. Un buen ejemplo es este: queremos nombrar proyectos para que coincidan con el nombre del ensamblado de salida y queremos que los nombres de los proyectos tengan un prefijo común como MyCompany.MyProduct .

Descubrí que observar estos errores en Code Reviews es propenso a errores y debe automatizarse. Así que escribí una herramienta simple que realiza estas y muchas otras comprobaciones para verificar la consistencia de la solución. Conozca SolutionInspector. Esto es de código abierto y se distribuye bajo licencia MIT. Puede compilarlo desde el código fuente o instalarlo desde NuGet:

 Install-Package SolutionInspector

La herramienta recorre toda la estructura de la solución y aplica muchas reglas de validación. Las reglas se configuran mediante archivos XML, colocados junto con otros archivos de solución. Para controlar la configuración por proyecto, simplemente agregue el mismo archivo con diferentes configuraciones a la carpeta del proyecto correspondiente.

No se requiere ningún archivo de configuración de forma predeterminada. En este caso, la herramienta aplicará todas las reglas disponibles y entregará todos los problemas a la consola.

Aquí está el ejemplo del archivo de configuración:

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

Aunque los ajustes son bastante descriptivos, voy a explicar algunos de ellos:

  • MinSolutionFormatVersion / MaxSolutionFormatVersion evitará que sus desarrolladores cambien la versión de Visual Studio.
  • DetectMissingFiles es muy útil para contenido web estático u otros archivos sin código agregados a la solución o un proyecto.
  • AllowBuildEvents puede evitar que se agreguen eventos de compilación personalizados, lo que puede hacer cosas innecesarias.
  • Properties son el elemento más flexible: puede comparar cualquier propiedad con los valores deseados, ya sean propiedades conocidas o personalizadas.

Conclusión

Hemos revisado varias prácticas estándar, archivos de configuración y configuraciones de proyectos que puede aplicar al iniciar un nuevo proyecto. Hacer esto desde el principio disminuirá la deuda técnica futura y hará que el código fuente de su producto se vea agradable y profesional. Para los proyectos de código abierto, esto es de particular importancia, porque cualquier colaborador conocería sus expectativas al examinar las configuraciones de la solución y los archivos del proyecto.

Relacionado: .NET Core - Volviéndose salvaje y de código abierto. Microsoft, ¿por qué te tomó tanto tiempo?