Está en la página 1de 613

Contents

Guía de .NET Core


Sobre .NET Core
Instalar
Información general
Instalación del SDK
Instalación del entorno de ejecución
Dependencias y SO admitidos
Cómo comprobar las versiones de .NET Core
Administradores de paquetes de Linux
Ubuntu 19.10
Ubuntu 19.04
Ubuntu 18.04
Ubuntu 16.04
CentOS 7
Debian 10
Debian 9
Fedora 31
Fedora 30
Fedora 29
OpenSUSE 15
RHEL 8.1
RHEL 7
SLES 15
SLES 12
Instalación de una versión localizada de IntelliSense
Primeros pasos
Introducción a C# y Visual Studio Code
Introducción a .NET Core en macOS con Visual Studio Code
Creación de su primera aplicación en Visual Studio
Depuración de una aplicación con Visual Studio
Publicación de una aplicación con Visual Studio
Creación de una biblioteca de .NET Standard en Visual Studio
Prueba de una biblioteca de .NET Standard en Visual Studio
Consumo de una biblioteca de .NET Standard en Visual Studio
Novedades de .NET Core
Novedades de .NET Core 3.1
Novedades de .NET Core 3.0
Novedades de .NET Core 2.2
Novedades de .NET Core 2.1
Novedades de .NET Core 2.0
Cambios importantes
Tutoriales
Plantillas para CLI
1 - Crear una plantilla de elemento
2 - Crear una plantilla de proyecto
3 - Crear un paquete de plantillas
Introducción a .NET Core con Visual Studio para Mac
Compilación de una solución completa de .NET Core en macOS
Introducción a .NET Core con las herramientas de la CLI
Organización y prueba de proyectos con la CLI de .NET Core
Desarrollar bibliotecas con herramientas multiplataforma
Creación de una aplicación .Net Core con complementos
Desarrollo de aplicaciones ASP.NET Core
Hospedaje de .NET Core desde código nativo
Configuración del entorno en tiempo de ejecución
Configuración
Configuración de la compilación
Depuración y configuración de perfiles
Nombre de recolector de elementos no utilizados
Configuración de la globalización
Configuración de redes
Configuración de subprocesos
Interoperabilidad nativa
Exposición de los componentes de .NET Core a COM
Paquetes, metapaquetes y marcos
Cambios en la información general de la CLI
Administración de dependencias
Adiciones al formato csproj
Migración
.NET Core 2.0 a 2.1
Migración desde project.json
Asignación entre project.json y csproj
Migración desde DNX
Implementación de la aplicación
Implementación de aplicaciones con herramientas CLI
Implementación de aplicaciones con Visual Studio
Creación de un paquete NuGet con herramientas multiplataforma
Puesta al día del runtime de implementación autocontenida
Almacenamiento de paquetes en tiempo de ejecución
Docker
Introducción a .NET y Docker
Incluir una aplicación de .NET Core en un contenedor
Herramientas de contenedor de Visual Studio
Herramientas de diagnóstico
Información general
Depuradores administrados
Registro y seguimiento
Herramientas globales de la CLI de .NET Core
dotnet-counters
dotnet-dump
dotnet-trace
Tutoriales de diagnóstico de .NET Core
Depuración de una fuga de memoria
Pruebas unitarias
Procedimientos recomendados para pruebas unitarias
Pruebas unitarias de C# con xUnit
Pruebas unitarias de C# con NUnit
Pruebas unitarias de C# con MSTest
Pruebas unitarias de F# con xUnit
Pruebas unitarias de F# con NUnit
Pruebas unitarias de F# con MSTest
Pruebas unitarias de VB con xUnit
Pruebas unitarias de VB con NUnit
Pruebas unitarias de VB con MSTest
Ejecución de pruebas unitarias selectivas
Salida publicada de una prueba unitaria
Pruebas unitarias dinámicas de proyectos de .NET Core con Visual Studio
Integración continua
Control de versiones
Selección de la versión de .NET Core
Eliminación de entornos de ejecución y SDK obsoletos
Catálogo de identificadores de tiempo de ejecución (RID)
Información general sobre el SDK de .NET Core
CLI de .NET Core
Información general
Herramientas
Herramientas globales
Información general
Creación de una herramienta global
Solución de problemas de uso de herramientas
Acceso elevado
Modelo de extensibilidad
Plantillas personalizadas
Habilitación de la finalización con tabulación
Telemetría
Información general de global.json
Referencia
dotnet
dotnet build
dotnet build-server
dotnet clean
dotnet help
dotnet migrate
dotnet msbuild
dotnet new
dotnet nuget
dotnet nuget delete
dotnet nuget locals
dotnet nuget push
dotnet pack
dotnet publish
dotnet restore
dotnet run
dotnet sln
dotnet store
dotnet test
dotnet tool
dotnet tool install
dotnet tool list
dotnet tool uninstall
dotnet tool update
dotnet vstest
Scripts de dotnet-install
Comandos de referencia del proyecto
dotnet add reference
dotnet list reference
dotnet remove reference
Comandos del paquete del proyecto
dotnet add package
dotnet list package
dotnet remove package
Herramientas adicionales de .NET Core
Herramienta de desinstalación de .NET Core
Proveedor de WCF Web Service Reference
dotnet-svcutil
dotnet-svcutil.xmlserializer
Generador de serializador XML
Portabilidad de .NET Framework
Información general
Análisis de las dependencias de terceros
Portabilidad de las bibliotecas
Organización de proyectos para .NET Core
Tecnologías no disponibles
Herramientas
Uso del paquete de compatibilidad de Windows
Portabilidad de los proyectos de Windows Forms
Portabilidad de los proyectos de WPF
Portabilidad de los proyectos de C++/CLI
Carga de dependencias
Información general
Descripción de AssemblyLoadContext
Carga de detalles
Sondeo de dependencia predeterminado
Carga de ensamblados administrados
Carga de ensamblados satélite
Carga de bibliotecas no administradas
Tutoriales
Creación de una aplicación de .NET Core con complementos
Uso y depuración de la descargabilidad de ensamblado en .NET Core
Compilación de .NET Core a partir del código fuente
Empaquetado de distribución de .NET Core
Documentos de VS 2015/project.json
Guía de .NET Core
08/01/2020 • 3 minutes to read • Edit Online

.NET Core es una plataforma de desarrollo de uso general de código abierto de cuyo mantenimiento se encargan
Microsoft y la comunidad .NET en GitHub. Es multiplataforma, admite Windows, macOS y Linux y puede usarse
para compilar aplicaciones de dispositivo, nube e IoT.
Consulte Acerca de .NET Core para más información sobre .NET Core, incluidas sus características, idiomas y
marcos admitidos y principales API.
Consulte los tutoriales de .NET Core para aprender a crear una aplicación .NET Core sencilla. En unos minutos su
primera aplicación estará lista y funcionando. Si quiere probar .NET Core en su explorador, consulte el tutorial en
línea Números en C#.

Descarga de .NET Core


Descargue el SDK de .NET Core para probar .NET Core en su máquina Windows, macOS o Linux. Si prefiere usar
contenedores de Docker, visite Docker Hub de .NET Core.
Si busca otra versión de .NET Core, todas las versiones de .NET Core están disponibles en la página de descargas
de .NET Core.

.NET Core 3.1


La última versión es .NET Core 3.1. En la versión 3.1 se incluyen mejoras menores con respecto a .NET Core 3.0,
pero .NET Core 3.1 es una versión admitida a largo plazo. Para más información sobre la versión .NET Core 3.1,
vea Novedades de .NET Core 3.1.

Creación de la primera aplicación


Después de instalar el SDK de .NET Core, abra un símbolo del sistema. Escriba los comandos dotnet siguientes
para crear y ejecutar una aplicación C#:

dotnet new console


dotnet run

Debería ver los siguientes resultados:

Hello World!

Soporte técnico
Microsoft admite .NET Core en Windows, macOS y Linux. Varias veces al año, por lo general mensualmente, se
actualiza para aumentar la seguridad y la calidad.
Las distribuciones binarias de .NET Core se compilan y prueban en servidores mantenidos por Microsoft en Azure
y reciben el mismo soporte técnico que cualquier otro producto de Microsoft.
Red Hat admite .NET Core en Red Hat Enterprise Linux (RHEL ). Red Hat compila .NET Core desde el código fuente
y permite que esté disponible en Red Hat Software Collections. Red Hat y Microsoft colaboran para asegurarse de
que .NET Core funciona bien en RHEL.
Sobre .NET Core
20/01/2020 • 15 minutes to read • Edit Online

.NET Core tiene las siguientes características:


Multiplataforma: se ejecuta en los sistemas operativos Windows, macOS y Linux.
Coherente entre arquitecturas: el código se ejecuta con el mismo comportamiento en varias arquitecturas,
como x64, x86 y ARM.
Herramientas de línea de comandos: incluye herramientas de línea de comandos sencillas que se pueden
usar para el desarrollo local y en escenarios de integración continua.
Implementación flexible: Se pueden incluir en la aplicación o se pueden instalar de forma paralela
(instalaciones a nivel de usuario o de sistema). Se puede usar con contenedores de Docker.
Compatible: .NET Core es compatible con .NET Framework, Xamarin y Mono mediante .NET Standard.
Código abierto: la plataforma .NET Core es de código abierto, con licencias de MIT y Apache 2. .NET Core es
un proyecto de .NET Foundation.
Compatible con Microsoft: .NET Core incluye compatibilidad con Microsoft, como se indica en .NET Core
Support (Compatibilidad de .NET Core).

Lenguajes
Los lenguajes C#, Visual Basic y F# pueden usarse para escribir aplicaciones y bibliotecas para .NET Core. Puede
usar estos idiomas en su editor de texto o en su entorno de desarrollo integrado (IDE ) favorito, incluidos:
Visual Studio
Visual Studio Code
Sublime Text
Vim
Esta integración la proporcionan, en parte, los colaboradores de los proyectos OmniSharp e Ionide.

API
.NET Core expone las API de muchos escenarios. A continuación se muestran algunos de estos escenarios:
Tipos primitivos, como System.Boolean y System.Int32.
Colecciones, como System.Collections.Generic.List<T> y System.Collections.Generic.Dictionary<TKey,TValue>.
Tipos de utilidades, como System.Net.Http.HttpClient y System.IO.FileStream.
Tipos de datos, como System.Data.DataSet y DbSet.
Tipos de alto rendimiento, como System.Numerics.Vector y Canalizaciones.
.NET Core proporciona compatibilidad con las API .NET Framework y Mono API implementando la especificación
de .NET Standard.

Marcos de trabajo
Se han creado varias plataformas en .NET Core:
ASP.NET Core
Plataforma universal de Windows (UWP ) de Windows 10
Tizen
Composición
.NET Core consta de las siguientes partes:
El runtime de .NET Core, que proporciona un sistema de tipos, la carga de ensamblados, un colector de
elementos no usados, interoperabilidad nativa y otros servicios básicos. Las bibliotecas de .NET Core
Framework proporcionan tipos de datos primitivos, tipos de composición de aplicaciones y utilidades
fundamentales.
El runtime de ASP.NET, el cual proporciona un marco para crear aplicaciones modernas conectadas a Internet y
basadas en la nube, como aplicaciones web, aplicaciones de IoT y back-ends móviles.
Las herramientas de CLI de .NET Core y compiladores de lenguaje (Roslyn y F#) que habilitan la experiencia de
desarrollador de .NET Core.
La herramienta dotnet, que se usa para iniciar aplicaciones .NET Core y herramientas de CLI. Selecciona el
runtime y lo hospeda, proporciona una directiva de carga de ensamblados e inicia aplicaciones y herramientas.
Estos componentes se distribuyen de las formas siguientes:
Runtime de .NET Core: incluye el runtime y las bibliotecas de la plataforma de .NET Core.
Runtime de ASP.NET Core: incluye el runtime y las bibliotecas de la plataforma de ASP.NET Core y .NET Core.
SDK de .NET Core: incluye las herramientas de CLI de .NET, el runtime de ASP.NET Core y el runtime y la
plataforma de .NET Core.
Código Abierto
.NET Core es código abierto ( licencia MIT) y fue presentado a .NET Foundation por Microsoft en 2014. Ahora es
uno de los proyectos más activos de .NET Foundation. Pueden usarlo todos los individuos y organizaciones con
fines personales, académicos o comerciales. Varias empresas usan .NET Core como parte de aplicaciones,
herramientas, nuevas plataformas y servicios de hospedaje. Algunas de estas empresas realizan contribuciones
significativas a .NET Core en GitHub y proporcionan una guía sobre la dirección del producto como parte del
Technical Steering Group de .NET Foundation.
Diseñado para adaptabilidad
.NET Core se ha creado como un producto muy similar, pero único, en comparación con otros productos .NET. Se
ha diseñado para permitir una amplia adaptabilidad a nuevas plataformas y cargas de trabajo, y tiene varios
puertos de CPU y sistemas operativos disponibles (y se puede portar a muchos más).
El producto se divide en varias partes, lo que permite que las distintas partes se adapten a nuevas plataformas en
horas diferentes. El entorno de tiempo de ejecución y las bibliotecas fundamentales específicas de la plataforma se
deben portar como una unidad. Las bibliotecas independientes de la plataforma deben funcionar, por diseño, en
todas las plataformas, tal y como están. Hay una tendencia del proyecto a reducir las implementaciones específicas
de la plataforma con el fin de aumentar la eficiencia del desarrollador, donde se prefiere el código C#
independiente de la plataforma siempre que se pueda implementar completa o parcialmente un algoritmo o una
API de esa forma.
Le gente se pregunta cómo se implementa .NET Core para que se admita en varios sistemas operativos.
Normalmente preguntan si hay otras implementaciones o si se usa compilación condicional. Son las dos cosas, con
una fuerte tendencia hacia la compilación condicional.
En el gráfico siguiente puede ver que la gran mayoría de bibliotecas de .NET Core es código independiente de la
plataforma que se comparte en todas las plataformas. El código independiente de la plataforma se puede
implementar como un solo ensamblado portátil que se usa en todas las plataformas.
Las implementaciones de Windows y Unix son de tamaño similar. Windows tiene una implementación mayor, ya
que las bibliotecas de .NET Core implementan algunas características que son exclusivas de Windows, como
Microsoft.Win32.Registry, pero aún no implementa muchos conceptos exclusivos de Unix. También verá que la
mayoría de las implementaciones de Linux y macOS se comparten en una implementación de Unix, mientras que
las implementaciones específicas de macOS y Linux son bastante similares en tamaño.
Hay una mezcla de bibliotecas específicas de la plataforma e independientes de la plataforma en .NET Core. Puede
ver el patrón en algunos ejemplos:
CoreCLR es específico de la plataforma. Se compila en los subsistemas de SO, como el administrador de
memoria y el programador de subprocesos.
System.IO y System.Security.Cryptography.Algorithms son específicos de la plataforma, dado que las API de
almacenamiento y criptografía difieren en cada sistema operativo.
System.Collections y System.Linq son independientes de la plataforma, dado que crean estructuras de datos y
funcionan sobre ellas.

Comparación con otras implementaciones de .NET


Puede resultar más fácil comprender la naturaleza de .NET Core si se compara con las implementaciones de .NET
existentes.
Comparación con .NET Framework
Microsoft presentó la plataforma .NET en el año 2000, y a partir de ese momento ha ido evolucionando. .NET
Framework ha sido la principal implementación de .NET producida por Microsoft durante ese periodo de casi dos
décadas.
Las principales diferencias entre .NET Core y .NET Framework son:
Modelos de aplicación: .NET Core no es compatible con todos los modelos de aplicación de .NET Framework.
En concreto, no es compatible con los formularios Web Forms ASP.NET ni ASP.NET MVC, pero sí con
ASP.NET Core MVC. Además, a partir de .NET Core 3.0, .NET Core también es compatible con WPF y
Windows Forms (solo en Windows).
API: .NET Core contiene un amplio subconjunto de bibliotecas de clases base de .NET Framework con una
factorización distinta (los nombres de ensamblado son distintos y los miembros expuestos en los tipos difieren
en los casos clave). En algunos casos, estas diferencias requieren cambios en el origen del puerto de .NET Core.
Para obtener más información, vea Analizador de portabilidad de .NET. .NET Core implementa la especificación
de la API .NET Standard.
Subsistemas: .NET Core implementa un subconjunto de los subsistemas de .NET Framework, de cara a una
implementación y un modelo de programación más sencillos. Por ejemplo, no se admite seguridad de acceso
del código (CAS ), aunque se admite la reflexión.
Plataformas: .NET Framework admite Windows y Windows Server, mientras que .NET Core también es
compatible con macOS y Linux.
Código abierto: .NET Core es código abierto, mientras que un subconjunto de .NET Framework de solo
lectura es código abierto.
Aunque .NET Core es única y tiene diferencias significativas con .NET Framework y otras implementaciones de
.NET, permite compartir código fácilmente entre estas implementaciones mediante técnicas de uso compartido de
origen o binarias.
Debido a que .NET Core admite la instalación en paralelo y el entorno de ejecución es completamente
independiente de .NET Framework, puede instalarse en máquinas con .NET Framework instalado sin ningún
problema.
Comparación con Mono
Mono es la implementación multiplataforma original de .NET. Comenzó como una alternativa de código abierto
para .NET Framework y pasó a tener como objetivo los dispositivos móviles cuando los dispositivos iOS y Android
se popularizaron. Se puede considerar un clon de la comunidad de .NET Framework. El equipo de proyecto de
Mono se basó en los estándares de .NET abiertos (en particular, ECMA 335) publicados por Microsoft para
proporcionar una implementación compatible.
Las principales diferencias entre .NET Core y Mono:
Modelos de aplicación: Mono admite un subconjunto de los modelos de aplicación de .NET Framework (por
ejemplo, Windows Forms) y algunos adicionales para el desarrollo móvil (por ejemplo, Xamarin.iOS ) mediante
el producto de Xamarin. .NET Core no es compatible con Xamarin.
API: Mono admite un gran subconjunto de las API de .NET Framework, con los mismos nombres de
ensamblado y factorización.
PlataformasMono admite muchas plataformas y CPU.
Código abiertoMono y .NET Core usan la licencia MIT y son proyectos de .NET Foundation.
Enfoque: el foco principal de Mono en los últimos años es plataformas móviles, aunque .NET Core se centra en
las cargas de trabajo de la nube y de escritorio.

El futuro
Se anunció que .NET 5 será la próxima versión de .NET Core y representa una unificación de la plataforma. El
proyecto pretende mejorar .NET de varias maneras clave:
Producir un único runtime y un marco de .NET que se pueda usar en todas partes y que tenga
comportamientos de runtime y experiencias de desarrollador uniformes.
Ampliar las funcionalidades de .NET con las mejores características de .NET Core, .NET Framework, Xamarin y
Mono.
Desarrollar el producto a partir de un solo código base que mejore todos los escenarios, que los desarrolladores
(Microsoft y la comunidad) puedan expandir y en el que puedan trabajar juntos.

Para obtener más información sobre lo que está planeado para .NET 5, vea Presentación de .NET 5.
Descarga e instalación de .NET Core
05/12/2019 • 2 minutes to read • Edit Online

En este artículo se proporciona información sobre cómo descargar e instalar .NET Core. Hay dos partes en .NET
Core, el entorno de ejecución, que se usa para ejecutar aplicaciones, y el SDK, que se usa para crear aplicaciones.
El SDK incluye el entorno de ejecución.
Si es un usuario que necesita .NET Core para ejecutar aplicaciones, vea Instalación de .NET Core Runtime.
Si es un desarrollador que necesita .NET Core para crear aplicaciones, vea Instalación del SDK de .NET
Core.

NOTE
El SDK de .NET Core incluye el entorno de ejecución.

Dependencias
.NET Core se admite en Windows, Linux y macOS. Para obtener una lista completa de los requisitos, vea Sistemas
operativos compatibles.
Instalación del SDK de .NET Core
20/01/2020 • 10 minutes to read • Edit Online

En este artículo obtendrá información sobre cómo instalar el SDK de .NET Core. El SDK de .NET Core se usa
para crear aplicaciones y bibliotecas de .NET Core. El entorno de ejecución de .NET Core siempre se instala
con el SDK.

Instalación mediante un instalador


Windows tiene instaladores independientes que se pueden usar para instalar el SDK de .NET Core 3.1:
CPU de x64 (64 bits)
CPU de x86 (32 bits)

Instalación mediante un instalador


macOS tiene instaladores independientes que se pueden usar para instalar el SDK de .NET Core 3.1:
CPU de x64 (64 bits)

Instalación con un administrador de paquetes


Se puede instalar el SDK de .NET Core con muchos de los administradores de paquetes comunes de Linux.
Para obtener más información, vea Administrador de paquetes de Linux: instalación de .NET Core.
Su instalación con un administrador de paquetes solo se admite en la arquitectura x64. Si va a instalar el SDK
de .NET Core con otra arquitectura, como ARM, siga las instrucciones de Descarga e instalación de forma
manual a continuación. Para obtener más información sobre qué arquitecturas se admiten, consulte
Dependencias y requisitos de .NET Core.

Descarga e instalación de forma manual


Para extraer el SDK y hacer que los comandos de la CLI de .NET Core estén disponibles en el terminal, en
primer lugar descargue una versión binaria de .NET Core. Después, abra un terminal y ejecute los comandos
siguientes.

mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-3.1.100-linux-x64.tar.gz -C $HOME/dotnet


export DOTNET_ROOT=$HOME/dotnet
export PATH=$PATH:$HOME/dotnet
TIP
Los comandos export anteriores solo hacen que los comandos de la CLI de .NET Core estén disponibles para la
sesión de terminal en la que se ha ejecutado.
Puede editar el perfil del shell para agregar los comandos de forma permanente. Hay una serie de shells distintos
disponibles para Linux, y cada uno de ellos tiene un perfil diferente. Por ejemplo:
Shell de Bash: ~/.bash_profile, ~/.bashrc
Shell de Korn: ~/.kshrc or .profile
Shell de Z: ~/.zshrc or .zprofile
Edite el archivo de origen adecuado para el shell y agregue :$HOME/dotnet al final de la instrucción PATH existente.
Si no se incluye ninguna instrucción PATH , agregue una nueva línea con export PATH=$PATH:$HOME/dotnet .
Además, agregue export DOTNET_ROOT=$HOME/dotnet al final del archivo.

Instalación con Visual Studio


Si usa Visual Studio para desarrollar aplicaciones de .NET Core, en la tabla siguiente se describe la versión
mínima necesaria de Visual Studio, basada en la versión del SDK de .NET Core de destino.

VERSIÓN DEL SDK DE .NET CORE VERSIÓN DE VISUAL STUDIO

3.1 Visual Studio 2019, versión 16.4 o posterior.

3.0 Visual Studio 2019, versión 16.3 o posterior.

2.2 Visual Studio 2017, versión 15.9 o posterior.

2.1 Visual Studio 2017, versión 15.7 o posterior.

Si ya tiene Visual Studio instalado, puede comprobar la versión siguiendo los pasos que se detallan a
continuación.
1. Abra Visual Studio.
2. Seleccione Ayuda > Acerca de Microsoft Visual Studio.
3. Lea el número de versión en el cuadro de diálogo Acerca de.
Visual Studio puede instalar el SDK y el entorno de ejecución de .NET Core más recientes.
Descargue Visual Studio.
Selección de una carga de trabajo
Al instalar o modificar Visual Studio, seleccione una de las cargas de trabajo siguientes o más, en función del
tipo de aplicación que quiera compilar:
La carga de trabajo Desarrollo multiplataforma de .NET Core en la sección Otros conjuntos de
herramientas.
La carga de trabajo Desarrollo de ASP.NET y web en la sección Web y nube.
La carga de trabajo Desarrollo de Azure en la sección Web y nube.
La carga de trabajo Desarrollo de escritorio de .NET en la sección Móviles y de escritorio.
Instalación con Visual Studio para Mac
Visual Studio para Mac instala el SDK de .NET Core cuando se selecciona la carga de trabajo .NET Core.
Para empezar con el desarrollo en .NET Core en macOS, vea Instalación de Visual Studio 2019 para Mac.
Para obtener la versión más reciente, .NET Core 3.1, se debe usar la versión preliminar de Visual Studio para
Mac 8.4.

Instalación junto con Visual Studio Code


Visual Studio Code es un editor de código fuente ligero y eficaz que se ejecuta en el escritorio. Visual Studio
Code está disponible para Windows, macOS y Linux.
Aunque Visual Studio Code no viene con un instalador automatizado de .NET Core como Visual Studio,
agregar compatibilidad con .NET Core es sencillo.
1. Descargue e instale Visual Studio Code.
2. Descargue e instale el SDK de .NET Core.
3. Instale la extensión de C# desde el Marketplace de Visual Studio Code.

Instalación mediante la automatización de PowerShell


Los scripts de dotnet-install se usan para la automatización y las instalaciones que no son de administrador
del SDK. Se puede descargar el script desde la página de referencia del script dotnet-install.
El valor predeterminado del script es instalar la versión más reciente de soporte técnico a largo plazo (LTS ) ,
que actualmente es .NET Core 3.1. Para instalar la versión actual de .NET Core, ejecute el script con el
modificador siguiente.

dotnet-install.ps1 -Channel Current

Instalación mediante la automatización de Bash


Los scripts de dotnet-install se usan para la automatización y las instalaciones que no son de administrador
del SDK. Se puede descargar el script desde la página de referencia del script dotnet-install.
El valor predeterminado del script es instalar la versión más reciente de soporte técnico a largo plazo (LTS ) ,
que actualmente es .NET Core 3.1. Para instalar la versión actual de .NET Core, ejecute el script con el
modificador siguiente.

./dotnet-install.sh -c Current

Todas las descargas de .NET Core


Puede descargar e instalar .NET Core directamente con uno de los vínculos siguientes:
Descargas de .NET Core 3.1
Descargas de .NET Core 3.0
Descargas de .NET Core 2.2
Descargas de .NET Core 2.1

Docker
Los contenedores proporcionan una manera ligera de aislar la aplicación del resto del sistema host. Los
contenedores de la misma máquina comparten solo el kernel y usan los recursos proporcionados a la
aplicación.
.NET Core puede ejecutarse en un contenedor de Docker. Las imágenes oficiales de Docker en .NET Core se
publican en el registro de contenedor de Microsoft (MCR ) y se pueden encontrar en el repositorio de Docker
Hub para Microsoft .NET Core. Cada repositorio contiene imágenes para diferentes combinaciones de .NET
(SDK o Runtime) y del sistema operativo que puede usar.
Microsoft ofrece imágenes que se adaptan a escenarios específicos. Por ejemplo, el repositorio de ASP.NET
Core proporciona imágenes que se compilan para ejecutar aplicaciones de ASP.NET Core en producción.
Para obtener más información sobre el uso de .NET Core en un contenedor de Docker, vea Introducción a
.NET y Docker y Ejemplos.
Pasos siguientes
Tutorial: Tutorial Hola mundo.
Tutorial: Creación de una aplicación con Visual Studio Code.
Tutorial: Inclusión de una aplicación de .NET Core en un contenedor.
Tutorial: Introducción a macOS.
Tutorial: Creación de una aplicación con Visual Studio Code.
Tutorial: Inclusión de una aplicación de .NET Core en un contenedor.
Tutorial: Creación de una aplicación con Visual Studio Code.
Tutorial: Inclusión de una aplicación de .NET Core en un contenedor.
Instalación del entorno de ejecución de .NET Core
20/01/2020 • 7 minutes to read • Edit Online

En este artículo, obtendrá información sobre cómo descargar e instalar el entorno de ejecución de .NET Core.
El entorno de ejecución de .NET Core se usa para ejecutar aplicaciones creadas con .NET Core.

Instalación mediante un instalador


Windows tiene instaladores independientes que se pueden usar para instalar el entorno de ejecución de .NET
Core 3.1:
CPU de x64 (64 bits)
CPU de x86 (32 bits)

Instalación mediante un instalador


macOS tiene instaladores independientes que se pueden usar para instalar el entorno de ejecución de .NET
Core 3.1:
CPU de x64 (64 bits)

Instalación con un administrador de paquetes


Se puede instalar el entorno de ejecución de .NET Core con muchos de los administradores de paquetes
comunes de Linux. Para obtener más información, vea Administrador de paquetes de Linux: instalación de
.NET Core.
Su instalación con un administrador de paquetes solo se admite en la arquitectura x64. Si va a instalar el
runtime de .NET Core con otra arquitectura, como ARM, siga las instrucciones de la sección Descarga e
instalación de forma manual. Para obtener más información sobre qué arquitecturas se admiten, consulte
Dependencias y requisitos de .NET Core.

Descarga e instalación de forma manual


Para extraer el runtime y hacer que los comandos de la CLI de .NET Core estén disponibles en el terminal, en
primer lugar descargue una versión binaria de .NET Core. Después, abra un terminal y ejecute los comandos
siguientes.

mkdir -p $HOME/dotnet && tar zxf aspnetcore-runtime-3.1.0-linux-x64.tar.gz -C $HOME/dotnet


export DOTNET_ROOT=$HOME/dotnet
export PATH=$PATH:$HOME/dotnet
TIP
Los comandos export anteriores solo hacen que los comandos de la CLI de .NET Core estén disponibles para la sesión
de terminal en la que se ha ejecutado.
Puede editar el perfil del shell para agregar los comandos de forma permanente. Hay una serie de shells distintos
disponibles para Linux, y cada uno de ellos tiene un perfil diferente. Por ejemplo:
Shell de Bash: ~/.bash_profile, ~/.bashrc
Shell de Korn: ~/.kshrc or .profile
Shell de Z: ~/.zshrc or .zprofile
Edite el archivo de origen adecuado para el shell y agregue :$HOME/dotnet al final de la instrucción PATH existente. Si
no se incluye ninguna instrucción PATH , agregue una nueva línea con export PATH=$PATH:$HOME/dotnet .
Además, agregue export DOTNET_ROOT=$HOME/dotnet al final del archivo.

Instalación mediante la automatización de PowerShell


Los scripts de dotnet-install se usan para la automatización y las instalaciones que no son de administrador del
entorno de ejecución. Se puede descargar el script desde la página de referencia del script dotnet-install.
El valor predeterminado del script es instalar la versión más reciente de soporte técnico a largo plazo (LTS ) ,
que actualmente es .NET Core 3.1. Puede elegir una versión concreta especificando el modificador Channel .
Incluya el modificador Runtime para instalar un entorno de ejecución. De lo contrario, el script instala el SDK.

dotnet-install.ps1 -Channel 3.1 -Runtime aspnetcore

NOTE
El comando anterior instala el entorno de ejecución de ASP.NET Core para obtener la máxima compatibilidad. El entorno
de ejecución de ASP.NET Core también incluye el estándar de .NET Core.

Instalación mediante la automatización de Bash


Los scripts de dotnet-install se usan para la automatización y las instalaciones que no son de administrador del
entorno de ejecución. Se puede descargar el script desde la página de referencia del script dotnet-install.
El valor predeterminado del script es instalar la versión más reciente de soporte técnico a largo plazo (LTS ) ,
que actualmente es .NET Core 3.1. Puede elegir una versión concreta especificando el modificador current .
Incluya el modificador runtime para instalar un entorno de ejecución. De lo contrario, el script instala el SDK.

./dotnet-install.sh --channel 3.1 --runtime aspnetcore

NOTE
El comando anterior instala el entorno de ejecución de ASP.NET Core para obtener la máxima compatibilidad. El entorno
de ejecución de ASP.NET Core también incluye el estándar de .NET Core.

Todas las descargas de .NET Core


Puede descargar e instalar .NET Core directamente con uno de los vínculos siguientes:
Descargas de .NET Core 3.1
Descargas de .NET Core 3.0
Descargas de .NET Core 2.2
Descargas de .NET Core 2.1

Docker
Los contenedores proporcionan una manera ligera de aislar la aplicación del resto del sistema host. Los
contenedores de la misma máquina comparten solo el kernel y usan los recursos proporcionados a la
aplicación.
.NET Core puede ejecutarse en un contenedor de Docker. Las imágenes oficiales de Docker en .NET Core se
publican en el registro de contenedor de Microsoft (MCR ) y se pueden encontrar en el repositorio de Docker
Hub para Microsoft .NET Core. Cada repositorio contiene imágenes para diferentes combinaciones de .NET
(SDK o Runtime) y del sistema operativo que puede usar.
Microsoft ofrece imágenes que se adaptan a escenarios específicos. Por ejemplo, el repositorio de ASP.NET
Core proporciona imágenes que se compilan para ejecutar aplicaciones de ASP.NET Core en producción.
Para obtener más información sobre el uso de .NET Core en un contenedor de Docker, vea Introducción a
.NET y Docker y Ejemplos.

Pasos siguientes
Cómo comprobar que .NET Core ya está instalado.
Dependencias y requisitos de .NET Core
18/12/2019 • 13 minutes to read • Edit Online

En este artículo se detallan las arquitecturas de la CPU y de los sistemas operativos que son compatibles
con .NET Core.

Sistemas operativos admitidos


.NET Core 3.1
.NET Core 3.0
.NET Core 2.2
.NET Core 2.1
Las versiones siguientes de Windows son compatibles con .NET Core 3.1:

NOTE
Un símbolo + representa la versión mínima.

SO VERSIÓN ARQUITECTURAS

Cliente Windows 7 SP1 y posteriores, y 8.1 x64, x86

Cliente de Windows 10 Versión 1607 y posteriores x64, x86

Windows Server 2012 R2 y posteriores x64, x86

Nano Server Versión 1803 y posteriores x64, ARM32

Para obtener más información sobre los sistemas operativos compatibles con .NET Core 3.1, las
distribuciones y la directiva del ciclo de vida, vea Versiones de SO compatibles con .NET Core 3.1.
Windows 7, Vista, 8.1, Server 2008 R2
Se necesitan dependencias adicionales en caso de instalar el SDK o el entorno de ejecución de .NET en las
versiones siguientes de Windows:
Windows 7 SP1
Windows Vista SP2
Windows 8.1
Windows Server 2008 R2
Windows Server 2012 R2
Instale el software siguiente:
Microsoft Visual C++ 2015 Redistributable Update 3.
KB2533623
Los requisitos anteriores también son necesarios si se encuentra con uno de los errores siguientes:

El programa no se puede iniciar porque el archivo api-ms-win-crt-runtime-l1 -1 -0.dll falta en el equipo.


Intente volver a instalar el programa para corregir este problema.
-o-
La biblioteca hostfxr.dll se ha encontrado, pero no se ha podido cargar desde C:\
<path_to_app>\hostfxr.dll.

.NET Core 3.1


.NET Core 3.0
.NET Core 2.2
.NET Core 2.1
.NET Core 3.1 considera Linux como un único sistema operativo. Solo hay una única compilación de Linux
(por arquitectura de chip) para las distribuciones de Linux compatibles.
.NET Core 3.1 se admite en las siguientes versiones o distribuciones de Linux:

NOTE
Un símbolo + representa la versión mínima.

SO VERSIÓN ARQUITECTURAS

Red Hat Enterprise Linux 6, 7, 8 x64

CentOS 7 (o posterior) x64

Oracle Linux 7 (o posterior) x64

Fedora 29+ x64

Debian 9+ x64, ARM32, ARM64

Ubuntu 16.04+ x64, ARM32, ARM64

Linux Mint 18+ x64

openSUSE 15+ x64

SUSE Enterprise Linux (SLES) 12 SP2+ x64

Alpine Linux 3.10 y posteriores x64, ARM64

Para obtener más información sobre los sistemas operativos compatibles con .NET Core 3.1, las
distribuciones y la directiva del ciclo de vida, vea Versiones de SO compatibles con .NET Core 3.1.
Para obtener más información sobre cómo instalar .NET Core 3.1 en ARM64 (kernel 4.14 y posteriores),
vea Instalación de .NET Core 3.0 en Linux ARM64.

IMPORTANT
La compatibilidad con ARM64 requiere la versión 4.14 del kernel de Linux o una versión posterior. No todas las
distribuciones de Linux cumplen este requisito. Por ejemplo, Ubuntu 18.04 es compatible, pero Ubuntu 16.04, no.
Dependencias de distribución de Linux
En función de la distribución de Linux, es posible que tenga que instalar dependencias adicionales.

IMPORTANT
Los nombres y las versiones exactos pueden variar ligeramente en la distribución de Linux que prefiera.

Ubuntu
Las distribuciones de Ubuntu necesitan tener instaladas las bibliotecas siguientes:
liblttng-ust0
libcurl3 (para 14.x y 16.x)
libcurl4 (para 18.x)
libssl1.0.0
libkrb5-3
zlib1g
libicu52 (para 14.x)
libicu55 (para 16.x)
libicu57 (para 17.x)
libicu60 (para 18.x)
En el caso de las aplicaciones de .NET Core que utilizan el ensamblado System.Drawing.Common, también
se necesita la dependencia siguiente:
libgdiplus (versión 6.0.1 o posteriores)

WARNING
La mayoría de versiones de Ubuntu incluyen una versión anterior de libgdiplus. Puede instalar una versión reciente
de libgdiplus al agregar el repositorio Mono al sistema. Para más información, consulte https://www.mono-
project.com/download/stable/.

CentOS y Fedora
Las distribuciones de CentOS necesitan tener instaladas las siguientes bibliotecas:
lttng-ust
libcurl
openssl-libs
krb5-libs
libicu
zlib
Usuarios de Fedora: Si la versión de OpenSSL es la 1.1 o una posterior, es necesario instalar compat-
openssl10.
En el caso de .NET Core 2.0, también se necesitan las dependencias siguientes:
libunwind
libuuid
Para obtener más información sobre las dependencias, vea Aplicaciones de Linux independientes.
En el caso de las aplicaciones de .NET Core que utilizan el ensamblado System.Drawing.Common, también
se necesitará la dependencia siguiente:
libgdiplus (versión 6.0.1 o posteriores)

WARNING
La mayoría de versiones de CentOS incluyen una versión anterior de libgdiplus. Puede instalar una versión reciente
de libgdiplus al agregar el repositorio Mono al sistema. Para más información, consulte https://www.mono-
project.com/download/stable/.

.NET Core es compatible con las versiones siguientes de macOS:

NOTE
Un símbolo + representa la versión mínima.

VERSIÓN DE .NET CORE MACOS ARQUITECTURAS

3.1 High Sierra (10.13 y x64 Más información


posteriores)

3.0 High Sierra (10.13 y x64 Más información


posteriores)

2.2 Sierra (10.12 y posteriores) x64 Más información

2.1 Sierra (10.12 y posteriores) x64 Más información

libgdiplus
Las aplicaciones .NET Core que usan el ensamblado System.Drawing.Common requieren la instalación de
libgdiplus.
Una manera fácil de obtener libgdiplus es usar el administrador de paquetes Homebrew ("brew") para
macOS. Después de instalar brew, instale libgdiplus mediante la ejecución de los comandos siguientes en
un símbolo del sistema de Terminal (comando):

brew update
brew install mono-libgdiplus

Pasos siguientes
Para desarrollar y ejecutar aplicaciones, instale el SDK de .NET Core, que incluye el entorno de
ejecución.
Para ejecutar las aplicaciones que han creado otros usuarios, instale el entorno de ejecución de .NET
Core.
Cómo comprobar que .NET Core ya está instalado
12/01/2020 • 3 minutes to read • Edit Online

En este artículo se explica cómo comprobar las versiones del entorno de ejecución y el SDK de .NET Core que
están instaladas en el equipo. Es posible que .NET Core ya se haya instalado si tiene un entorno de desarrollo
integrado, como Visual Studio o Visual Studio para Mac.
Al instalar un SDK, se instala el entorno de ejecución correspondiente.
Si se produce un error en alguno de los comandos de este artículo, no tendrá instalado el entorno de ejecución o
el SDK. Para obtener más información, vea Descarga e instalación de .NET Core.

Comprobación de las versiones del SDK


Se pueden ver las versiones del SDK de .NET Core que están instaladas actualmente con un terminal. Abra un
terminal y ejecute el comando dotnet --list-sdks .

dotnet --list-sdks

2.1.500 [C:\program files\dotnet\sdk]


2.1.502 [C:\program files\dotnet\sdk]
2.1.504 [C:\program files\dotnet\sdk]
2.1.600 [C:\program files\dotnet\sdk]
2.1.602 [C:\program files\dotnet\sdk]
2.2.101 [C:\program files\dotnet\sdk]
3.0.100 [C:\program files\dotnet\sdk]
3.1.100 [C:\program files\dotnet\sdk]

dotnet --list-sdks

2.1.500 [/home/user/dotnet/sdk]
2.1.502 [/home/user/dotnet/sdk]
2.1.504 [/home/user/dotnet/sdk]
2.1.600 [/home/user/dotnet/sdk]
2.1.602 [/home/user/dotnet/sdk]
2.2.101 [/home/user/dotnet/sdk]
3.0.100 [/home/user/dotnet/sdk]
3.1.100 [/home/user/dotnet/sdk]

dotnet --list-sdks

2.1.500 [/usr/local/share/dotnet/sdk]
2.1.502 [/usr/local/share/dotnet/sdk]
2.1.504 [/usr/local/share/dotnet/sdk]
2.1.600 [/usr/local/share/dotnet/sdk]
2.1.602 [/usr/local/share/dotnet/sdk]
2.2.101 [/usr/local/share/dotnet/sdk]
3.0.100 [/usr/local/share/dotnet/sdk]
3.1.100 [/usr/local/share/dotnet/sdk]

Comprobación de las versiones del entorno de ejecución


Se pueden ver las versiones del entorno de ejecución de .NET Core que están instaladas actualmente con el
comando dotnet --list-runtimes .

dotnet --list-runtimes

Microsoft.AspNetCore.All 2.1.7 [c:\program files\dotnet\shared\Microsoft.AspNetCore.All]


Microsoft.AspNetCore.All 2.1.13 [c:\program files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [c:\program files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.3 [c:\program files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [c:\program files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [c:\program files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.7 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.3 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [c:\program files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.0 [c:\program files\dotnet\shared\Microsoft.WindowsDesktop.App]

dotnet --list-runtimes

Microsoft.AspNetCore.All 2.1.7 [/home/user/dotnet/shared/Microsoft.AspNetCore.All]


Microsoft.AspNetCore.All 2.1.13 [/home/user/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [/home/user/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.3 [/home/user/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [/home/user/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [/home/user/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.7 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.3 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [/home/user/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [/home/user/dotnet/shared/Microsoft.NETCore.App]
dotnet --list-runtimes

Microsoft.AspNetCore.All 2.1.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]


Microsoft.AspNetCore.All 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.13 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.7 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Más información
Se pueden ver las versiones del SDK y del entorno de ejecución con el comando dotnet --info . También
obtendrá otra información relacionada con el entorno, como la versión del sistema operativo y el identificador del
entorno de ejecución (RID ).

Pasos siguientes
Instalar el entorno de ejecución de .NET Core.
Instalar el SDK de .NET Core.
Administrador de paquetes de Ubuntu 19.04:
instalación de .NET Core
20/01/2020 • 5 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Ubuntu 19.04. Si
va a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

wget -q https://packages.microsoft.com/config/ubuntu/19.04/packages-microsoft-prod.deb -O packages-microsoft-


prod.deb
sudo dpkg -i packages-microsoft-prod.deb

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-sdk-3.1, vea la sección Solución de
problemas del administrador de paquetes.

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET
Core. En el terminal, ejecute los comandos siguientes.
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install aspnetcore-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete aspnetcore-runtime-3.1, vea la sección
Solución de problemas del administrador de paquetes.

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-runtime-3.1, vea la sección Solución
de problemas del administrador de paquetes.

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .

Solución de problemas del administrador de paquetes


Si recibe un mensaje de error similar a No se puede encontrar el paquete (el paquete .NET Core) , ejecute
los comandos siguientes.

sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb


sudo apt-get update
sudo apt-get install {the .NET Core package}

Si eso no funciona, puede ejecutar una instalación manual con los comandos siguientes.

sudo apt-get install -y gpg


wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/ubuntu/19.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install {the .NET Core package}
Administrador de paquetes de Ubuntu 18.04:
instalación de .NET Core
20/01/2020 • 5 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Ubuntu 18.04.
Si va a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core,
ya que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-


prod.deb
sudo dpkg -i packages-microsoft-prod.deb

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute los comandos siguientes.

sudo add-apt-repository universe


sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-sdk-3.1, vea la sección Solución de
problemas del administrador de paquetes.

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET
Core. En el terminal, ejecute los comandos siguientes.
sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install aspnetcore-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete aspnetcore-runtime-3.1, vea la sección
Solución de problemas del administrador de paquetes.

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute los comandos siguientes.

sudo add-apt-repository universe


sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-runtime-3.1, vea la sección Solución
de problemas del administrador de paquetes.

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .

Solución de problemas del administrador de paquetes


Si recibe un mensaje de error similar a No se puede encontrar el paquete (el paquete .NET Core) , ejecute
los comandos siguientes.

sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb


sudo apt-get update
sudo apt-get install {the .NET Core package}

Si eso no funciona, puede ejecutar una instalación manual con los comandos siguientes.

sudo apt-get install -y gpg


wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install {the .NET Core package}
Administrador de paquetes de Ubuntu 16.04:
instalación de .NET Core
20/01/2020 • 5 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Ubuntu 16.04.
Si va a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core,
ya que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb -O packages-microsoft-


prod.deb
sudo dpkg -i packages-microsoft-prod.deb

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-sdk-3.1, vea la sección Solución de
problemas del administrador de paquetes.

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET
Core. En el terminal, ejecute los comandos siguientes.
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install aspnetcore-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete aspnetcore-runtime-3.1, vea la sección
Solución de problemas del administrador de paquetes.

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1

IMPORTANT
Si recibe un mensaje de error similar a No se puede encontrar el paquete dotnet-runtime-3.1, vea la sección Solución
de problemas del administrador de paquetes.

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .

Solución de problemas del administrador de paquetes


Si recibe un mensaje de error similar a No se puede encontrar el paquete (el paquete .NET Core) , ejecute
los comandos siguientes.

sudo dpkg --purge packages-microsoft-prod && sudo dpkg -i packages-microsoft-prod.deb


sudo apt-get update
sudo apt-get install {the .NET Core package}

Si eso no funciona, puede ejecutar una instalación manual con los comandos siguientes.

sudo apt-get install -y gpg


wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/ubuntu/16.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install {the .NET Core package}
Administrador de paquetes de CentOS 7: instalación
de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en CentOS 7. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute el comando siguiente.

sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo yum install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET. En
el terminal, ejecute el comando siguiente.

sudo yum install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.

sudo yum install dotnet-runtime-3.1


Procedimiento para instalar otras versiones
Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de Debian 10: instalación
de .NET Core
20/01/2020 • 4 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Debian 10. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg


sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/debian/10/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET. En
el terminal, ejecute los comandos siguientes.
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de Debian 9: instalación
de .NET Core
20/01/2020 • 4 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Debian 9. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg


sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/debian/9/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET. En
el terminal, ejecute los comandos siguientes.
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute los comandos siguientes.

sudo apt-get update


sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-runtime-3.1

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de Fedora 30:
instalación de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Fedora 30. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc


sudo wget -q -O /etc/yum.repos.d/microsoft-prod.repo
https://packages.microsoft.com/config/fedora/30/prod.repo

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo dnf install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET. En
el terminal, ejecute el comando siguiente.

sudo dnf install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.
sudo dnf install dotnet-runtime-3.1

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de Fedora 29:
instalación de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en Fedora 29. Si
va a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc


sudo wget -q -O /etc/yum.repos.d/microsoft-prod.repo
https://packages.microsoft.com/config/fedora/29/prod.repo

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo dnf install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET.
En el terminal, ejecute el comando siguiente.

sudo dnf install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.
sudo dnf install dotnet-runtime-3.1

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de openSUSE 15:
instalación de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en openSUSE 15.
Si va a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core,
ya que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute los comandos siguientes.

sudo zypper install libicu


sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
wget -q https://packages.microsoft.com/config/opensuse/15/prod.repo
sudo mv prod.repo /etc/zypp/repos.d/microsoft-prod.repo
sudo chown root:root /etc/zypp/repos.d/microsoft-prod.repo

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo zypper install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET.
En el terminal, ejecute el comando siguiente.

sudo zypper install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.
sudo zypper install dotnet-runtime-3.1

Procedimiento para instalar otras versiones


Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de RHEL 8.1: instalación
de .NET Core
12/01/2020 • 2 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en RHEL 8.1. .NET
Core 3.1 todavía no está disponible para RHEL 8.1.

NOTE
RHEL 8.0 no incluye .NET Core 3.0. Use el comando yum upgrade para actualizar a RHEL 8.1.

Registro de la suscripción de Red Hat


Para instalar .NET Core desde Red Hat en RHEL, primero debe registrarse con el administrador de suscripciones
de Red Hat. Si esto no se ha realizado en el sistema, o si no tiene certeza de ello, vea la documentación del
producto de Red Hat para .NET Core.

Instalación del SDK de .NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el SDK de
.NET Core. En el terminal, ejecute los comandos siguientes.

dnf install dotnet-sdk-3.0


scl enable dotnet-sdk-3.0 bash

Instalación del entorno de ejecución de ASP.NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el entorno de
ejecución de ASP.NET Core. En el terminal, ejecute los comandos siguientes.

dnf install aspnetcore-runtime-3.0


scl enable aspnetcore-runtime-3.0 bash

Instalación del entorno de ejecución de .NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el entorno de
ejecución de .NET Core. En el terminal, ejecute los comandos siguientes.

sudo dnf install dotnet-runtime-3.0


scl enable dotnet-runtime-3.0 bash

Vea también
Uso de .NET Core 3.0 en Red Hat Enterprise Linux 8
Administrador de paquetes de RHEL 7: instalación
de .NET Core
12/01/2020 • 2 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en RHEL 7. .NET
Core 3.1 todavía no está disponible para RHEL 7.

Registro de la suscripción de Red Hat


Para instalar .NET Core desde Red Hat en RHEL, primero debe registrarse con el administrador de
suscripciones de Red Hat. Si esto no se ha realizado en el sistema, o si no tiene certeza de ello, vea la
documentación del producto de Red Hat para .NET Core.

Instalación del SDK de .NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el SDK de
.NET Core. Para habilitar el canal dotnet de RHEL 7 e instalarlo, ejecute los comandos siguientes en el terminal.

subscription-manager repos --enable=rhel-7-server-dotnet-rpms


yum install rh-dotnet30 -y
scl enable rh-dotnet30 bash

Instalación del entorno de ejecución de ASP.NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el entorno de
ejecución de ASP.NET Core. En el terminal, ejecute los comandos siguientes.

subscription-manager repos --enable=rhel-7-server-dotnet-rpms


yum install rh-dotnet30-aspnetcore-runtime-3.0 -y
scl enable rh-dotnet30 bash

Instalación del entorno de ejecución de .NET Core


Después de registrarse con el administrador de suscripciones, está a punto para instalar y habilitar el entorno de
ejecución de .NET Core. En el terminal, ejecute los comandos siguientes.

subscription-manager repos --enable=rhel-7-server-dotnet-rpms


yum install rh-dotnet30-dotnet-runtime-3.0 -y
scl enable rh-dotnet30 bash

Vea también
Uso de .NET Core 3.0 en Red Hat Enterprise Linux 7
Administrador de paquetes de SLES 15: instalación
de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en SLES 15. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute el comando siguiente.

sudo rpm -Uvh https://packages.microsoft.com/config/sles/15/packages-microsoft-prod.rpm

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo zypper install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET.
En el terminal, ejecute el comando siguiente.

sudo zypper install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.

sudo zypper install dotnet-runtime-3.1


Procedimiento para instalar otras versiones
Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Administrador de paquetes de SLES 12: instalación
de .NET Core
20/01/2020 • 3 minutes to read • Edit Online

_Las instalaciones del administrador de paquetes solo se admiten en la arquitectura _x64. Otras arquitecturas,
como ARM, deben instalar manualmente el SDK de .NET Core o instalar manualmente el entorno de ejecución
de .NET Core. Para obtener más información, vea Dependencias y requisitos de .NET Core .
En este artículo se describe cómo usar un administrador de paquetes para instalar .NET Core en SLES 12. Si va
a instalar el entorno de ejecución, le recomendamos que instale el entorno de ejecución de ASP.NET Core, ya
que incluye los de .NET Core y ASP.NET Core.

Registro de la clave y la fuente de Microsoft


Antes de instalar .NET, deberá realizar lo siguiente:
Registrar clave de Microsoft.
Registrar el repositorio del producto.
Instalar las dependencias necesarias.
Esto solo se debe hacer una vez por máquina.
Abra un terminal y ejecute el comando siguiente.

sudo rpm -Uvh https://packages.microsoft.com/config/sles/12/packages-microsoft-prod.rpm

Instalación del SDK de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el SDK de .NET Core. En el terminal,
ejecute el comando siguiente.

sudo zypper install dotnet-sdk-3.1

Instalación del entorno de ejecución de ASP.NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de ASP.NET.
En el terminal, ejecute el comando siguiente.

sudo zypper install aspnetcore-runtime-3.1

Instalación del entorno de ejecución de .NET Core


Actualice los productos disponibles para la instalación y, después, instale el entorno de ejecución de .NET Core.
En el terminal, ejecute el comando siguiente.

sudo zypper install dotnet-runtime-3.1


Procedimiento para instalar otras versiones
Los paquetes agregados a las fuentes del administrador de paquetes se denominan con un formato susceptible
de intrusiones: {product}-{type}-{version} .
product
Tipo de producto .NET que se va a instalar. Las opciones válidas son:
dotnet
aspnetcore
type
Elige el SDK o el entorno de ejecución. Las opciones válidas son:
sdk
runtime
version
Versión del SDK o del entorno de ejecución que se va a instalar. En este artículo se proporcionarán
siempre las instrucciones para la última versión admitida. Las opciones válidas son cualquier versión de
lanzamiento, como las siguientes:
3.0
2.2
2.1
Ejemplos
Instalación del SDK de .NET Core 2.2: dotnet-sdk-2.2
Instalación del entorno de ejecución de ASP.NET Core 3.0: aspnetcore-runtime-3.0
Instalación del entorno de ejecución de ASP.NET Core 2.1: dotnet-runtime-2.1

Solucionar problemas
Si la combinación de paquetes no funciona, no está disponible. Por ejemplo, no hay un SDK de ASP.NET Core;
los componentes del SDK se incluyen en el SDK de .NET Core. El valor aspnetcore-sdk-2.2 es no es correcto y
debe ser dotnet-sdk-2.2 .
Procedimiento para instalar archivos de IntelliSense
localizados para .NET Core
30/12/2019 • 7 minutes to read • Edit Online

IntelliSense es una característica que ayuda a completar código y que está disponible en diferentes entornos de
desarrollo integrado (IDE ), como Visual Studio. De manera predeterminada, al desarrollar proyectos de .NET Core,
el SDK solo incluye la versión en inglés de los archivos de IntelliSense. En este artículo, se explica lo siguiente:
Procedimiento para instalar la versión localizada de estos archivos.
Procedimiento para modificar la instalación de Visual Studio para usar otro idioma.

Requisitos previos
SDK de .NET Core 3.0 o una versión posterior.
Versión 16.3 de Visual Studio 2019 u otra posterior.

Descarga e instalación de los archivos de IntelliSense localizados


IMPORTANT
Para poder realizar este procedimiento, necesita tener permiso de administrador para copiar los archivos de IntelliSense en la
carpeta de instalación de .NET Core.

1. Vaya a la página Descarga de archivos de IntelliSense.


2. Descargue el archivo de IntelliSense en el idioma y la versión que prefiera.
3. Extraiga el contenido del archivo ZIP.
4. Vaya a la carpeta de instalación de .NET Core. De manera predeterminada, se encuentra en %Archivos de
programa%\dotnet\packs.
Elija para qué SDK quiere instalar el archivo de IntelliSense y vaya a la ruta de acceso
correspondiente. Tiene las siguientes opciones:

TIPO DE SDK RUTA DE ACCESO

.NET Core Microsoft.NETCore.App.Ref

Escritorio de Windows Microsoft.WindowsDesktop.App.Ref

.NET Standard NETStandard.Library.Ref

Vaya a la versión para la que quiera instalar el archivo de IntelliSense localizado. Por ejemplo, la 3.1.0.
Abra la carpeta ref.
Abra la carpeta del moniker. Por ejemplo, netcoreapp3.1.
Así pues, la ruta de acceso completa tendrá un aspecto similar al siguiente: C:\Archivos de
programa\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1.
5. Cree una subcarpeta en la carpeta del moniker que acaba de abrir. El nombre de la carpeta indicará el idioma
que quiere usar. En la siguiente tabla, se especifican las diferentes opciones:

LENGUAJE NOMBRE DE CARPETA

Portugués (brasileño) pt-br

Chino (simplificado) zh-hans

Chino (tradicional) zh-hant

Francés fr

Alemán de

Italiano it

Japonés ja

Coreano ko

Ruso ru

Español es

6. Copie en esta nueva carpeta los archivos .xml que ha extraído en el paso 3. Los archivos .xml se mostrarán
agrupados según las diferentes carpetas de SDK, de modo que debe copiarlos en la del SDK que haya
elegido en el paso 4.

Modificación del idioma de Visual Studio


Para que Visual Studio use otro idioma para IntelliSense, instale el paquete de idioma correspondiente. Esto se
puede realizar durante la instalación o después modificando la instalación de Visual Studio. Si ya tiene
Visual Studio configurado en el idioma que quiere, su instalación de IntelliSense está lista.
Instalación del paquete de idioma
Si no ha instalado el paquete de idioma deseado durante la configuración, actualice Visual Studio como se indica a
continuación para instalar el paquete de idioma:

IMPORTANT
Para instalar, actualizar o modificar Visual Studio, debe iniciar sesión con una cuenta que tenga permisos administrativos. Para
obtener más información, consulte Permisos de usuario y Visual Studio.

1. Busque el instalador de Visual Studio en su equipo.


Por ejemplo, en un equipo que ejecuta Windows 10, seleccione Iniciar y, después, desplácese hasta la letra I
donde lo verá como Instalador de Visual Studio.
NOTE
También pude encontrar el instalador de Visual Studio en la siguiente ubicación:
C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe

Es posible que tenga que actualizar el instalador antes de continuar. De ser así, siga las indicaciones.
2. En el instalador, busque la edición de Visual Studio a la que quiera agregar el paquete de idioma y, luego,
elija Modificar.

IMPORTANT
Si no ve el botón Modificar, pero sí el botón Actualizar, significa que necesita actualizar su versión de Visual Studio
para poder modificar su instalación. Cuando haya finalizado la actualización, aparecerá el botón Modificar.

3. En la pestaña Paquetes de idioma, seleccione o anule la selección de los idiomas que quiera instalar o
desinstalar.

4. Elija Modificar. Se inicia la actualización.


Modificación de la configuración de idioma en Visual Studio
Una vez que haya instalado los paquete de idioma deseados, modifique la configuración de Visual Studio para usar
otro idioma:
1. Abra Visual Studio.
2. En la ventana de inicio, elija Continuar sin código.
3. En el menú principal, seleccione Herramientas > Opciones. Se abrirá el cuadro de diálogo Opciones.
4. En la carpeta Entorno, elija Configuración internacional.
5. En la lista desplegable Idioma, seleccione el que quiera usar. Elija Aceptar.
6. Aparecerá un cuadro de diálogo en el que se le informará de que debe reiniciar Visual Studio para que se
apliquen los cambios. Elija Aceptar.
7. Reinicie Visual Studio.
Después de esto, IntelliSense deberá funcionar según lo esperado al abrir un proyecto de .NET Core que tenga
como destino la versión de los archivos de IntelliSense que acaba de instalar.

Vea también
IntelliSense en Visual Studio
Introducción a .NET Core
20/01/2020 • 3 minutes to read • Edit Online

En este artículo se proporciona información sobre cómo comenzar con .NET Core. .NET Core se puede instalar en
Windows, Linux y macOS. Puede programar en su editor de texto preferido y crear aplicaciones y bibliotecas
multiplataforma.
Si no está seguro de qué es .NET Core o cómo se relaciona con otras tecnologías .NET, comience con la
información general ¿Qué es .NET?. En resumen, .NET Core es una implementación multiplataforma de código
abierto de .NET.

Crear una aplicación


En primer lugar, descargue e instale el SDK de .NET Core en el equipo.
A continuación, abra un terminal como PowerShell, Símbolo del sistema o bash. Escriba los comandos dotnet
siguientes para crear y ejecutar una aplicación C#:

dotnet new console --output sample1


dotnet run --project sample1

Debería ver los siguientes resultados:

Hello World!

¡ Enhorabuena! Ha creado una sencilla aplicación .NET Core. También puede usar Visual Studio Code, Visual Studio
(solo Windows) o Visual Studio para Mac (solo macOS ), para crear una aplicación .NET Core.

Tutoriales
Para comenzar a desarrollar aplicaciones .NET Core, puede seguir estos tutoriales paso a paso:
Windows
Linux
macOS
Creación de su primera aplicación de consola con .NET Core en Visual Studio 2019
Compilación de una biblioteca de clases con .NET Standard en Visual Studio
Introducción a .NET Core mediante la CLI de .NET Core

Vea el vídeo de Channel 9 sobre cómo instalar y usar Visual


Studio Code y .NET Core.

Vea los vídeos .NET Core 101 en YouTube.

Vea el artículo Dependencias y requisitos de .NET Core para obtener una lista de las versiones de Windows
admitidas.
Introducción a C# y Visual Studio Code
12/01/2020 • 8 minutes to read • Edit Online

.NET Core ofrece una plataforma modular y rápida para crear aplicaciones que se ejecutan en Windows, Linux y
macOS. Use Visual Studio Code con la extensión de C# para disfrutar de una sólida experiencia de edición con
compatibilidad total para C# IntelliSense (completado de código inteligente) y para depuración.

Requisitos previos
1. Instale Visual Studio Code.
2. Instale el SDK de .NET Core.
3. Instale la extensión de C# para Visual Studio Code. Para más información sobre cómo instalar extensiones en
Visual Studio Code, vea el Marketplace de extensiones de VS Code.

Hello World
Se va a empezar con un programa "Hola mundo" sencillo basado en .NET Core:
1. Abrir un proyecto:
Abra Visual Studio Code.
Haga clic en el icono del explorador en el menú de la izquierda y después haga clic en Abrir
carpeta.
Seleccione Archivo > Abrir carpeta en el menú principal para abrir la carpeta en la que quiere
que esté el proyecto de C# y haga clic en Seleccionar carpeta. En el ejemplo se va a crear una
carpeta para el proyecto denominada HelloWorld.

2. Inicializar un proyecto de C#:


Abra el terminal integrado de Visual Studio Code al seleccionar Ver > Terminal integrado en el
menú principal.
En la ventana de terminal, escriba dotnet new console .
Este comando crea un archivo Program.cs en la carpeta con un programa "Hola mundo" sencillo ya
escrito, junto con un archivo de proyecto de C# denominado HelloWorld.csproj.

3. Resolver los recursos de compilación:


En .NET Core 1.x, escriba dotnet restore . Al ejecutar dotnet restore , se concede acceso a los
paquetes de .NET Core necesarios para compilar el proyecto.
NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan
implícitamente todos los comandos que requieren que se produzca una restauración, como dotnet new ,
dotnet build y dotnet run . Sigue siendo un comando válido en algunos escenarios donde tiene
sentido realizar una restauración explícita, como las compilaciones de integración continua en Azure
DevOps Services o en los sistemas de compilación que necesitan controlar explícitamente la hora a la que se
produce la restauración.

4. Ejecutar el programa "Hola mundo":


Escriba dotnet run .

También puede ver un breve tutorial de vídeo para obtener ayuda del programa de instalación en Windows,
macOS o Linux.

Depuración
1. Haga clic en el archivo Program.cs para abrirlo. La primera vez que se abre un archivo de C# en Visual
Studio Code, se carga OmniSharp en el editor.
2. Visual Studio Code debe pedirle que agregue los recursos que faltan para compilar y depurar la
aplicación. Seleccione Sí.

3. Para abrir la vista Depurar, haga clic en el icono de depuración en el menú de la izquierda.
4. Busque la flecha verde en la parte superior del panel. Asegúrese de que .NET Core Launch (consola)
está seleccionado en el menú desplegable que está junto a la flecha.

5. Agregue un punto de interrupción al proyecto; para ello, haga clic en el margen del editor, que es el
espacio a la izquierda de los números de línea del editor, junto a la línea 9 o mueva el cursor del texto de la
línea 9 en el editor y presione F9.
6. Para empezar a depurar, presione F5 o seleccione la flecha verde. El depurador detiene la ejecución del
programa cuando alcanza el punto de interrupción establecido en el paso anterior.
Mientras depura, puede ver las variables locales en el panel superior izquierdo o usar la consola de
depuración.
7. Seleccione la flecha azul de la parte superior para continuar la depuración o seleccione el cuadrado rojo
de la parte superior para detenerla.
TIP
Para obtener más información y sugerencias sobre solución de problemas en relación con la depuración de .NET Core con
OmniSharp en Visual Studio Code, vea Instructions for setting up the .NET Core debugger (Instrucciones para configurar el
depurador de .NET Core).

Agregar una clase


1. Para agregar una nueva clase, haga clic con el botón derecho en el Explorador de Visual Studio Code y
seleccione Nuevo archivo. Asé se agrega un nuevo archivo a la carpeta abierta en Visual Studio Code.
2. Asigne un nombre al archivo MyClass.cs. Debe guardarlo con una extensión .cs al final para que se
reconozca como archivo csharp.
3. Agregue el código siguiente para crear la primera clase. Asegúrese de incluir el espacio de nombres
correcto para poder hacer referencia a él desde el archivo Program.cs:

using System;

namespace HelloWorld
{
public class MyClass
{
public string ReturnMessage()
{
return "Happy coding!";
}
}
}

4. Llame a la nueva clase con el método principal de Program.cs agregando el código siguiente:

using System;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
var c1 = new MyClass();
Console.WriteLine($"Hello World! {c1.ReturnMessage()}");
}
}
}

5. Guarde los cambios y vuelva a ejecutar el programa. El nuevo mensaje debe aparecer con la cadena
anexada.

> dotnet run


Hello World! Happy coding!

Preguntas más frecuentes


Me faltan los recursos necesarios para compilar y depurar C# en Visual Studio Code. Mi depurador dice "Sin
configuración".
La extensión C# de Visual Studio Code puede generar recursos para compilar y depurar por usted. Visual Studio
Code le pedirá que genere estos recursos al abrir un proyecto de C#. Aunque no genere los recursos, podrá
seguir ejecutando este comando si abre la paleta de comandos (Vista > Paleta de comandos) y escribe
">.NET: Generar recursos para la compilación y depuración". Al seleccionar esta opción se generan los archivos
de configuración .vscode, launch.json y tasks.json que necesita.

Vea también
Setting up Visual Studio Code (Configuración de Visual Studio Code)
Debugging in Visual Studio Code (Depuración en Visual Studio Code)
Tutorial: Creación de una solución de .NET Core en
macOS con Visual Studio Code
20/01/2020 • 12 minutes to read • Edit Online

En este documento se proporcionan los pasos y el flujo de trabajo para crear una solución de .NET Core para
macOS. Obtendrá información sobre cómo crear proyectos, pruebas unitarias, usar las herramientas de
depuración e incorporar bibliotecas de terceros a través de NuGet.

NOTE
En este artículo se usa Visual Studio Code en macOS.

Requisitos previos
Instale el SDK de .NET Core. El SDK de .NET Core incluye la última versión de la plataforma de .NET Core y el
tiempo de ejecución.
Instale Visual Studio Code. Durante el transcurso de este artículo, también instalará las extensiones de Visual
Studio Code que mejoran la experiencia de desarrollo de .NET Core.
Instale la extensión de C# de Visual Studio Code; para ello, abra Visual Studio Code y presione Fn+F1 para abrir la
paleta de Visual Studio Code. Escriba ext install para ver la lista de extensiones. Seleccione la extensión de C#.
Reinicie Visual Studio Code para activar la extensión. Para obtener más información, vea la documentación de la
extensión de C# enVisual Studio Code.

Primeros pasos
En este tutorial, creará tres proyectos: un proyecto de biblioteca, pruebas para ese proyecto de biblioteca y una
aplicación de consola que usa la biblioteca. Puede ver o descargar el origen de este artículo en el repositorio
dotnet/samples de GitHub. Para obtener instrucciones de descarga, vea Ejemplos y tutoriales.
Inicie Visual Studio Code. Presione Ctrl+` (el carácter de comilla inversa o tilde aguda) o seleccione Ver >
Terminal desde el menú para abrir un terminal insertado en Visual Studio Code. Todavía puede abrir un shell
externo con el comando Abrir en símbolo del sistema del Explorador (Abrir en terminal en Mac o Linux) si
prefiere trabajar fuera de Visual Studio Code.
Comience creando un archivo de solución, que actúa como un contenedor para uno o más proyectos de .NET
Core. En el terminal, ejecute el comando dotnet new para crear una solución golden.sln dentro de una nueva
carpeta denominada golden:

dotnet new sln -o golden

Navegue a la nueva carpeta golden y ejecute el siguiente comando para crear un proyecto de biblioteca, que
produce dos archivos,library.csproj y Class1.cs, en la carpeta library:

dotnet new classlib -o library

Ejecute el comando dotnet sln para agregar el proyecto library.csproj recién creado a la solución:
dotnet sln add library/library.csproj

El archivo library.csproj contiene la información siguiente:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

</Project>

Nuestros métodos de biblioteca serializan y deserializan objetos en formato JSON. Para admitir la serialización y
deserialización JSON, agregue una referencia al paquete NuGet Newtonsoft.Json . El comando dotnet add agrega
elementos nuevos a un proyecto. Para agregar una referencia a un paquete NuGet, use el comando
dotnet add package y especifique el nombre del paquete:

dotnet add library package Newtonsoft.Json

Esto agrega Newtonsoft.Json y sus dependencias al proyecto de biblioteca. De manera alternativa, edite
manualmente el archivo library.csproj y agregue el nodo siguiente:

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

Ejecute dotnet restore (vea la nota), lo que restaura las dependencias y crea una carpeta obj dentro de library con
tres archivos, incluido un archivo project.assets.json:

dotnet restore

En la carpeta library, cambie el nombre del archivo Class1.cs a Thing.cs. Reemplace el código por el siguiente:

using static Newtonsoft.Json.JsonConvert;

namespace Library
{
public class Thing
{
public int Get(int left, int right) =>
DeserializeObject<int>($"{left + right}");
}
}

La clase Thing contiene un método público, Get , que devuelve la suma de dos números pero lo hace
convirtiendo la suma en una cadena y, después, deserializándola en un entero. Esto usa varias características de C#
recientes, como las directivas using static , los miembros con forma de expresión y la interpolación de cadenas.
Compile la biblioteca con el comando dotnet build . Esto crea un archivo library.dll en
golden/library/bin/Debug/netstandard1.4:

dotnet build
Crear el proyecto de prueba
Cree un proyecto de prueba para la biblioteca. Desde la carpeta golden, cree un nuevo proyecto de prueba:

dotnet new xunit -o test-library

Agregue el proyecto de prueba a la solución:

dotnet sln add test-library/test-library.csproj

Agregue una referencia del proyecto a la biblioteca que ha creado en la sección anterior, de manera que el
compilador pueda buscar y usar el proyecto de biblioteca. Use el comando dotnet add reference :

dotnet add test-library/test-library.csproj reference library/library.csproj

De manera alternativa, edite manualmente el archivo test-library.csproj y agregue el nodo siguiente:

<ItemGroup>
<ProjectReference Include="..\library\library.csproj" />
</ItemGroup>

Ahora que se han configurado correctamente las dependencias, cree las pruebas para la biblioteca. Abra
UnitTest1.cs y reemplace el contenido por el código siguiente:

using Library;
using Xunit;

namespace TestApp
{
public class LibraryTests
{
[Fact]
public void TestThing() {
Assert.NotEqual(42, new Thing().Get(19, 23));
}
}
}

Tenga en cuenta que afirma que el valor 42 no es igual a 19+23 (o 42) cuando se crea la prueba unitaria por
primera vez ( Assert.NotEqual ), lo que producirá un error. Un paso importante en la creación de las pruebas
unitarias es crear la prueba para que produzca un error la primera vez para confirmar su lógica.
Desde la carpeta golden, ejecute los comandos siguientes:

dotnet restore
dotnet test test-library/test-library.csproj

Estos comandos buscarán de manera recursiva todos los proyectos para restaurar dependencias, compilarlos y
activar el ejecutor de pruebas xUnit para ejecutar las pruebas. Se produce un error en la prueba, como se esperaba.
Edite el archivo UnitTest1.cs y cambie la aserción de Assert.NotEqual a Assert.Equal . Ejecute el comando
siguiente desde la carpeta golden para volver a ejecutar la prueba, que se pasa esta vez:
dotnet test test-library/test-library.csproj

Crear la aplicación de consola


La aplicación de consola que crea con los pasos siguientes toma una dependencia del proyecto de biblioteca que
ha creado anteriormente y llama a su método de biblioteca cuando se ejecuta. Con este patrón de desarrollo, ve
cómo crear bibliotecas reutilizables en varios proyectos.
Cree una aplicación de consola nueva desde la carpeta golden:

dotnet new console -o app

Agregue el proyecto de la aplicación de consola a la solución:

dotnet sln add app/app.csproj

Cree la dependencia en la biblioteca ejecutando el comando dotnet add reference :

dotnet add app/app.csproj reference library/library.csproj

Ejecute dotnet restore (vea la nota) para restaurar las dependencias de los tres proyectos en la solución. Abra
Program.cs y reemplace el contenido del método Main por la siguiente línea:

WriteLine($"The answer is {new Thing().Get(19, 23)}");

Agregue dos directivas using en la parte superior del archivo Program.cs:

using static System.Console;


using Library;

Ejecute el siguiente comando dotnet run para ejecutar el ejecutable, donde la opción -p en dotnet run
especifica el proyecto para la aplicación principal. La aplicación genera la cadena "La respuesta es 42".

dotnet run -p app/app.csproj

Depurar la aplicación
Establezca un punto de interrupción en la instrucción WriteLine del método Main . Haga esto presionando la tecla
Fn+F9 cuando el cursor se encuentre encima de la línea WriteLine o haciendo clic con el mouse en el margen
izquierdo de la línea donde quiera establecer el punto de interrupción. Aparecerá un círculo rojo en el margen
junto a la línea de código. Cuando se alcance el punto de interrupción, la ejecución de código se detendrá antes de
que se ejecute la línea del punto de interrupción.
Abra la pestaña del depurador; para ello, seleccione el icono Depurar en la barra de herramientas de Visual Studio
Code, seleccione Ver > Depurar desde la barra de menús o con el método abreviado de teclado
Comando+MAYÚS+D:
Presione el botón Reproducir para iniciar la aplicación en el depurador. En este proyecto ha creado un proyecto de
prueba y una aplicación. El depurador pregunta qué proyecto desea iniciar. Seleccione el proyecto "aplicación". La
aplicación comienza la ejecución y se ejecuta hasta el punto de interrupción, donde se detiene. Recorra paso a paso
el método Get y asegúrese de que hayan pasado los argumentos correctos. Confirme que la respuesta es 42.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Tutorial: Creación de su primera aplicación de
consola con .NET Core en Visual Studio 2019
20/01/2020 • 9 minutes to read • Edit Online

En este artículo se proporciona una introducción paso a paso para crear y ejecutar una aplicación de consola
Hola mundo con .NET Core en Visual Studio 2019. Tradicionalmente, se usa una aplicación Hola mundo para
introducir a los principiantes en un nuevo lenguaje de programación. En este programa simplemente muestra la
frase "Hola mundo" en la pantalla.

Requisitos previos
Visual Studio 2019, versión 16.4 o posterior con la carga de trabajo Desarrollo multiplataforma de
.NET Core instalada El SDK de .NET Core 3.1 se instala automáticamente al seleccionar esta carga de
trabajo.
Para más información, consulte la sección Instalación con Visual Studio del artículo Instalación del SDK de .NET
Core.

Creación de la aplicación
Las instrucciones siguientes crean una sencilla aplicación de consola de Hola mundo:
C#
Visual Basic
1. Abra Visual Studio 2019.
2. Cree un nuevo proyecto de aplicación de consola de .Net Core en C# denominado "HelloWorld".
a. En la ventana de inicio, elija Crear un proyecto nuevo.
b. En la página Crear un proyecto, escriba consola en el cuadro de búsqueda. Después, elija C# en
la lista de lenguajes y, luego, Todas las plataformas en la lista de plataformas. Elija la plantilla
Aplicación de consola (.NET Core) y haga clic en Siguiente.

TIP
Si no ve las plantillas de .NET Core, es probable que falte la carga de trabajo necesaria instalada. En el
mensaje ¿No encuentra lo que busca? , elija el vínculo Instalar más herramientas y características. Se
abre el Instalador de Visual Studio. Asegúrese de que tiene instalada la carga de trabajo Desarrollo
multiplataforma de .NET Core.

c. En la página Configurar el nuevo proyecto, escriba HelloWorld en el cuadro Nombre del


proyecto. Luego, elija Crear.
La plantilla de aplicación de consola de C# para .NET Core define automáticamente una clase, Program ,
con un único método, Main , que adopta una matriz String como argumento. Main es el punto de entrada
de la aplicación, el método que se llama automáticamente mediante el tiempo de ejecución cuando inicia
la aplicación. Los argumentos de línea de comandos proporcionados cuando se inicia la aplicación están
disponibles en la matriz args.

La plantilla crea una aplicación "Hola mundo" sencilla. Llama al método Console.WriteLine(String) para mostrar
la cadena literal "Hola mundo" en la ventana de la consola.

Ejecutar la aplicación
1. Para ejecutar el programa, elija HelloWorld en la barra de herramientas o presione F5.
Se abre la ventana de la consola con el texto "Hello World" impreso en la pantalla y parte de la
información de depuración de Visual Studio.

2. Presione cualquier tecla para cerrar la ventana de consola.

Mejora de la aplicación
Mejore su aplicación para pedir su nombre al usuario y mostrarlo junto con la fecha y la hora. Las instrucciones
siguientes modifican y ejecutan de nuevo la aplicación:
C#
Visual Basic
1. Reemplace el contenido del método Main , que actualmente es solo la línea que llama a
Console.WriteLine , con el código siguiente:

Console.WriteLine("\nWhat is your name? ");


var name = Console.ReadLine();
var date = DateTime.Now;
Console.WriteLine($"\nHello, {name}, on {date:d} at {date:t}!");
Console.Write("\nPress any key to exit...");
Console.ReadKey(true);

Este código muestra "What is your name?" en la ventana de la consola y espera a que el usuario escriba
una cadena seguida de la tecla Entrar. Almacena esta cadena en una variable denominada name . También
recupera el valor de la propiedad DateTime.Now, que contiene la hora local actual, y lo asigna a una
variable denominada date . Por último, usa una cadena interpolada para mostrar estos valores en la
ventana de la consola.
2. Compile el programa; para ello, seleccione Generar > Compilar solución.
3. Para ejecutar el programa, elija HelloWorld en la barra de herramientas o presione F5.
4. Responda a la solicitud escribiendo un nombre y presionando la tecla Entrar.
5. Presione cualquier tecla para cerrar la ventana de consola.

Pasos siguientes
En este artículo, ha creado y ejecutado su primera aplicación de .NET Core. En el paso siguiente, va a depurar la
aplicación.
Depuración de una aplicación "Hola mundo" con .NET Core en Visual Studio
Depuración de la aplicación Hola mundo de .NET
Core en C# o Visual Basic con Visual Studio
20/01/2020 • 24 minutes to read • Edit Online

Hasta ahora, ha seguido los pasos descritos en Creación de su primera aplicación de consola con .NET Core en
Visual Studio 2019 para crear y ejecutar una aplicación de consola sencilla. Cuando haya escrito y compilado la
aplicación, puede comenzar a probarla. Visual Studio incluye un conjunto completo de herramientas de
depuración que puede usar para solucionar problemas de la aplicación.

Depuración de la configuración de compilación


El modo de depuración y versión son dos de las configuraciones de compilación predeterminadas de Visual
Studio. La configuración de compilación actual se muestra en la barra de herramientas. En la siguiente imagen de
la barra de herramientas se muestra que Visual Studio está configurado para compilar la versión de depuración
de la aplicación:

Empiece por ejecutar la versión de depuración de la aplicación. La configuración de compilación de depuración


desactiva la mayoría de las optimizaciones del compilador y proporciona información más completa durante el
proceso de compilación.

Establecer un punto de interrupción


Ejecute su programa y pruebe algunas características de depuración:
C#
Visual Basic
1. Establezca un punto de interrupción en la línea que dice
Console.WriteLine($"\nHello, {name}, on {date:d} at {date:t}!"); ; para ello, haga clic en el margen
izquierdo de la ventana de código de esa línea. También puede establecer un punto de interrupción
colocando el símbolo de intercalación en la línea de código y presionando después F9 o seleccionando
Depurar > Alternar punto de interrupción en la barra de menús.
Un punto de interrupción interrumpe temporalmente la ejecución de la aplicación antes de que se ejecute
la línea con el punto de interrupción.
Como se muestra en la siguiente imagen, para indicar la línea en la que se establece el punto de
interrupción, Visual Studio lo resalta y muestra un círculo rojo en el margen izquierdo.
2. Ejecute el programa en el modo de depuración seleccionando el botón HelloWorld con la flecha verde en
la barra de herramientas, presionando F5 o seleccionando Depurar > Iniciar depuración.
3. Cuando el sistema le pida un nombre, escriba una cadena en la ventana de consola y luego presione
Entrar.
4. La ejecución del programa se detiene cuando llega al punto de interrupción y antes de que se ejecute el
método Console.WriteLine . La ventana Variables locales muestra los valores de las variables definidas en
el método que se ejecuta actualmente.

5. La ventana Inmediato le permite interactuar con la aplicación que está depurando. Puede cambiar el valor
de las variables de forma interactiva para ver cómo afecta esto al programa.
a. Si la ventana Inmediato no está visible, muéstrela; para ello, elija Depurar > Ventanas >
Inmediato.
b. Escriba name = "Gracie" en la ventana Inmediato y presione la tecla Entrar.
c. Escriba date = DateTime.Parse("11/16/2019 5:25 PM") en la ventana Inmediato y presione la tecla
Entrar.
La ventana Inmediato muestra el valor de la variable de cadena y las propiedades del valor DateTime.
Además, los valores de las variables se actualizan en la ventana Variables locales.

6. Seleccione el botón Continuar en la barra de herramientas para continuar con la ejecución del programa,
o seleccione Depurar > Continuar. Los valores mostrados en la ventana de la consola corresponden a los
cambios realizados en la ventana Inmediato.

7. Presione cualquier tecla para salir de la aplicación y detenga la depuración.


Establecimiento de un punto de interrupción condicional
Su programa muestra la cadena que escribe el usuario. ¿Qué sucede si el usuario no escribe nada? Puede probar
esto con una característica de depuración útil que se denomina punto de interrupción condicional, que interrumpe
la ejecución del programa cuando se cumplen una o más condiciones.
Para establecer un punto de interrupción condicional y probar lo que sucede cuando el usuario no especifica una
cadena, haga lo siguiente:
C#
Visual Basic
1. Haga clic con el botón derecho en el punto rojo que representa al punto de interrupción. En el menú
contextual, seleccione Condiciones para abrir el cuadro diálogo Configuración del punto de
interrupción. Active la casilla Condiciones si aún no está seleccionada.

2. Para la Expresión condicional, reemplace "por ejemplo, x == 5" por lo siguiente:

String.IsNullOrEmpty(name)

Se está probando una condición de código, en la que la llamada al método String.IsNullOrEmpty(name) es


true porque name no tiene asignado un valor o porque su valor es una cadena vacía (""). En lugar de una
expresión condicional, también puede especificar un número de llamadas, que es lo que interrumpe la
ejecución antes de que una instrucción se ejecute un número especificado de veces; o una condición de
filtro, que es lo que interrumpe la ejecución del programa en función de atributos como un identificador de
subproceso, nombre de proceso o nombre de subproceso.
3. Seleccione Cerrar para cerrar el cuadro de diálogo.
4. Inicie el programa con la depuración presionando F5.
5. En la ventana de consola, cuando se le pida que escriba su nombre, presione la tecla Entrar.
6. Como la condición que especificó ( name es null o String.Empty) se ha cumplido, la ejecución del
programa se detiene cuando se alcanza el punto de interrupción y antes de que se ejecute el método
Console.WriteLine .

7. Seleccione la ventana Variables locales, que muestra los valores de las variables que son locales para el
método que se ejecuta actualmente. En este caso, Main es el método que se está ejecutando actualmente.
Observe que el valor de la variable name es "" o String.Empty.
8. Confirme que el valor es una cadena vacía escribiendo la siguiente instrucción en la ventana Inmediato y
presionando Entrar. El resultado es true .

? name == String.Empty

9. Seleccione el botón Continuar en la barra de herramientas para continuar la ejecución del programa.
10. Presione cualquier tecla para cerrar la ventana de consola y detener la depuración.
11. Para borrar el punto de interrupción, haga clic en el punto en el margen izquierdo de la ventana de código,
o seleccione Depurar > Alternar punto de interrupción mientras la línea de código está seleccionada.

Ejecución paso a paso de un programa


Visual Studio también le permite recorrer línea a línea un programa y supervisar su ejecución. Normalmente,
establecería un punto de interrupción y usaría esta característica para seguir el flujo del programa mediante una
pequeña parte de su código de programa. Como nuestro programa es pequeño, puede ejecutar paso a paso el
programa entero:
C#
Visual Basic
1. En la barra de menús, seleccione Depurar > Paso a paso por instrucciones o presione la tecla F11.
Visual Studio resalta y muestra una flecha junto a la siguiente línea de ejecución.
En este punto, la ventana Variables locales muestra que su programa ha definido solo una variable, args .
Dado que no ha pasado ningún argumento de línea de comandos al programa, su valor es una matriz de
cadena vacía. Además, Visual Studio ha abierto una ventana de consola en blanco.
2. Seleccione Depurar > Paso a paso por instrucciones o presione F11. Visual Studio ahora resalta la
siguiente línea de ejecución. Como se muestra en la imagen, el código tarda en ejecutarse menos de una
milésima de segundo entre la última instrucción y esta. args sigue siendo la única variable declarada y la
ventana de consola sigue estando en blanco.

3. Seleccione Depurar > Paso a paso por instrucciones o presione F11. Visual Studio resalta la instrucción
que incluye la asignación de variables name . La ventana Variables locales muestra que name es null , y
la ventana de consola muestra la cadena "What is your name?".
4. Para responder a la solicitud, escriba una cadena en la ventana de consola y presione Entrar. La consola no
responde y la cadena que especificó no se muestra en la ventana de la consola, pero el método
Console.ReadLine capturará en cambio la entrada.
5. Seleccione Depurar > Paso a paso por instrucciones o presione F11. Visual Studio resalta la instrucción
que incluye la asignación de variables date . La ventana Variables locales muestra el valor devuelto por la
llamada al método Console.ReadLine. La ventana de la consola también muestra la cadena que escribió en
la solicitud.
6. Seleccione Depurar > Paso a paso por instrucciones o presione F11. La ventana Variables locales
muestra el valor de la variable date tras la asignación desde la propiedad DateTime.Now. La ventana de
consola permanece sin cambios.
7. Seleccione Depurar > Paso a paso por instrucciones o presione F11. Visual Studio llama al método
Console.WriteLine(String, Object, Object). La ventana de la consola muestra la cadena con formato.
8. Seleccione Depurar > Paso a paso para salir o presione Mayús+F11. Esta acción detiene la ejecución
paso a paso. La ventana de la consola muestra un mensaje y espera a que presione una tecla.
9. Presione cualquier tecla para cerrar la ventana de consola y detener la depuración.

Creación de una versión de lanzamiento


Una vez que ha probado la versión de depuración de la aplicación, también debe compilar y probar la versión de
lanzamiento. La versión de lanzamiento incorpora optimizaciones del compilador que en ocasiones afectan
negativamente al comportamiento de una aplicación. Por ejemplo, las optimizaciones del compilador que están
diseñadas para mejorar el rendimiento pueden crear condiciones de carrera en aplicaciones multiproceso.
Para compilar y probar la versión de lanzamiento de la aplicación de la consola, cambie la configuración de
compilación en la barra de herramientas de Depurar a Versión.
Cuando presiona F5 o elije Compilar solución en el menú Compilar, Visual Studio compila la versión de
lanzamiento de la aplicación. Puede probarla como hizo con la versión de depuración.

Pasos siguientes
Cuando haya depurado la aplicación, el siguiente paso es publicar una versión implementable de la misma. Para
más información sobre cómo hacerlo, vea Publicación de la aplicación Hola mundo de .NET Core con Visual
Studio 2017.
Publicación de la aplicación Hola mundo de .NET
Core con Visual Studio
20/01/2020 • 4 minutes to read • Edit Online

En Creación de una aplicación Hola mundo con .NET Core en Visual Studio, ha compilado una aplicación de
consola Hola mundo. En Depuración de la aplicación Hola mundo con Visual Studio, la ha probado con el
depurador de Visual Studio. Ahora que está seguro de que funciona como se esperaba, puede publicarla para que
otros usuarios puedan ejecutarla. La publicación crea el conjunto de archivos que se necesitan para ejecutar la
aplicación. Para implementar los archivos, cópielos en el equipo de destino.

Publicar la aplicación
1. Asegúrese de que Visual Studio esté compilando la versión de lanzamiento de la aplicación. Si es necesario,
cambie la configuración de compilación en la barra de herramientas de Depurar a Versión.

2. Haga clic con el botón derecho en el proyecto HelloWorld (no en la solución HelloWorld) y seleccione
Publicar en el menú. (también puede seleccionar Publicar Hola mundo en el menú principal Compilar).

3. En la página Elegir un destino de publicación, seleccione Carpeta y, a continuación, seleccione Crear


perfil.
4. En la página Publicar, seleccione Publicar.

Inspección de los archivos


El proceso de publicación crea una implementación dependiente del marco, que es un tipo de implementación
donde la aplicación publicada se ejecuta en cualquier plataforma compatible con .NET Core con .NET Core
instalado en el sistema. Los usuarios pueden ejecutar la aplicación publicada haciendo doble clic en el archivo
ejecutable o emitiendo el comando dotnet HelloWorld.dll desde un símbolo del sistema.
En los pasos siguientes, examinará los archivos creados por el proceso de publicación.
1. Abra un símbolo del sistema.
Una forma de abrir un símbolo del sistema es escribir Símbolo del sistema (o cmd) en el cuadro de
búsqueda de la barra de tareas de Windows. Seleccione la aplicación de escritorio Símbolo del sistema o
presione Entrar si ya está seleccionado en los resultados de búsqueda.
2. Vaya a la aplicación publicada en el subdirectorio bin\Release\netcoreapp3.1\publish del directorio del
proyecto de la aplicación.

Como se muestra en la imagen, el resultado publicado incluye los siguientes archivos:


HelloWorld.deps.json
Este es el archivo de dependencias en tiempo de ejecución de la aplicación. Define los componentes
y las bibliotecas de .NET Core (incluida la biblioteca de vínculos dinámicos que contiene la
aplicación) necesarios para ejecutar la aplicación. Para obtener más información, consulte Archivos
de configuración en tiempo de ejecución.
HelloWorld.dll
Esta es la versión de implementación dependiente del marco de la aplicación. Para ejecutar esta
biblioteca de vínculos dinámicos, escriba dotnet HelloWorld.dll en un símbolo del sistema.
HelloWorld.exe
Esta es la versión del ejecutable dependiente del marco de la aplicación. Para ejecutarlo, escriba
HelloWorld.exe en un símbolo del sistema.

HelloWorld.pdb (opcional para la implementación)


Este es el archivo de símbolos de depuración. No necesita implementar este archivo junto con su
aplicación, aunque se debe guardar en caso de que necesite depurar la versión publicada de la
aplicación.
HelloWorld.runtimeconfig.json
Este es el archivo de configuración en tiempo de ejecución de la aplicación. Identifica la versión de
.NET Core en la que se ha compilado la aplicación para ejecutarse. Para obtener más información,
consulte Archivos de configuración en tiempo de ejecución.

Recursos adicionales
Implementación de aplicaciones .NET Core
Creación de una de .NET Standard en Visual Studio
20/01/2020 • 8 minutes to read • Edit Online

Una biblioteca de clases define los tipos y los métodos que se llaman desde una aplicación. Una biblioteca de
clases que tiene como destino .NET Standard 2.0, lo que permite que cualquier implementación .NET que admita
esa versión de .NET Standard pueda llamar a su biblioteca. Cuando termine la biblioteca de clases, puede decidir
si quiere distribuirla como un componente de terceros o si la quiere incluir como un componente empaquetado
con una o varias aplicaciones.

NOTE
Para ver una lista de las versiones de .NET Standard y las plataformas que admiten, vea .NET Standard.

En este tema, se creará una sencilla biblioteca de utilidades que contiene un único método de control de cadenas.
Se implementará como un método de extensión de modo que se pueda llamar como si fuera un miembro de la
clase String.

Creación de una solución de Visual Studio


Empiece por crear una solución en blanco para colocar el proyecto de biblioteca de clases en ella. Una solución de
Visual Studio sirve como contenedor de uno o varios proyectos. Agregará proyectos adicionales relacionados a la
misma solución si continúa con la serie de tutoriales.
Para crear la solución en blanco:
1. Abra Visual Studio.
2. En la ventana de inicio, elija Crear un proyecto nuevo.
3. En el cuadro de búsqueda de la página Crear un nuevo proyecto, escriba solución. Elija la plantilla
Solución en blanco y luego seleccione Siguiente.
4. En la página Configure el nuevo proyecto, escriba ClassLibraryProjects en el cuadro Nombre del
proyecto. Luego, elija Crear.

TIP
También puede omitir este paso y dejar que Visual Studio cree la solución automáticamente al crear el proyecto en el paso
siguiente. Busque las opciones de la solución en la página Configure el nuevo proyecto.

Crear un proyecto de biblioteca de clases


C#
Visual Basic
1. Agregue un nuevo proyecto de biblioteca de clases de .NET Standard para C# denominado "StringLibrary"
a la solución.
a. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione
Agregar > Nuevo proyecto.
b. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba biblioteca. Elija C#
en la lista de lenguajes y, luego, Todas las plataformas en la lista de plataformas. Elija la plantilla
Biblioteca de clases (.NET Standard) y, luego, siguiente.
c. En la página Configure el nuevo proyecto, escriba StringLibrary en el cuadro Nombre del
proyecto. Luego, elija Crear.
2. Asegúrese de que la biblioteca tiene como destino la versión correcta de .NET Standard. Haga clic con el
botón derecho en el proyecto de biblioteca en el Explorador de soluciones y, luego, seleccione
Propiedades. El cuadro de texto Plataforma de destino muestra que el proyecto tiene como destino
.NET Standard 2.0.
3. Reemplace el código de la ventana de código por el código siguiente y guarde el archivo:

using System;

namespace UtilityLibraries
{
public static class StringLibrary
{
public static bool StartsWithUpper(this String str)
{
if (String.IsNullOrWhiteSpace(str))
return false;

Char ch = str[0];
return Char.IsUpper(ch);
}
}
}

La biblioteca de clases, UtilityLibraries.StringLibrary , contiene un método denominado


StartsWithUpper . Este método devuelve un valor Boolean que indica si la instancia de cadena actual
comienza con un carácter en mayúscula. El estándar Unicode distingue caracteres en mayúsculas de
caracteres en minúsculas. El método Char.IsUpper(Char) devuelve true si un carácter está en mayúsculas.
4. En la barra de menús, seleccione Compilar > Compilar solución.
El proyecto se debería compilar sin errores.

Pasos siguientes
La biblioteca se ha creado correctamente. Como no se ha llamado a ninguno de los métodos, no se sabe si
funciona como estaba previsto. El siguiente paso en el desarrollo de la biblioteca consiste en probarla.
Crear un proyecto de prueba unitaria
Prueba de una biblioteca .NET Standard con .NET
Core en Visual Studio
20/01/2020 • 15 minutes to read • Edit Online

En Creación de una biblioteca de .NET Standard con C# y el SDK de .NET Core en Visual Studio 2017, ha creado
una biblioteca de clases simple que agrega un método de extensión a la clase String. Ahora, creará una prueba
unitaria para asegurarse de que funciona según lo esperado. Agregará su proyecto de prueba unitaria a la solución
que ha creado en el artículo anterior.

Crear un proyecto de prueba unitaria


Para crear el proyecto de prueba unitaria, haga lo siguiente:
1. Abra la solución ClassLibraryProjects que creó en el artículo Creación de una biblioteca de .NET Standard
con C# y el SDK de .NET Core en Visual Studio 2017.
2. Agregue un nuevo proyecto de prueba unitaria denominado "StringLibraryTest" a la solución.
a. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione
Agregar > Nuevo proyecto.
b. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba mstest. En la lista de
lenguajes, elija C# o Visual Basic y, luego, en la lista de plataformas, elija Todas las plataformas.
Elija la plantilla Proyecto de prueba de Ms (.NET Core) y, luego, elija Siguiente.
c. En la página Configurar el nuevo proyecto, escriba StringLibraryTest en el cuadro Nombre del
proyecto. Luego, elija Crear.

NOTE
Además de MSTest, también puede crear proyectos de prueba xUnit y nUnit para .NET Core en Visual Studio.

3. Visual Studio crea el proyecto y abre el archivo de clase en la ventana de código con el siguiente código:

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace StringLibraryTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
}
}
}
Imports Microsoft.VisualStudio.TestTools.UnitTesting

Namespace StringLibraryTest
<TestClass>
Public Class UnitTest1
<TestMethod>
Sub TestSub()

End Sub
End Class
End Namespace

El código fuente creado por la plantilla de prueba unitaria hace lo siguiente:


Importa el espacio de nombres de Microsoft.VisualStudio.TestTools.UnitTesting, que contiene los
tipos utilizados para las pruebas unitarias.
Aplica el atributo TestClass a la clase UnitTest1 . Cada método de prueba en una clase de prueba
etiquetada con el atributo TestMethod se ejecuta automáticamente cuando se ejecute la prueba
unitaria.
Aplica el atributo TestMethod para definir TestMethod1 en C# o TestSub en Visual Basic como
método de prueba para la ejecución automática cuando se ejecuta la prueba unitaria.
4. En el Explorador de soluciones, haga clic con el botón derecho en el nodo Dependencias del proyecto
StringLibraryTest y seleccione Agregar referencia del menú contextual.

5. En el cuadro de diálogo Administrador de referencias, expanda el nodo Proyectos y marque la casilla


junto a StringLibrary. Agregar una referencia al ensamblado StringLibrary permite al compilador buscar
métodos StringLibrary. Seleccione el botón Aceptar. Se agrega una referencia a su proyecto de biblioteca
de clases, StringLibrary .

Adición y ejecución de métodos de prueba unitaria


Cuando Visual Studio ejecuta una prueba unitaria, ejecuta cada método marcado con el atributo
TestMethodAttribute en una clase de prueba unitaria; la clase a la que se le aplica el atributo TestClassAttribute. Un
método de prueba finaliza cuando se encuentra el primer error, o cuando todas las pruebas contenidas en el
método se han realizado correctamente.
Las pruebas más comunes llaman a los miembros de la clase Assert. Muchos métodos de aserción incluyen al
menos dos parámetros, uno de los cuales es el resultado esperado de la prueba y el otro es el resultado real de la
prueba. Algunos de los métodos Assert a los que se llama con más frecuencia se muestran en la tabla siguiente:

MÉTODOS DE ASERCIÓN FUNCIÓN

Assert.AreEqual Comprueba que dos valores u objetos son iguales. La aserción


da error si los valores o los objetos no son iguales.

Assert.AreSame Comprueba que dos variables de objeto hacen referencia al


mismo objeto. La aserción da error si las variables hacen
referencia a objetos diferentes.

Assert.IsFalse Comprueba si una condición es false . La aserción produce


un error si la condición es true .

Assert.IsNotNull Comprueba que un objeto no es null . La aserción da error


si el objeto es null .

También puede usar el método ThrowsException en un método de prueba para indicar el tipo de excepción que se
espera que produzca. La prueba dará error si no se inicia la excepción especificada.
Al probar el método StringLibrary.StartsWithUpper , quiere proporcionar un número de cadenas que comiencen
con un carácter en mayúsculas. Espera que el método devuelva true en estos casos, por lo que puede llamar al
método IsTrue. Del mismo modo, quiere proporcionar un número de cadenas que comiencen con algo que no sea
un carácter en mayúsculas. Espera que el método devuelva false en estos casos, por lo que puede llamar al
método IsFalse.
Dado que el método de biblioteca administra cadenas, quiere asegurarse también de que administra
correctamente una cadena vacía ( String.Empty ), una cadena válida que no tenga caracteres y cuyo Length sea 0, y
una cadena null que no se haya inicializado. Si StartsWithUpper se llama como un método de extensión en una
instancia String, no se puede pasar una cadena null . En cambio, también se puede llamar directamente como un
método estático y pasarse como un argumento String único.
Definirá tres métodos, cada uno de los cuales llama a su método Assert repetidamente para cada elemento de una
matriz de cadenas. Dado que el método de prueba produce un error tan pronto como encuentra el primer error,
llamará a una sobrecarga de método que le permita pasar una cadena que indique el valor de cadena usado en la
llamada al método.
Para crear los métodos de prueba:
1. En la ventana de código UnitTest1.cs o UnitTest1.vb, reemplace el código por el siguiente:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UtilityLibraries;

namespace StringLibraryTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestStartsWithUpper()
{
// Tests that we expect to return true.
string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
foreach (var word in words)
{
bool result = word.StartsWithUpper();
Assert.IsTrue(result,
String.Format("Expected for '{0}': true; Actual: {1}",
word, result));
}
}

[TestMethod]
public void TestDoesNotStartWithUpper()
{
// Tests that we expect to return false.
string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
"1234", ".", ";", " " };
foreach (var word in words)
{
bool result = word.StartsWithUpper();
Assert.IsFalse(result,
String.Format("Expected for '{0}': false; Actual: {1}",
word, result));
}
}

[TestMethod]
public void DirectCallWithNullOrEmpty()
{
// Tests that we expect to return false.
string[] words = { string.Empty, null };
foreach (var word in words)
{
bool result = StringLibrary.StartsWithUpper(word);
Assert.IsFalse(result,
String.Format("Expected for '{0}': false; Actual: {1}",
word == null ? "<null>" : word, result));
}
}
}
}
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports UtilityLibraries

Namespace StringLibraryTest
<TestClass>
Public Class UnitTest1
<TestMethod>
Public Sub TestStartsWithUpper()
' Tests that we expect to return true.
Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
For Each word In words
Dim result As Boolean = word.StartsWithUpper()
Assert.IsTrue(result,
$"Expected for '{word}': true; Actual: {result}")
Next
End Sub

<TestMethod>
Public Sub TestDoesNotStartWithUpper()
' Tests that we expect to return false.
Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
"1234", ".", ";", " "}
For Each word In words
Dim result As Boolean = word.StartsWithUpper()
Assert.IsFalse(result,
$"Expected for '{word}': false; Actual: {result}")
Next
End Sub

<TestMethod>
Public Sub DirectCallWithNullOrEmpty()
' Tests that we expect to return false.
Dim words() As String = {String.Empty, Nothing}
For Each word In words
Dim result As Boolean = StringLibrary.StartsWithUpper(word)
Assert.IsFalse(result,
$"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual:
{result}")
Next
End Sub
End Class
End Namespace

La prueba de caracteres en mayúsculas en el método TestStartsWithUpper incluye la letra mayúscula griega


alfa (U + 0391) y la letra mayúscula cirílica EM (U + 041C ). La prueba de caracteres en minúsculas en el
método TestDoesNotStartWithUpper incluye la letra griega minúscula alfa (U + 03B1) y la letra cirílica
minúscula Ghe (U + 0433).
2. En la barra de menús, seleccione Archivo > Guardar UnitTest1.cs como o Archivo > Guardar
UnitTest1.vb como. En el cuadro de diálogo Guardar archivo como, seleccione la flecha junto al botón
Guardar y seleccione Guardar con codificación.
3. En el cuadro de diálogo Confirmar guardar como, seleccione el botón Sí para guardar el archivo.
4. En el cuadro de diálogo Opciones avanzadas para guardar, seleccione Unicode (UTF-8 con firma) -
Página de códigos 65001 desde la lista desplegable Codificación y seleccione Aceptar.

Si obtiene un error al guardar el código fuente en un archivo con codificación UTF -8, Visual Studio puede
guardarlo como un archivo ASCII. Cuando eso suceda, el tiempo de ejecución no descodifica correctamente
los caracteres UTF -8 del rango ASCII, y los resultados de la prueba no serán correctos.
5. En la barra de menús, seleccione Prueba > Ejecutar > Todas las pruebas. Se abre la ventana del
Explorador de pruebas y muestra que las pruebas se han ejecutado correctamente. Las tres pruebas se
muestran en la sección Pruebas superadas y en la sección Resumen se informa del resultado de la serie
de pruebas.
Administración de errores de prueba
Su serie de pruebas no tuvo errores, pero vamos a cambiarla un poco para que uno de los métodos de prueba
produzca un error:
1. Modifique la matriz words en el método TestDoesNotStartWithUpper para incluir la cadena "Error". No
necesita guardar el archivo porque Visual Studio guarda automáticamente archivos abiertos cuando se crea
una solución para ejecutar pruebas.

string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",


"1234", ".", ";", " " };

Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",


"1234", ".", ";", " " }

2. Ejecute la prueba seleccionando Prueba > Ejecutar > Todas las pruebas de la barra de menús. En la
ventana Explorador de pruebas se indica que dos pruebas se han realizado correctamente y que una ha
finalizado con errores.

3. Seleccione la prueba con errores, TestDoesNotStartWith . En la ventana Explorador de pruebas se muestra


el mensaje generado por la instrucción Assert: "Error de Assert.IsFalse. Se esperaba para "Error": false; real:
True". Debido al error, no se probaron todas las cadenas de la matriz después de "Error".
4. Deshaga la modificación que hizo en el paso 1 y quite la cadena "Error". Vuelva a ejecutar la prueba y se
superarán las pruebas.

Prueba de la versión de la biblioteca


Ha estado ejecutando sus pruebas con la versión de depuración de la biblioteca. Ahora que todas sus pruebas se
han superado y que ha probado adecuadamente la biblioteca, debe ejecutar las pruebas un tiempo adicional con
respecto a la compilación de versión de la biblioteca. Varios factores, como las optimizaciones del compilador, a
veces pueden producir un comportamiento diferente entre las compilaciones de depuración y versión.
Para probar la compilación de versión:
1. En la barra de herramientas de Visual Studio, cambie la configuración de compilación de Depurar a
Versión.

2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto StringLibrary y seleccione
Compilar desde el menú contextual para volver a compilar la biblioteca.

3. Ejecute las pruebas unitarias seleccionando Prueba > Ejecutar > Todas las pruebas de la barra de
menús. Las pruebas se superan.
Ahora que ha terminado de probar la biblioteca, el siguiente paso es ponerla a disposición de los llamadores.
Puede empaquetarla con una o varias aplicaciones o puede distribuirla como un paquete NuGet. Para obtener
más información, vea Consumo de una biblioteca de clases .NET Standard.

Vea también
Conceptos básicos de las pruebas unitarias en Visual Studio
Consumo de una biblioteca de .NET Standard en
Visual Studio
20/01/2020 • 8 minutes to read • Edit Online

Una vez que haya creado una biblioteca de clases de .NET Standard, la haya probado y haya creado una versión de
lanzamiento de dicha biblioteca, el siguiente paso es ponerla a disposición de los autores de las llamadas. Existen
dos maneras de hacerlo:
Si una única solución va a usar la biblioteca (por ejemplo, si es un componente de una sola aplicación más
grande), se puede incluir como proyecto en la solución.
Si la biblioteca va a estar accesible públicamente, puede distribuirla como un paquete NuGet.
En este tutorial aprenderá a:
Agregue una aplicación de consola a la solución que haga referencia a un proyecto de biblioteca de .NET
Standard.
Cree un paquete NuGet que contenga un proyecto de biblioteca de .NET Standard.

Incorporación de una aplicación de consola a la solución


Así como incluyó pruebas unitarias en la misma solución que la biblioteca de clases en Prueba de una biblioteca
de .NET Standard con .NET Core en Visual Studio 2017, puede incluir la aplicación como parte de esa solución.
Por ejemplo, se puede usar la biblioteca de clases en una aplicación de consola que pide al usuario que inserte una
cadena e informa de si su primer carácter está en mayúsculas:
1. Abra la solución ClassLibraryProjects que creó en el artículo Creación de una biblioteca de clases de .NET
Standard en Visual Studio.
2. Agregue una nueva aplicación de consola de .NET Core denominada "Showcase" a la solución.
a. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione
Agregar > Nuevo proyecto.
b. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba consola. Elija C# o
Visual Basic en la lista de lenguajes y luego, Todas las plataformas en la lista de plataformas. Elija
la plantilla Aplicación de consola (.NET Core) y haga clic en Siguiente.
c. En la página Configure el nuevo proyecto, escriba ShowCase en el cuadro Nombre del
proyecto. Luego, elija Crear.
3. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto Presentación y seleccione
Establecer como proyecto de inicio en el menú contextual.
4. Inicialmente, el proyecto no tiene acceso a la biblioteca de clases. Para permitir que se llame a métodos de
la biblioteca de clases, puede crear una referencia a la biblioteca de clases. En el Explorador de
soluciones, haga clic con el botón derecho en el nodo Dependencias del proyecto ShowCase y seleccione
Agregar referencia.

5. En el cuadro de diálogo Administrador de referencias, seleccione StringLibrary, el proyecto de


biblioteca de clases, y pulse el botón Aceptar.
6. En la ventana de código del archivo Program.vb o Program.vb, reemplace todo el código con el código
siguiente:
using System;
using UtilityLibraries;

class Program
{
static void Main(string[] args)
{
int row = 0;

do
{
if (row == 0 || row >= 25)
ResetConsole();

string input = Console.ReadLine();


if (String.IsNullOrEmpty(input)) break;
Console.WriteLine($"Input: {input} {"Begins with uppercase? ",30}: " +
$"{(input.StartsWithUpper() ? "Yes" : "No")}\n");
row += 3;
} while (true);
return;

// Declare a ResetConsole local method


void ResetConsole()
{
if (row > 0) {
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
Console.Clear();
Console.WriteLine("\nPress <Enter> only to exit; otherwise, enter a string and press
<Enter>:\n");
row = 3;
}
}
}
Imports UtilityLibraries

Module Program
Dim row As Integer = 0

Sub Main()
Do
If row = 0 OrElse row >= 25 Then ResetConsole()

Dim input As String = Console.ReadLine()


If String.IsNullOrEmpty(input) Then Return

Console.WriteLine($"Input: {input} {"Begins with uppercase? ",30}: " +


$"{If(input.StartsWithUpper(), "Yes", "No")} {vbCrLf}")
row += 3
Loop While True
End Sub

Private Sub ResetConsole()


If row > 0 Then
Console.WriteLine("Press any key to continue...")
Console.ReadKey()
End If
Console.Clear()
Console.WriteLine("{0}Press <Enter> only to exit; otherwise, enter a string and press <Enter>:
{0}",
vbCrLf)
row = 3
End Sub
End Module

El código usa la variable row para mantener un recuento del número de filas de datos escritas en la
ventana de consola. Siempre que sea mayor o igual a 25, el código borra la ventana de consola y muestra
un mensaje al usuario.
El programa le pide al usuario que escriba una cadena. Indica si la cadena comienza con un carácter en
mayúsculas. Si el usuario presiona la tecla Entrar sin especificar una cadena, la aplicación finaliza y la
ventana de la consola se cierra.
7. Si es necesario, cambie la barra de herramientas para compilar la versión de depuración del proyecto
ShowCase . Compile y ejecute el programa haciendo clic en la flecha verde en el botón Presentación.

La aplicación que usa esta biblioteca se puede depurar y publicar siguiendo los pasos indicados en Depuración de
la aplicación Hola mundo de .NET Core en C# o Visual Basic con Visual Studio 2017 y Publicación de la aplicación
Hola mundo de .NET Core con Visual Studio 2017.

Creación de un paquete NuGet


Puede hacer que la biblioteca de clases tenga una disponibilidad amplia si la publica como un paquete NuGet.
Visual Studio no admite la creación de paquetes NuGet. Para crear uno, debe usar los comandos de la CLI de .NET
Core:
1. Abra una ventana de consola.
Por ejemplo, escriba Símbolo del sistema en el cuadro de búsqueda de la barra de tareas de Windows.
Seleccione la aplicación de escritorio Símbolo del sistema o presione Entrar si ya está seleccionado en los
resultados de búsqueda.
2. Vaya al directorio del proyecto de la biblioteca. El directorio contiene el código fuente y un archivo de
proyecto, StringLibrary.csproj o StringLibrary.vbproj.
3. Ejecute el comando dotnet pack para generar un paquete con una extensión .nupkg:

dotnet pack --no-build

TIP
Si el directorio que contiene dotnet.exe no está en la ruta de acceso, puede encontrar su ubicación escribiendo
where dotnet.exe en la ventana de consola.

Para más información sobre la creación de paquetes NuGet, consulte Cómo crear un paquete NuGet con
herramientas multiplataforma .
Novedades de .NET Core 3.1
20/01/2020 • 4 minutes to read • Edit Online

En este artículo se describen las novedades de .NET Core 3.1. Esta versión contiene ligeras mejoras de .NET Core
3.0, y se centra en pequeñas correcciones, pero importantes. La característica más importante sobre .NET Core 3.1
es que es una versión de soporte técnico a largo plazo (LTS ) .
Si usa Visual Studio 2019, debe actualizar a Visual Studio 2019, versión 16.4 para trabajar con proyectos de .NET
Core 3.1. Para más información sobre las novedades de Visual Studio, consulte el blog de Visual Studio.
Visual Studio para Mac también admite e incluye .NET Core 3.1 en el canal de la versión preliminar de
Visual Studio para Mac 8.4. Deberá participar en el canal de versión preliminar para usar .NET Core 3.1.
Para más información sobre la versión, consulte el anuncio de .NET Core 3.1.
Descargue .NET Core 3.1 y empiece a trabajar en Windows, macOS o Linux.

Compatibilidad a largo plazo


.NET Core 3.1 es una versión LTS con soporte técnico de Microsoft durante los próximos tres años. Se recomienda
encarecidamente mover las aplicaciones a .NET Core 3.1. El ciclo de vida actual de otras versiones principales es el
siguiente:

RELEASE NOTA

.NET Core 3.0 Fin del ciclo de vida el 3 de marzo de 2020.

.NET Core 2.2 Fin del ciclo de vida el 23 de diciembre de 2019.

.NET Core 2.1 Fin del ciclo de vida el 21 de agosto de 2021.

Para más información, consulte la directiva de soporte técnico de .NET Core.

Windows Forms
Solo Windows

WARNING
Hay cambios importantes en Windows Forms.

Se incluyeron controles heredados en Windows Forms que llevan un tiempo sin estar disponibles en el cuadro de
herramientas del diseñador de Visual Studio. Estos controles se volvieron a reemplazar por otros nuevos en .NET
Framework 2.0 y se han quitado del SDK de escritorio para .NET Core 3.1.

CONTROL ELIMINADO REEMPLAZO RECOMENDADO API ASOCIADAS ELIMINADAS


CONTROL ELIMINADO REEMPLAZO RECOMENDADO API ASOCIADAS ELIMINADAS

DataGrid DataGridView DataGridCell


DataGridRow
DataGridTableCollection
DataGridColumnCollection
DataGridTableStyle
DataGridColumnStyle
DataGridLineStyle
DataGridParentRowsLabel
DataGridParentRowsLabelStyle
DataGridBoolColumn
DataGridTextBox
GridColumnStylesCollection
GridTableStylesCollection
HitTestType

ToolBar ToolStrip ToolBarAppearance

ToolBarButton ToolStripButton ToolBarButtonClickEventArgs


ToolBarButtonClickEventHandler
ToolBarButtonStyle
ToolBarTextAlign

ContextMenu ContextMenuStrip

Menu ToolStripDropDown MenuItemCollection


ToolStripDropDownMenu

MainMenu MenuStrip

MenuItem ToolStripMenuItem

Se recomienda actualizar las aplicaciones a .NET Core 3.1 y pasar a los controles de reemplazo. Reemplazar los
controles es un proceso sencillo; se trata básicamente de "buscar y reemplazar" el tipo.

C++/CLI
Solo Windows
Se ha agregado compatibilidad con la creación de proyectos de C++/CLI (lo que también se conoce como "C++
administrado"). Los archivos binarios generados a partir de estos proyectos son compatibles con .NET Core 3.0 y
versiones posteriores.
Para agregar compatibilidad con C++/CLI en Visual Studio 2019 16.4, instale la carga de trabajo Desarrollo para el
escritorio con C++. Esta carga de trabajo agrega dos plantillas a Visual Studio:
Biblioteca de clases de CLR (.NET Core)
Proyecto vacío de CLR (.NET Core)

Pasos siguientes
Revise los cambios importantes entre .NET Core 3.0 y 3.1.
Revise los cambios importantes entre .NET Framework y .NET Core 3.0 para aplicaciones de Windows Forms.
Novedades de .NET Core 3.0
03/12/2019 • 41 minutes to read • Edit Online

En este artículo se describen las novedades de .NET Core 3.0. Una de las mejoras más importantes es la
compatibilidad con las aplicaciones de Escritorio de Windows (solo Windows). Mediante el componente Escritorio
de Windows del SDK de .NET Core 3.0, puede portar sus aplicaciones de Windows Forms y
Windows Presentation Foundation (WPF ). Para ser más precisos, el componente Escritorio de Windows solo se
admite e incluye en Windows. Para obtener más información, vea la sección Escritorio de Windows más adelante
en este artículo.
.NET Core 3.0 agrega compatibilidad con C# 8.0. Se recomienda encarecidamente usar Visual Studio 2019, versión
16.3 o una versión posterior, Visual Studio para Mac 8.3 o una versión posterior, o Visual Studio Code con la última
extensión de C# .
Descargue .NET Core 3.0 y empiece a trabajar ya en Windows, macOS o Linux.
Para obtener más información acerca de la versión, consulte el anuncio de .NET Core 3.0.
Microsoft considera .NET Core RC1 como listo para producción y es totalmente compatible. Si usa una versión
preliminar, debe pasar a la versión RTM para obtener soporte técnico continuo.

Mejoras del lenguaje C# 8.0


C# 8.0 también forma parte de esta versión, que incluye la característica de tipos de referencia que aceptan valores
NULL, flujos asincrónicos y más patrones. Para obtener más información sobre las características de C# 8.0, vea
Novedades de C# 8.0.
Se han agregado mejoras del lenguaje para admitir las siguientes características de API que se detallan a
continuación:
Rangos e índices
Flujos asincrónicos

.NET Standard 2.1


.NET Core 3.0 implementa .NET Standard 2.1. Pero la plantilla predeterminada dotnet new classlib genera un
proyecto que sigue destinado a .NET Standard 2.0. Para destinarlo a .NET Standard 2.1, edite el archivo de
proyecto y cambie la propiedad TargetFramework a netstandard2.1 :

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

</Project>

Si usa Visual Studio, necesita Visual Studio 2019, ya que Visual Studio 2017 no admite .NET Standard 2.1 ni
.NET Core 3.0.

Compilación e implementación
Archivos ejecutables predeterminados
.NET Core compila ahora archivos ejecutables dependientes del marco de forma predeterminada. Este
comportamiento es nuevo en las aplicaciones que usan una versión de .NET Core instalada globalmente.
Anteriormente, solo las implementaciones independientes generarían un archivo ejecutable.
Durante dotnet build o dotnet publish , se crea un archivo ejecutable que coincide con el entorno y la plataforma
del SDK que se usa. Estos ejecutables funcionan de la misma forma que los ejecutables nativos:
Haga doble clic en el archivo ejecutable.
También puede iniciar la aplicación desde un símbolo del sistema directamente, como myapp.exe en Windows y
./myapp en Linux y macOS.

Archivos ejecutables de único archivo


El comando dotnet publish admite empaquetar la aplicación en un ejecutable de archivo único específico de la
plataforma. El archivo ejecutable es autoextraíble y contiene todas las dependencias (incluidas las nativas)
necesarias para ejecutar la aplicación. Cuando la aplicación se ejecuta por primera vez, se extrae en un directorio
que se basa en el nombre de la aplicación y el identificador de compilación. El inicio es más rápido cuando se
vuelve a ejecutar la aplicación. La aplicación no necesita extraerse por segunda vez a menos que se haya utilizado
una nueva versión.
Para publicar un ejecutable de archivo único, establezca PublishSingleFile en el proyecto o en la línea de
comandos con el comando dotnet publish :

<PropertyGroup>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

O bien

dotnet publish -r win10-x64 -p:PublishSingleFile=true

Para obtener más información sobre la publicación de archivos únicos, vea el documento de diseño del programa
de instalación de conjunto de archivos únicos.
Vinculación de ensamblados
El SDL de .NET Core 3.0 cuenta con una herramienta que puede reducir el tamaño de las aplicaciones mediante el
análisis de IL y el recorte de los ensamblados no usados.
Las aplicaciones independientes incluyen todo lo necesario para ejecutar el código, sin necesidad de instalar .NET
en el equipo host. Sin embargo, muchas veces, la aplicación solo requiere un pequeño subconjunto de marco para
que funcione, y otras bibliotecas que no se utilizan podrían quitarse.
.NET Core incluye ahora un valor que usará la herramienta Enlazador de IL para examinar el nivel de integridad de
la aplicación. Esta herramienta detecta el código que es necesario y, después, recorta las bibliotecas no utilizadas.
Esta herramienta puede reducir significativamente el tamaño de implementación de algunas aplicaciones.
Para habilitar esta herramienta, agregue el valor <PublishTrimmed> en el proyecto y publique una aplicación
independiente:

<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
dotnet publish -r <rid> -c Release

Por ejemplo, la nueva y básica plantilla de proyecto de consola "Hola mundo" que se incluye, cuando se publica,
tiene un tamaño aproximado de 70 MB. Mediante el uso de <PublishTrimmed> , ese tamaño se reduce a unos 30
MB.
Es importante tener en cuenta que las aplicaciones o marcos (incluidos ASP.NET Core y WPF ) que usan la
reflexión o las características dinámicas relacionadas, se interrumpirán a menudo cuando se recorten. Esta
interrupción se produce porque el enlazador no conoce este comportamiento dinámico y no puede determinar qué
tipos de marco son necesarios para la reflexión. La herramienta Enlazador de IL puede configurarse para tener en
cuenta este escenario.
Por encima de todo lo demás, no olvide probar la aplicación después del recorte.
Para más información sobre la herramienta Enlazador de IL, vea la documentación o visite el repositorio
mono/linker.
Compilación en niveles
La compilación en niveles (TC ) está activada de forma predeterminada con .NET Core 3.0. Esta característica
permite que el runtime utilice el compilador Just-In-Time (JIT) de forma más flexible para generar un mejor
rendimiento.
La principal ventaja de TC es permitir la vuelta a los métodos JIT con un nivel de menor calidad, pero más rápido, o
un nivel de mayor calidad, pero más lento. Esto contribuye a aumentar el rendimiento de una aplicación a medida
que pasa por distintas fases de ejecución, desde el inicio hasta alcanzar el estado estable. Esto contrasta con el
enfoque no TC, donde cada método se compila de una sola manera (al igual que el nivel de alta calidad), que se
inclina por el estado estable sobre el rendimiento de inicio.
Al habilitar TC durante el inicio de un método al que se llama:
Si el método tiene código compilado por AOT (ReadyToRun), se usará el código generado previamente.
De lo contrario, el método se compilará mediante JIT. Normalmente, estos métodos son genéricos con respecto
a los tipos de valor.
La compilación mediante JIT rápida produce código de menor calidad a un ritmo superior. Este tipo de
compilación está habilitado de forma predeterminada en .NET Core 3.0 para los métodos que no
contienen ningún bucle y que tienen preferencia durante el inicio.
La compilación mediante JIT completamente optimizada produce código de mayor calidad a un ritmo
inferior. En el caso de los métodos en los que no se use la compilación mediante JIT rápida (por ejemplo,
si el método tiene el atributo [MethodImpl(MethodImplOptions.AggressiveOptimization)] ), se utilizará la
compilación mediante JIT totalmente optimizada.
Finalmente, después de que se llame a los métodos varias veces, se volverán a compilar mediante JIT con la
compilación mediante JIT completamente optimizada en segundo plano.
El código generado con compilación mediante JIT rápida puede ejecutarse más lentamente, asignar más memoria
o usar más espacio de pila. Si tiene algún problema, puede deshabilitar la compilación mediante JIT rápida usando
este valor en el archivo del proyecto:

<PropertyGroup>
<TieredCompilationQuickJit>false</TieredCompilationQuickJit>
</PropertyGroup>

Para deshabilitar completamente TC, use esta opción en el archivo de proyecto:


<PropertyGroup>
<TieredCompilation>false</TieredCompilation>
</PropertyGroup>

Cualquier cambio en la configuración anterior del archivo del proyecto puede requerir que se refleje una
compilación limpia (elimine los directorios obj y bin y vuelva a realizar la compilación).
Imágenes ReadyToRun
Puede mejorar el tiempo de inicio de la aplicación .NET Core mediante la compilación de los ensamblados de
aplicación como el formato ReadyToRun (R2R ). R2R es una forma de compilación Ahead Of Time (AOT).
Los binarios de R2R mejoran el rendimiento de inicio reduciendo la cantidad de trabajo que el compilador Just-In-
Time (JIT) debe llevar a cabo cuando se carga la aplicación. Los binarios contienen código nativo similar en
comparación con lo que generaría el compilador JIT. Sin embargo, los binarios de R2R son más grandes porque
contienen tanto el código de lenguaje intermedio (IL ), que sigue siendo necesario para algunos escenarios, como la
versión nativa del mismo código. R2R solo está disponible cuando publica una aplicación independiente que tenga
como destino entornos de tiempo de ejecución específicos (RID ), como Linux x64 o Windows x64.
Para compilar el proyecto como ReadyToRun, haga lo siguiente:
1. Agregue el valor <PublishReadyToRun> al proyecto:

<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

2. Publique una aplicación independiente. Por ejemplo, este comando crea una aplicación independiente para
la versión de 64 bits de Windows:

dotnet publish -c Release -r win-x64 --self-contained

Restricciones multiplataforma y de arquitectura


Actualmente, el compilador ReadyToRun no admite la compatibilidad cruzada. Debe compilar en un destino dado.
Por ejemplo, si desea imágenes R2R para Windows x64, deberá ejecutar el comando de publicación en ese
entorno.
Excepciones de la compatibilidad cruzada:
Windows x64 se puede usar para compilar imágenes de Windows ARM32, ARM64 y x86.
Windows x86 se puede usar para compilar imágenes de Windows ARM32.
Linux x64 se puede usar para compilar imágenes de Linux ARM32 y ARM64.

Runtime y SDK
Puesta al día de versiones principales
.NET Core 3.0 presenta una característica opcional que permite poner la aplicación al día con la versión principal
más reciente de .NET Core. Además, se agregó una nueva configuración para controlar cómo se aplica la puesta al
día a la aplicación. Esto se puede configurar de las maneras siguientes:
Propiedad de archivo del proyecto: RollForward
Propiedad de archivo de configuración del entorno de ejecución: rollForward
Variable de entorno: DOTNET_ROLL_FORWARD
Argumento de línea de comandos: --roll-forward
Debe especificarse uno de los valores siguientes. Si se omite la configuración, Minor es el valor predeterminado.
LatestPatch
Se pone al día con la última versión de revisión. Se deshabilita la puesta al día de versiones secundarias.
Minor
Se pone al día con la versión secundaria mínima superior, si no se encuentra la versión secundaria solicitada. Si
se encuentra la versión secundaria solicitada, se utiliza la directiva LatestPatch.
Major
Se pone al día con la versión secundaria mínima superior, y la versión secundaria mínima, si no se encuentra la
versión secundaria solicitada. Si se encuentra la versión principal solicitada, se utiliza la directiva Minor.
LatestMinor
Se pone al día con la última versión secundaria, aunque la versión secundaria solicitada esté presente. Se
destina a escenarios de hospedaje de componentes.
LatestMajor
Se pone al día con la última versión principal y la última versión secundaria, aunque la versión principal
solicitada esté presente. Se destina a escenarios de hospedaje de componentes.
Disable
No se pone al día. Solo se enlaza a la versión especificada. No se recomienda esta directiva para uso general, ya
que deshabilita la capacidad de puesta al día con las revisiones más recientes. Este valor solo se recomienda a
efectos de pruebas.
Además del valor Disable, todos los valores usarán la última versión de revisión disponible.
Compilación de dependencias de copias
El comando dotnet build copia ahora las dependencias de NuGet para la aplicación de la caché de NuGet a la
carpeta de salida de compilación. Anteriormente, las dependencias solo se copiaban como parte de dotnet publish
.
Hay algunas operaciones, como la publicación de páginas Razor y la vinculación, que aún es necesario publicar.
Herramientas locales
.NET Core 3.0 presenta herramientas locales. Las herramientas locales son similares a las herramientas globales
pero están asociadas a una ubicación concreta en el disco. Las herramientas locales no están disponibles
globalmente y se distribuyen como paquetes NuGet.

WARNING
Si ha probado herramientas locales en la versión preliminar 1 de .NET Core 3.0, tales como la ejecución de
dotnet tool restore o de dotnet tool install , elimine la carpeta de caché de herramientas locales. En caso contrario,
las herramientas locales no funcionan en las versiones más recientes. Esta carpeta se encuentra en:
En macOS, Linux: rm -r $HOME/.dotnet/toolResolverCache

En Windows: rmdir /s %USERPROFILE%\.dotnet\toolResolverCache

Las herramientas locales se basan en un nombre de archivo de manifiesto dotnet-tools.json del directorio actual.
Este archivo de manifiesto define las herramientas que estarán disponibles en esa carpeta y a continuación. Puede
distribuir el archivo de manifiesto con su código para asegurarse de que todo aquel que trabaje con su código
pueda restaurar y utilizar las mismas herramientas.
Para las herramientas locales y globales, se requiere una versión compatible del entorno de ejecución. Actualmente,
muchas herramientas de NuGet.org tienen como destino el entorno de ejecución de .NET Core 2.1. Para instalar
estas herramientas local o globalmente, aún tendría que instalar NET Core 2.1 Runtime.
Tamaños del montón de recolección de elementos no utilizados más pequeños
Se ha reducido el tamaño predeterminado del montón del recolector de elementos no utilizados, lo que se traduce
en que .NET Core usa menos memoria. Este cambio se adapta mejor al presupuesto de asignación de generación 0
con tamaños de caché de procesador moderno.
Compatibilidad con Large Pages de recolección de elementos no utilizados
Large Pages (también conocida como Huge Pages en Linux) es una característica en la que el sistema operativo es
capaz de establecer regiones de memoria más grandes que el tamaño de página nativo (a menudo, 4 K) para
mejorar el rendimiento de la aplicación que solicita estas páginas grandes.
Ahora, el recolector de elementos no utilizados puede configurarse con el valor GCLargePages como
característica opcional para elegir la asignación de páginas grandes en Windows.

Escritorio de Windows y COM


Windows Installer del SDK de .NET Core
El instalador MSI para Windows ha cambiado a partir de .NET Core 3.0. Los instaladores del SDK actualizarán
ahora las versiones de la banda de características del SDK. Las bandas de características se definen en los grupos
de centenas de la sección revisión del número de versión. Por ejemplo, 3.0.101 y 3.0.201 son versiones de dos
bandas de características distintas mientras que 3.0.101 y 3.0.199 están en la misma banda de características. Y,
cuando se instale el SDK 3.0.101 de .NET Core, se quitará el SDK 3.0.100 de .NET Core de la máquina si existe.
Cuando se instale el SDK 3.0.200 de .NET Core en la misma máquina, no se quitará el SDK 3.0.101 de .NET Core.
Para obtener más información sobre las versiones, vea el artículo de introducción a la creación de versiones de
.NET Core.
Escritorio de Windows
.NET Core 3.0 admite aplicaciones de escritorio de Windows con Windows Presentation Foundation (WPF ) y
Windows Forms. Estos marcos también admiten el uso de controles modernos y los estilos de Fluent de la
biblioteca de XAML de la interfaz de usuario de Windows (WinUI) a través de islas XAML.
El componente Escritorio de Windows forma parte del SDK de Windows .NET Core 3.0.
Puede crear una aplicación de Windows Forms o WPF con los siguientes comandos dotnet :

dotnet new wpf


dotnet new winforms

Visual Studio 2019 agrega plantillas de nuevo proyecto para WPF y Windows Forms de .NET Core 3.0.
Para obtener más información sobre cómo migrar una aplicación existente de .NET Framework, vea los artículos
sobre cómo portar proyectos de WPF y cómo portar proyectos de Windows Forms.
PPP alto de WinForms
En .NET Core, las aplicaciones de Windows Forms pueden establecer el modo de valores altos de PPP con
Application.SetHighDpiMode(HighDpiMode). El método SetHighDpiMode establece el modo de valores altos de
PPP correspondiente a menos que la opción se haya establecido por otros medios como App.Manifest o P/Invoke
antes de Application.Run .
Los posibles valores de highDpiMode , expresados por la enumeración System.Windows.Forms.HighDpiMode son:
DpiUnaware
SystemAware
PerMonitor
PerMonitorV2
DpiUnawareGdiScaled
Para más información sobre los modos de valores altos de PPP, consulte el artículo sobre desarrollo de
aplicaciones de escritorio con valores altos de PPP en Windows.
Creación de componentes COM
En Windows, ahora puede crear componentes COM administrados invocables. Esta capacidad es fundamental para
usar .NET Core con modelos de complemento COM, así como para ofrecer paridad con .NET Framework.
A diferencia de .NET Framework, donde se utilizó mscoree.dll como servidor COM, .NET Core agregará un archivo
dll de inicio nativo al directorio bin al compilar el componente COM.
Para ver un ejemplo de cómo crear un componente COM y usarlo, consulte la demostración de COM.
Interoperabilidad nativa de Windows
Windows ofrece una API nativa enriquecida en forma de API de C sin formato, COM y WinRT. Mientras que
.NET Core admite P/Invoke, .NET Core 3.0 agrega la capacidad de API COM CoCreate y API WinRT Activate.
Para obtener un ejemplo de código, vea la demostración de Excel.
Implementación de MSIX
MSIX es un nuevo formato de paquete de aplicación de Windows. Se puede usar para implementar aplicaciones de
escritorio de .NET Core 3.0 en Windows 10.
El proyecto de paquete de aplicación de Windows, disponible en Visual Studio 2019, le permite crear paquetes de
MSIX con aplicaciones de .NET Core independientes.
El archivo del proyecto de .NET Core debe especificar los tiempos de ejecución admitidos en la propiedad
<RuntimeIdentifiers> :

<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>

Mejoras de Linux
SerialPort para Linux
.Net Core 3.0 proporciona compatibilidad básica para System.IO.Ports.SerialPort en Linux.
Anteriormente, .NET Core solo admitía el uso de SerialPort en Windows.
Para obtener más información sobre la compatibilidad limitada para el puerto de serie en Linux, vea Problema
#33146 de GitHub.
Docker y límites de memoria de cgroup
La ejecución de .NET Core 3.0 en Linux con Docker funciona mejor con límites de memoria de cgroup. La ejecución
de un contenedor de Docker con límites de memoria, como con docker run -m , cambia el comportamiento de
.NET Core.
Tamaño predeterminado del montón del recolector de elementos no utilizados (GC ): máximo de 20 MB o 75 %
del límite de memoria en el contenedor.
Puede establecerse el tamaño explícito como número absoluto o porcentaje del límite de cgroup.
El tamaño mínimo del segmento reservado por el montón de GC es de 16 MB. Con este tamaño se reduce el
número de montones que se crean en las máquinas.
Compatibilidad de GPIO con Raspberry Pi
Se han publicado dos paquetes en NuGet que puede usar para la programación de GPIO:
System.Device.Gpio
Iot.Device.Bindings
Los paquetes GPIO incluyen interfaces API para dispositivos GPIO, SPI, I2C y PWM. El paquete de enlaces de IoT
incluye enlaces de dispositivos. Para obtener más información, vea el repositorio de GitHub de los dispositivos.
Compatibilidad con ARM64 para Linux
.NET Core 3.0 agrega compatibilidad con ARM64 para Linux. El principal caso de uso de ARM64 son escenarios de
IoT. Para obtener más información, vea el artículo sobre el estado de ARM64 de .NET Core.
Hay imágenes de docker para .NET Core en ARM64 disponibles para Alpine, Debian y Ubuntu.

NOTE
Windows aún no ofrece soporte técnico para ARM64.

Seguridad
TLS 1.3 y OpenSSL 1.1.1 en Linux
.NET Core aprovecha ahora la ventaja de la compatibilidad con TLS 1.3 en OpenSSL 1.1.1, cuando está disponible
en un entorno determinado. Con TLS 1.3:
Se han mejorado los tiempos de conexión con menores recorridos de ida y vuelta necesarios entre el cliente y
servidor.
Se ha mejorado la seguridad gracias a la eliminación de varios algoritmos criptográficos obsoletos y no
seguros.
Cuando está disponible, .NET Core 3.0 utiliza OpenSSL 1.1.1, OpenSSL 1.1.0 o OpenSSL 1.0.2 en un sistema
Linux. Si OpenSSL 1.1.1 está disponible, los tipos System.Net.Security.SslStream y System.Net.Http.HttpClient,
utilizarán TLS 1.3 (suponiendo que el cliente y el servidor admitan TLS 1.3).

IMPORTANT
Windows y macOS aún no admiten TLS 1.3. .NET Core 3.0 será compatible con TLS 1.3 en estos sistemas operativos cuando
haya disponible soporte técnico.

El siguiente ejemplo de C# 8.0 muestra .NET Core 3.0 en Ubuntu 18.10 al conectarse a https://www.cloudflare.com:
using System;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace whats_new
{
public static class TLS
{
public static async Task ConnectCloudFlare()
{
var targetHost = "www.cloudflare.com";

using TcpClient tcpClient = new TcpClient();

await tcpClient.ConnectAsync(targetHost, 443);

using SslStream sslStream = new SslStream(tcpClient.GetStream());

await sslStream.AuthenticateAsClientAsync(targetHost);
await Console.Out.WriteLineAsync($"Connected to {targetHost} with {sslStream.SslProtocol}");
}
}
}

Cifrados de criptografía
.NET 3.0 agrega compatibilidad con los cifrados AES -GCM y AES -CCM, que se implementan con
System.Security.Cryptography.AesGcm y System.Security.Cryptography.AesCcm respectivamente. Estos dos
algoritmos son algoritmos AEAD (Authenticated Encryption with Associated Data).
El código siguiente muestra cómo utilizar cifrado AesGcm para cifrar y descifrar datos aleatorios.
using System;
using System.Linq;
using System.Security.Cryptography;

namespace whats_new
{
public static class Cipher
{
public static void Run()
{
// key should be: pre-known, derived, or transported via another channel, such as RSA encryption
byte[] key = new byte[16];
RandomNumberGenerator.Fill(key);

byte[] nonce = new byte[12];


RandomNumberGenerator.Fill(nonce);

// normally this would be your data


byte[] dataToEncrypt = new byte[1234];
byte[] associatedData = new byte[333];
RandomNumberGenerator.Fill(dataToEncrypt);
RandomNumberGenerator.Fill(associatedData);

// these will be filled during the encryption


byte[] tag = new byte[16];
byte[] ciphertext = new byte[dataToEncrypt.Length];

using (AesGcm aesGcm = new AesGcm(key))


{
aesGcm.Encrypt(nonce, dataToEncrypt, ciphertext, tag, associatedData);
}

// tag, nonce, ciphertext, associatedData should be sent to the other part

byte[] decryptedData = new byte[ciphertext.Length];

using (AesGcm aesGcm = new AesGcm(key))


{
aesGcm.Decrypt(nonce, ciphertext, tag, decryptedData, associatedData);
}

// do something with the data


// this should always print that data is the same
Console.WriteLine($"AES-GCM: Decrypted data is {(dataToEncrypt.SequenceEqual(decryptedData) ? "the
same as" : "different than")} original data.");
}
}
}

Importación y exportación de claves criptográfica


.NET Core 3.0 admite la importación y exportación de claves asimétricas públicas y privadas en formatos estándar.
No es necesario utilizar un certificado X.509.
Todos los tipos de clave, como RSA, DSA, ECDsa y ECDiffieHellman, admiten los siguientes formatos:
Clave pública
SubjectPublicKeyInfo X.509
Clave privada
PrivateKeyInfo PKCS#8
EncryptedPrivateKeyInfo PKCS#8
Las claves RSA también admiten:
Clave pública
RSAPublicKey PKCS#1
Clave privada
RSAPrivateKey PKCS#1
Los métodos de exportación generan datos binarios con codificación DER y los métodos de importación esperan
lo mismo. Si una clave se almacena en el formato PEM de texto descriptivo, el llamador debe descodificar en
base64 el contenido antes de llamar a un método de importación.

using System;
using System.Security.Cryptography;

namespace whats_new
{
public static class RSATest
{
public static void Run(string keyFile)
{
using var rsa = RSA.Create();

byte[] keyBytes = System.IO.File.ReadAllBytes(keyFile);


rsa.ImportRSAPrivateKey(keyBytes, out int bytesRead);

Console.WriteLine($"Read {bytesRead} bytes, {keyBytes.Length - bytesRead} extra byte(s) in file.");


RSAParameters rsaParameters = rsa.ExportParameters(true);
Console.WriteLine(BitConverter.ToString(rsaParameters.D));
}
}
}

Los archivos PKCS#8 se pueden inspeccionar con System.Security.Cryptography.Pkcs.Pkcs8PrivateKeyInfo y los


archivos PFX/PKCS#12 se pueden inspeccionar con System.Security.Cryptography.Pkcs.Pkcs12Info. Los archivos
PFX/PKCS#12 se pueden manipular con System.Security.Cryptography.Pkcs.Pkcs12Builder.

Cambios de API en .NET Core 3.0


Rangos e índices
El nuevo tipo System.Index se puede utilizar para la indización. Puede crear uno desde un índice int que cuente
desde el principio o con un operador ^ de prefijo (C#) que cuente desde el final:

Index i1 = 3; // number 3 from beginning


Index i2 = ^4; // number 4 from end
int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"

Existe también el tipo System.Range, que consta de dos valores Index , uno para el inicio y otro para el final, y se
puede escribir con una expresión de intervalo x..y (C#). Luego puede crear un índice con un Range , lo que
genera un segmento:

var slice = a[i1..i2]; // { 3, 4, 5 }

Para obtener más información, vea el tutorial sobre intervalos e índices.


Flujos asincrónicos
El tipo IAsyncEnumerable<T> es una nueva versión asincrónica de IEnumerable<T>. El lenguaje permite ejecutar
la instrucción await foreach en IAsyncEnumerable<T> para consumir sus elementos, y usar la instrucción
yield return en ellos para generar los elementos.
En el ejemplo siguiente se muestra la producción y el consumo de flujos asincrónicos. La instrucción foreach es
asincrónica y usa yield return para generar un flujo asincrónico para los llamadores. Este patrón (que usa
yield return ) es el modelo recomendado para generar flujos asincrónicos.

async IAsyncEnumerable<int> GetBigResultsAsync()


{
await foreach (var result in GetResultsAsync())
{
if (result > 20) yield return result;
}
}

Además de poder ejecutar await foreach , también puede crear iteradores asincrónicos, por ejemplo, uno que
devuelva un enumerador IAsyncEnumerable/IAsyncEnumerator en el que pueda ejecutar await y yield . Para los
objetos que deban eliminarse, puede usar IAsyncDisposable , que implementan varios tipos BCL, como Stream y
Timer .

Para obtener más información, vea el tutorial sobre flujos asincrónicos.


Punto flotante de IEEE
Las API de punto flotante se actualizan para cumplir con la revisión IEEE 754-2008. El objetivo de estos cambios es
exponer todas operaciones requeridas y asegurarse de que cumplen con la especificación IEEE. Para obtener más
información sobre las mejoras de punto flotante, vea la entrada de blog sobre mejoras de formato y análisis de
punto flotante en .NET Core 3.0.
Entre las correcciones de análisis y formato se incluyen:
Analice y redondee entradas de cualquier longitud correctamente.
Analice y formatee el cero negativo correctamente.
Análisis correcto de Infinity y NaN al hacer una comprobación que no distingue mayúsculas de minúsculas y
permitir un + anterior opcional cuando corresponda.
Entre las nuevas API System.Math se incluyen:
BitIncrement(Double) y BitDecrement(Double)
Corresponde a las operaciones IEEE nextUp y nextDown . Devuelven el número de punto flotante más
pequeño que compara mayor o menor que la entrada (respectivamente). Por ejemplo,
Math.BitIncrement(0.0) devolvería double.Epsilon .

MaxMagnitude(Double, Double) y MinMagnitude(Double, Double)


Corresponde a las operaciones IEEE maxNumMag y minNumMag , que devuelven el valor que es mayor o menor
en magnitud de las dos entradas (respectivamente). Por ejemplo, Math.MaxMagnitude(2.0, -3.0) devolvería
-3.0 .

ILogB (Double)
Corresponde a la operación IEEE logB que devuelve un valor entero, devuelve el logaritmo en base 2
integral del parámetro de entrada. Este método es efectivamente el mismo que floor(log2(x)) , pero con
errores de redondeo mínimo.
ScaleB (Double, Int32)
Corresponde a la operación IEEE scaleB que toma un valor integral, devuelve eficazmente x * pow(2, n) ,
pero se realiza con errores de redondeo mínimo.
Log2(Double)
Corresponde a la operación IEEE log2 . Devuelve el logaritmo de base 2. Minimiza el error de redondeo.
FusedMultiplyAdd(Double, Double, Double)
Corresponde a la operación IEEE fma . Realiza una multiplicación y suma fusionadas. Es decir, realiza
(x * y) + z como operación única, de forma que se minimiza el error de redondeo. Un ejemplo sería
FusedMultiplyAdd(1e308, 2.0, -1e308) , que devuelve 1e308 . La operación (1e308 * 2.0) - 1e308 regular
devuelve double.PositiveInfinity .
CopySign(Double, Double)
Corresponde a la operación IEEE copySign . Devuelve el valor de x , pero con el signo de y .
Elementos intrínsecos dependientes de la plataforma .NET
Se han agregado API que permiten el acceso a determinadas instrucciones CPU orientadas al rendimiento, como
los conjuntos de instrucciones de manipulación de bits o SIMD. Estas instrucciones pueden ayudar a
conseguir importantes mejoras de rendimiento en ciertos escenarios, como el procesamiento de datos con
eficiencia en paralelo.
En su caso, las bibliotecas de .NET han comenzado a utilizar estas instrucciones para mejorar el rendimiento.
Para obtener más información, vea el artículo sobre elementos intrínsecos dependientes de la plataforma .NET.
API de versión mejoradas de .NET Core
A partir de .NET Core 3.0, las API de versión incluidas con .NET Core ahora devuelven la información que se
espera. Por ejemplo:

System.Console.WriteLine($"Environment.Version: {System.Environment.Version}");

// Old result
// Environment.Version: 4.0.30319.42000
//
// New result
// Environment.Version: 3.0.0

System.Console.WriteLine($"RuntimeInformation.FrameworkDescription:
{System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");

// Old result
// RuntimeInformation.FrameworkDescription: .NET Core 4.6.27415.71
//
// New result (notice the value includes any preview release information)
// RuntimeInformation.FrameworkDescription: .NET Core 3.0.0-preview4-27615-11

WARNING
Cambio importante. Se trata técnicamente de un cambio importante, porque ha cambiado el esquema de control de
versiones.

Compatibilidad con JSON integrada con rápido rendimiento


Los usuarios de .NET han contado en gran medida en Json.NET y otras bibliotecas populares de JSON, que
siguen siendo buenas opciones. Json.NET utiliza cadenas de .NET como tipo de datos base, que, en esencia, es
UTF -16.
La nueva compatibilidad con JSON integrada es el alto rendimiento, una baja asignación y se basa en Span<byte> .
Para obtener más información sobre el espacio de nombres y los tipos de System.Text.Json, vea Serialización de
JSON en .NET: Introducción. Para obtener tutoriales sobre escenarios comunes de serialización de JSON, vea
Procedimientos para serializar y deserializar JSON en .NET.
Compatibilidad con HTTP/2
El tipo System.Net.Http.HttpClient es compatible con el protocolo HTTP/2. Si se habilita HTTP/2, la versión del
protocolo HTTP se negocia a través de TLS/ALPN y HTTP/2 solo se usa si el servidor opta por usarlo.
El protocolo predeterminado sigue siendo HTTP/1.1, pero se puede habilitar HTTP/2 de dos maneras diferentes.
En primer lugar, puede establecer el mensaje de solicitud HTTP para usar HTTP/2:

var client = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };

// HTTP/1.1 request
using (var response = await client.GetAsync("/"))
Console.WriteLine(response.Content);

// HTTP/2 request
using (var request = new HttpRequestMessage(HttpMethod.Get, "/") { Version = new Version(2, 0) })
using (var response = await client.SendAsync(request))
Console.WriteLine(response.Content);

En segundo lugar, puede cambiar HttpClient para usar HTTP/2 de forma predeterminada:

var client = new HttpClient()


{
BaseAddress = new Uri("https://localhost:5001"),
DefaultRequestVersion = new Version(2, 0)
};

// HTTP/2 is default
using (var response = await client.GetAsync("/"))
Console.WriteLine(response.Content);

Muchas veces cuando está desarrollando una aplicación, desea utilizar una conexión no cifrada. Si sabe que el
punto de conexión de destino utilizará HTTP/2, puede activar las conexiones no cifradas para HTTP/2. Puede
activarlas estableciendo la variable de entorno DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2UNENCRYPTEDSUPPORT
en 1 o habilitándolas en el contexto de la aplicación:

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

Pasos siguientes
Revise los cambios importantes entre .NET Core 2.2 y 3.0.
Revise los cambios importantes entre .NET Framework y .NET Core 3.0 para aplicaciones de Windows Forms.
Novedades de .NET Core 2.2
04/11/2019 • 8 minutes to read • Edit Online

.NET Core 2.2 incluye mejoras en la implementación de aplicaciones, en el control de eventos de los servicios en
tiempo de ejecución, en la autenticación de bases de datos SQL de Azure, en el rendimiento del compilador JIT y la
inyección de código antes de la ejecución del método Main .

Nuevo modo de implementación


A partir de .NET Core 2.2, puede implementar archivos ejecutables dependientes del marco, que son archivos .exe
en lugar de .dll. Los archivos ejecutable dependientes del marco (FDE ), que funcionan de forma similar a las
implementaciones dependientes del marco, todavía se basan en la presencia de una versión compartida por todo el
sistema de .NET Core para ejecutar. Su aplicación contiene solo el código y cualquier dependencia de terceros. A
diferencia de las implementaciones dependientes del marco, los FDE son específicos de la plataforma.
Este nuevo modo de implementación tiene la ventaja de compilar un archivo ejecutable en lugar de una biblioteca,
lo que significa que puede ejecutar la aplicación directamente sin invocar dotnet primero.

Principal
Control de eventos en los servicios en tiempo de ejecución
A menudo es posible que desee supervisar el uso que hace la aplicación de los servicios de tiempo de ejecución,
como GC, JIT y ThreadPool, para comprender cómo afectan a la aplicación. En los sistemas Windows, esto se hace
normalmente mediante la supervisión de los eventos ETW del proceso actual. Aunque este método sigue
funcionando bien, no siempre es posible usar ETW si la ejecución se realiza en un entorno con pocos privilegios o
en Linux o macOS.
A partir de .NET Core 2.2, ahora se pueden consumir eventos CoreCLR utilizando la clase
System.Diagnostics.Tracing.EventListener. Estos eventos describen el comportamiento de esos servicios en tiempo
de ejecución como la interoperabilidad, ThreadPool, JIT y GC. Estos son los mismos eventos que se exponen como
parte del proveedor ETW de CoreCLR. De esta forma, las aplicaciones pueden consumir estos eventos o usar un
mecanismo de transporte para enviarlos a un servicio de agregación de telemetría. Puede ver cómo suscribirse a
eventos en el código de ejemplo siguiente:
internal sealed class SimpleEventListener : EventListener
{
// Called whenever an EventSource is created.
protected override void OnEventSourceCreated(EventSource eventSource)
{
// Watch for the .NET runtime EventSource and enable all of its events.
if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
{
EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(-1));
}
}

// Called whenever an event is written.


protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
// Write the contents of the event to the console.
Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name =
{eventData.EventName}");
for (int i = 0; i < eventData.Payload.Count; i++)
{
string payloadString = eventData.Payload[i]?.ToString() ?? string.Empty;
Console.WriteLine($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
}
Console.WriteLine("\n");
}
}

Además, .NET Core 2.2 agrega las dos propiedades siguientes a la clase EventWrittenEventArgs para proporcionar
información adicional sobre los eventos ETW:
EventWrittenEventArgs.OSThreadId
EventWrittenEventArgs.TimeStamp

Datos
Autenticación de AAD en bases de datos SQL de Azure con la propiedad SqlConnection.AccessToken
A partir de .NET Core 2.2, puede usarse un token de acceso emitido por Azure Active Directory para autenticarse
en una base de datos SQL de Azure. Para admitir tokens de acceso, la propiedad AccessToken se ha agregado a la
clase SqlConnection. Para aprovechar las ventajas de la autenticación de AAD, descargue la versión 4.6 del paquete
System.Data.SqlClient NuGet. Para poder usar la característica, puede obtener el valor del token de acceso
mediante la biblioteca de autenticación de Active Directory para .NET contenida en el paquete NuGet
Microsoft.IdentityModel.Clients.ActiveDirectory .

Mejoras del compilador JIT


La compilación en niveles sigue siendo una característica opcional
En .NET Core 2.1, el compilador JIT implementó una nueva tecnología de compilador, la compilación en niveles,
como característica opcional. El objetivo de la compilación en niveles es mejorar el rendimiento. Una de las tareas
importantes realizadas por el compilador JIT es optimizar la ejecución de código. Sin embargo, para las rutas de
código poco utilizadas, el compilador puede dedicar más tiempo a la optimización del código del que dedica el
tiempo de ejecución al ejecutar el código no optimizado. La compilación por niveles incluye dos fases en la
compilación JIT:
Un primer nivel, que genera código tan pronto como sea posible.
Un segundo nivel, que genera código optimizado para los métodos que se ejecutan con frecuencia. El
segundo nivel de la compilación se realiza en paralelo para mejorar el rendimiento.
Para obtener información sobre la mejora del rendimiento que puede obtenerse gracias a la compilación en
niveles, vea Announcing .NET Core 2.2 Preview 2 (Anuncio de la versión preliminar 2 de .NET Core 2.2).
En la versión preliminar 2 de .NET Core 2.2, la compilación en niveles se habilitó de forma predeterminada. Sin
embargo, hemos decidido que aún no estamos listos para habilitar la compilación en niveles de forma
predeterminada. Por tanto, en .NET Core 2.2, la compilación en nieves sigue siendo una característica opcional.
Para obtener información sobre cómo usar la compilación en niveles, vea Mejoras del compilador JIT en
Novedades de .NET Core 2.1.

Tiempo de ejecución
Inyección de código antes de ejecutar el método Main
A partir de .NET Core 2.2, puede usar un enlace de inicio para inyectar código antes de ejecutar el método Main de
la aplicación. Los enlaces de inicio permiten a un host personalizar el comportamiento de las aplicaciones una vez
que se hayan implementado sin necesidad de volver a compilar o cambiar la aplicación.
Los proveedores de hospedaje deberían definir la directiva y la configuración personalizadas, incluida la
configuración que posiblemente influya en el comportamiento de carga del punto de entrada principal, como el
comportamiento System.Runtime.Loader.AssemblyLoadContext . El enlace puede usarse para configurar la
inyección de telemetría o el seguimiento, configurar las devoluciones de llamada para el control, así como definir
otros comportamientos dependientes del entorno. El enlace es independiente del punto de entrada, por lo que no
es necesario modificar el código de usuario.
Consulte Host startup hook (Hospedaje del enlace de inicio) para obtener más información.

Vea también
Novedades de .NET Core
Novedades de ASP.NET Core 2.2
Novedades de EF Core 2.2
Novedades de .NET Core 2.1
04/11/2019 • 20 minutes to read • Edit Online

.NET Core 2.1 incluye mejoras y características nuevas en las áreas siguientes:
Herramientas
Puesta al día
Implementación
Paquete de compatibilidad de Windows
Mejoras de la compilación JIT
Cambios en la API

Tooling
El SDK de .NET Core 2.1 (v 2.1.300), el conjunto de herramientas incluidas con .NET Core 2.1, incluye los
siguientes cambios y mejoras:
Mejoras en el rendimiento de la compilación
Un aspecto fundamental de .NET Core 2.1 es mejorar el rendimiento del tiempo de compilación, especialmente
para compilaciones incrementales. Estas mejoras de rendimiento se aplican a las compilaciones de línea de
comandos mediante dotnet build y a las compilaciones de Visual Studio. Algunas áreas individuales de mejora
incluyen:
Para la resolución de activos del paquete, solo se resuelven los activos utilizados por una compilación en
lugar de todos los activos.
Almacenamiento en caché de referencias de ensamblado.
Uso de servidores de compilación de SDK de larga ejecución, que son procesos que se extienden a través
de invocaciones dotnet build individuales. Eliminan la necesidad de compilar mediante JIT grandes
bloques de código cada vez que se ejecuta dotnet build . Los procesos del servidor de compilación se
pueden terminar automáticamente con el siguiente comando:

dotnet buildserver shutdown

Nuevos comandos de la CLI


Una serie de herramientas que estaban disponibles solo en función del proyecto mediante
DotnetCliToolReference ahora están disponibles como parte del SDK de .NET Core. Estas herramientas incluyen:

dotnet watch proporciona un monitor del sistema de archivos que espera que un archivo cambie antes de
ejecutar un conjunto designado de comandos. Por ejemplo, el siguiente comando vuelve a generar
automáticamente el proyecto actual y genera un resultado detallado cada vez que cambie un archivo en él:

dotnet watch -- --verbose build

Tenga en cuenta que la opción -- precede a la opción --verbose . Delimita las opciones pasadas
directamente al comando dotnet watch de los argumentos que se pasan al proceso dotnet secundario.
Sin él, la opción --verbose se aplica al comando dotnet watch , no al comando dotnet build .
Para más información, consulte Desarrollar aplicaciones ASP.NET Core con un monitor de archivos.
dotnet dev-certs genera y administra los certificados que se usan durante el desarrollo de aplicaciones de
ASP.NET Core.
dotnet user-secrets administra los secretos en un almacén de secretos de usuario en aplicaciones de
ASP.NET Core.
dotnet sql-cachecrea una tabla e índices en una base de datos de Microsoft SQL Server que se usará para
el almacenamiento en caché distribuido.
dotnet ef es una herramienta para administrar bases de datos, objetos DbContext y migraciones en las
aplicaciones de Entity Framework Core. Para obtener más información, vea EF Core .NET Command-line
Tools (Herramienta de la línea de comandos de .NET de EF Core).
Herramientas globales
.NET core 2.1 es compatible con Herramientas globales: es decir, las herramientas personalizadas que están
disponibles globalmente desde la línea de comandos. El modelo de extensibilidad en versiones previas de .NET
Core permitió que las herramientas personalizadas estuvieran disponibles para cada proyecto solo utilizando
DotnetCliToolReference .

Para instalar una herramienta global, use el comando dotnet tool install. Por ejemplo:

dotnet tool install -g dotnetsay

Una vez instalada, la herramienta se puede ejecutar desde la línea de comandos especificando el nombre de la
herramienta. Para más información, vea Información general sobre las herramientas globales de .NET Core.
Administración de herramientas con el comando dotnet tool

En el SDK de .NET Core 2.1, todas las operaciones de herramientas utilizan el comando dotnet tool . Están
disponibles las siguientes opciones:
dotnet tool install para instalar una herramienta.
dotnet tool update para desinstalar y reinstalar una herramienta, lo cual la actualiza eficazmente.
dotnet tool list para enumerar las herramientas instaladas actualmente.
dotnet tool uninstall para desinstalar las herramientas instaladas actualmente.

Puesta al día
Todas las aplicaciones de .NET Core a partir de .NET Core 2.0 se ponen al día automáticamente a la versión
secundaria más reciente instalada en un sistema.
A partir de .NET Core 2.0, si la versión de .NET Core que se creó una aplicación no está presente en tiempo de
ejecución, la aplicación se ejecuta automáticamente en la versión secundaria instalada más reciente de .NET Core.
En otras palabras, si una aplicación se compila con .NET Core 2.0, y .NET Core 2.0 no está presente en el sistema
host pero sí lo está .NET Core 2.1, la aplicación se ejecuta con .NET Core 2.1.

IMPORTANT
Este comportamiento de puesta al día no se aplica para versiones preliminares. De forma predeterminada, tampoco se aplica
a las versiones principales, pero se puede cambiar con las opciones siguientes.

Este comportamiento se puede modificar si se cambia la configuración para la puesta al día en los marcos de
trabajo compartidos que no sean candidatos. Los valores disponibles son los siguientes:
0 : se deshabilita el comportamiento de puesta al día de las versiones secundarias. Con este valor, una
aplicación compilada para .NET Core 2.0.0 se pondrá al día a .NET Core 2.0.1, pero no a .NET Core 2.2.0 ni
.NET Core 3.0.0.
1 : se habilita el comportamiento de puesta al día de las versiones secundarias. Este es el valor
predeterminado de la opción. Con este valor, una aplicación compilada para .NET Core 2.0.0 se pondrá al día a
.NET Core 2.0.1 o .NET Core 2.2.0, en función de la versión instalada, pero no a .NET Core 3.0.0.
2 : se habilita el comportamiento de puesta al día de las versiones principales y secundarias. Si se establece, se
tienen en cuenta incluso versiones principales diferentes, por lo que una aplicación compilada para .NET Core
2.0.0 se pondrá al día a .NET Core 3.0.0.
Esta configuración se puede modificar de estas tres maneras:
Si se establece la variable de entorno DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX en el valor deseado.
Agregue la línea siguiente con el valor deseado al archivo .runtimeconfig.json:

"rollForwardOnNoCandidateFx" : 0

Cuando se usan herramientas de la CLI de .NET Core, si se agrega la opción siguiente con el valor deseado
a un comando de .NET Core como run :

dotnet run --rollForwardOnNoCandidateFx=0

La puesta al día de versiones de revisión es independiente de esta configuración y se realiza después de aplicar la
puesta al día de cualquier versión principal o secundaria posible.

Implementación
Mantenimiento de aplicaciones independientes
dotnet publish ahora publica aplicaciones independientes con una versión en tiempo de ejecución con
mantenimiento. Cuando publica una aplicación independiente con el SDK 2.1 de .NET Core (v. 2.1.300), su
aplicación incluye la última versión de tiempo de ejecución con mantenimiento conocida por ese SDK. Cuando
actualice a la versión más reciente del SDK, publicará con la versión más reciente del tiempo de ejecución de .NET
Core. Esto se aplica para tiempos de ejecución de .NET Core 1.0 y versiones posteriores.
La publicación independiente se basa en las versiones del tiempo de ejecución en NuGet.org. No necesita tener el
tiempo de ejecución con mantenimiento en su máquina.
Con el SDK de .NET Core 2.0, las aplicaciones independientes se publican con el tiempo de ejecución de .NET
Core 2.0.0 a menos que se especifique una versión diferente a través de la propiedad RuntimeFrameworkVersion .
Con este nuevo comportamiento, ya no será necesario configurar esta propiedad para seleccionar una versión de
tiempo de ejecución más alta para una aplicación independiente. El enfoque más sencillo a partir de ahora es
publicar siempre con el SDK de .NET Core 2.1 (v. 2.1.300).
Para obtener más información, vea Self-contained deployment runtime roll forward (Puesta al día de runtimes de
implementación independientes).

Paquete de compatibilidad de Windows


Al trasladar el código existente de .NET Framework a .NET Core, puede usar el paquete de compatibilidad de
Windows. Esto proporciona acceso a 20 000 API más de las que están disponibles en .NET Core. Estas API
incluyen tipos en el espacio de nombres System.Drawing, la clase EventLog, WMI, contadores de rendimiento,
servicios de Windows y los tipos y miembros de Registro de Windows.

Mejoras del compilador JIT


.NET Core incorpora una nueva tecnología de compilador JIT denominada compilación por niveles (también
conocida como optimización adaptable) que puede mejorar significativamente el rendimiento. La compilación por
niveles es una configuración opcional.
Una de las tareas importantes realizadas por el compilador JIT es optimizar la ejecución de código. Sin embargo,
para las rutas de código poco utilizadas, el compilador puede dedicar más tiempo a la optimización del código del
que dedica el tiempo de ejecución a ejecutar el código no optimizado. La compilación por niveles incluye dos fases
en la compilación JIT:
Un primer nivel, que genera código tan pronto como sea posible.
Un segundo nivel, que genera código optimizado para los métodos que se ejecutan con frecuencia. El
segundo nivel de la compilación se realiza en paralelo para mejorar el rendimiento.
Puede participar en la compilación en niveles de cualquiera de estas dos maneras.
Para utilizar la compilación en capas en todos los proyectos que utilizan el SDK de .NET Core 2.1,
establezca la variable de entorno siguiente:

COMPlus_TieredCompilation="1"

Para utilizar la compilación por niveles por proyecto, agregue la propiedad <TieredCompilation> a la
sección <PropertyGroup> del archivo de proyecto de MSBuild, como se muestra en el ejemplo siguiente:

<PropertyGroup>
<!-- other property definitions -->

<TieredCompilation>true</TieredCompilation>
</PropertyGroup>

Cambios en la API
Span<T> y Memory<T>

.NET Core 2.1 incluye algunos tipos nuevos que hacen que trabajar con matrices y otros tipos de memoria sea
mucho más eficiente. Estos nuevos tipos incluyen:
System.Span<T> y System.ReadOnlySpan<T>.
System.Memory<T> y System.ReadOnlyMemory<T>.
Sin estos tipos, al pasar tales elementos como una porción de una matriz o una sección de un búfer de memoria,
debe hacer una copia de una parte de los datos antes de pasarlo a un método. Estos tipos proporcionan una vista
virtual de los datos que elimina la necesidad de ejecutar operaciones adicionales de copia y asignación de
memoria.
En el ejemplo siguiente se usa una instancia de Span<T> y Memory<T> para proporcionar una vista virtual de 10
elementos de una matriz.
using System;

class Program
{
static void Main()
{
int[] numbers = new int[100];
for (int i = 0; i < 100; i++)
{
numbers[i] = i * 2;
}

var part = new Span<int>(numbers, start: 10, length: 10);


foreach (var value in part)
Console.Write($"{value} ");
}
}
// The example displays the following output:
// 20 22 24 26 28 30 32 34 36 38

Module Program
Sub Main()
Dim numbers As Integer() = New Integer(99) {}

For i As Integer = 0 To 99
numbers(i) = i * 2
Next

Dim part = New Memory(Of Integer)(numbers, start:=10, length:=10)

For Each value In part.Span


Console.Write($"{value} ")
Next
End Sub
End Module
' The example displays the following output:
' 20 22 24 26 28 30 32 34 36 38

Compresión de Brotli
.NET Core 2.1 agrega compatibilidad con la compresión y descompresión de Brotli. Brotli es un algoritmo de
compresión sin pérdida de datos de uso general que se define en RFC 7932 y es compatible con la mayoría de los
exploradores web y servidores web principales. Puede usar la clase System.IO.Compression.BrotliStream basada
en secuencias o las clases System.IO.Compression.BrotliEncoder y System.IO.Compression.BrotliDecoder basadas
en intervalos de alto rendimiento. En el ejemplo siguiente se muestra la compresión con la clase BrotliStream:

public static Stream DecompressWithBrotli(Stream toDecompress)


{
MemoryStream decompressedStream = new MemoryStream();
using (BrotliStream decompressionStream = new BrotliStream(toDecompress, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedStream);
}
decompressedStream.Position = 0;
return decompressedStream;
}
Public Function DecompressWithBrotli(toDecompress As Stream) As Stream
Dim decompressedStream As New MemoryStream()
Using decompressionStream As New BrotliStream(toDecompress, CompressionMode.Decompress)
decompressionStream.CopyTo(decompressedStream)
End Using
decompressedStream.Position = 0
Return decompressedStream
End Function

El comportamiento de BrotliStream es el mismo que DeflateStream y GZipStream, lo que facilita la conversión de


código que llama a estas API a BrotliStream.
Nuevas API de criptografía y mejoras de criptografía
.NET Core 2.1 incluye numerosas mejoras para las API de criptografía:
System.Security.Cryptography.Pkcs.SignedCms está disponible en el paquete
System.Security.Cryptography.Pkcs. La implementación es la misma que la clase SignedCms en .NET
Framework.
Las nuevas sobrecargas de los métodos X509Certificate.GetCertHash y X509Certificate.GetCertHashString
aceptan un identificador de algoritmo hash para permitir que los autores de la llamada obtengan valores de
huella digital de certificado utilizando algoritmos distintos de SHA-1.
Las nuevas API de criptografía basadas en Span<T> están disponibles para crear valores hash, HMAC,
generación de números aleatorios criptográficos, generación de firmas asimétricas, procesamiento de
firmas asimétricas y cifrado RSA.
El rendimiento de System.Security.Cryptography.Rfc2898DeriveBytes mejoró aproximadamente un 15 %
mediante el uso de una implementación basada en Span<T>.
La nueva clase System.Security.Cryptography.CryptographicOperations incluye dos nuevos métodos:
FixedTimeEquals tarda una cantidad fija de tiempo en devolver dos entradas cualesquiera de la
misma longitud, siendo así adecuada para su uso en la comprobación criptográfica para evitar
contribuir al control de tiempo de la información en el canal.
ZeroMemory es una rutina de borrado de memoria que no se puede optimizar.
El método estático RandomNumberGenerator.Fill rellena un Span<T> con valores aleatorios.
System.Security.Cryptography.Pkcs.EnvelopedCms ahora es compatible con Linux y macOS.
La curva elíptica Diffie-Hellman (ECDH) ahora está disponible en la familia de clases
System.Security.Cryptography.ECDiffieHellman. El área expuesta es la misma que en .NET Framework.
La instancia devuelta por RSA.Create puede cifrar o descifrar con OAEP con un resumen de SHA-2, así
como generar o validar firmas mediante RSA-PSS.
Mejoras en los sockets
.NET Core incluye un nuevo tipo, System.Net.Http.SocketsHttpHandler y una reescritura
System.Net.Http.HttpMessageHandler, que forman la base de las API de red de nivel superior.
System.Net.Http.SocketsHttpHandler, por ejemplo, es la base de la implementación HttpClient. En versiones
anteriores de .NET Core, las API de nivel superior se basaban en implementaciones de redes nativas.
La implementación de sockets introducida en .NET Core 2.1 presenta una serie de ventajas:
Una mejora significativa del rendimiento en comparación con la implementación anterior.
Eliminación de las dependencias de plataforma, lo que simplifica la implementación y el mantenimiento.
Comportamiento coherente en todas las plataformas de .NET Core.
SocketsHttpHandler es la implementación predeterminada en .NET Core 2.1. Sin embargo, puede configurar su
aplicación para usar la clase anterior HttpClientHandler llamando al método AppContext.SetSwitch:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", False)

También puede usar una variable de entorno para optar por no usar implementaciones de sockets basadas en
SocketsHttpHandler. Para ello, configure DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER en false o en 0.
En Windows, también puede optar por usar System.Net.Http.WinHttpHandler, que se basa en una
implementación nativa, o la clase SocketsHttpHandler pasando una instancia de la clase al constructor HttpClient.
En Linux y macOS, solo se puede configurar HttpClient para cada proceso. En Linux, deberá implementar libcurl si
desea usar la antigua implementación de HttpClient. (Se instala con .NET Core 2.0).

Vea también
Novedades de .NET Core
Novedades de EF Core 2.1
Novedades de ASP.NET Core 2.1
Novedades de .NET Core 2.0
12/12/2019 • 13 minutes to read • Edit Online

.NET Core 2.0 incluye mejoras y características nuevas en las áreas siguientes:
Herramientas
Compatibilidad con lenguajes
Mejoras en la plataforma
Cambios en la API
Integración de Visual Studio
Mejoras en la documentación

Tooling
dotnet restore se ejecuta de manera implícita
En las versiones anteriores de .NET Core, era necesario ejecutar el comando dotnet restore para descargar
dependencias inmediatamente después de crear un proyecto nuevo con el comando dotnet new, así como también
cada vez que se agregaba una dependencia nueva al proyecto.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

También puede deshabilitar la invocación automática de dotnet restore si pasa el modificador --no-restore a los
comandos new , run , build , publish , pack y test .
Redestinación a .NET Core 2.0
Si el SDK de .NET Core 2.0 SDK está instalado, los proyectos que tienen .NET Core 1.x como destino se pueden
redestinar a .NET Core 2.0.
Para redestinar a .NET Core 2.0, edite el archivo del proyecto cambiando el valor del elemento <TargetFramework>
(o del elemento <TargetFrameworks> , si tiene más de un destino en el archivo del proyecto) de 1.x a 2.0:

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

También puede redestinar las bibliotecas de .NET Standard a .NET Standard 2.0 del mismo modo:

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

Para más información sobre cómo migrar el proyecto a .NET Core 2.0, consulte el artículo sobre migración de
ASP.NET Core 1.x a ASP.NET Core 2.0.
Compatibilidad con lenguajes
Además de admitir C# y F#, .NET Core 2.0 también es compatible con Visual Basic.
Visual Basic
Con la versión 2.0, .NET Core ahora es compatible con Visual Basic 2017. Puede usar Visual Basic para crear los
tipos de proyecto siguientes:
Aplicaciones de consola .NET Core
Bibliotecas de clases .NET Core
Bibliotecas de clases .NET Standard
Proyectos de prueba unitaria .NET Core
Proyectos de prueba xUnit .NET Core
Por ejemplo, para crear una aplicación "Hola mundo" de Visual Basic, haga estos pasos en la línea de comandos:
1. En una ventana de la consola, cree un directorio para el proyecto y conviértalo en el directorio actual.
2. Escriba el comando dotnet new console -lang vb .
El comando crea un archivo del proyecto con una extensión de archivo .vbproj , además de un archivo de
código fuente de Visual Basic llamado Program.vb. Este archivo contiene el código fuente para escribir la
cadena "Hola mundo" en la ventana de consola.
3. Escriba el comando dotnet run . La CLI de .NET Core compila y ejecuta automáticamente la aplicación, con
lo que se muestra el mensaje "Hola mundo" en la ventana de la consola.
Compatibilidad con C# 7.1
.NET Core 2.0 es compatible con C# 7.1, que agrega varias características nuevas, entre las que se incluyen las
siguientes:
El método Main , el punto de entrada de la aplicación, se puede marcar con la palabra clave async.
Nombres de tupla deducidos.
Expresiones predeterminadas.

Mejoras en la plataforma
.NET Core 2.0 incluye varias características que facilitan la instalación de .NET Core y su uso en sistemas
operativos compatibles.
.NET Core para Linux es una sola implementación
.NET Core 2.0 ofrece una sola implementación de Linux que funciona en varias distribuciones de Linux. .NET Core
1.x requería que descargara una implementación de Linux específica para la distribución.
También puede desarrollar aplicaciones que tienen Linux como destino como un solo sistema operativo. .NET Core
1.x requería que se tuviera cada distribución de Linux como destino de forma independiente.
Compatibilidad con las bibliotecas de cifrado de Apple
.NET Core 1.x en macOS requería la biblioteca de cifrado del kit de herramientas OpenSSL. .NET Core 2.0 usa las
bibliotecas de cifrado de Apple y no requiere OpenSSL, por lo que ya no es necesario instalarlo.

Cambios en la API y compatibilidad con bibliotecas


Compatibilidad con .NET Standard 2.0
.NET Standard define un conjunto de API con control de versiones que debe estar disponible en las
implementaciones de .NET que cumplen con esa versión del estándar. .NET Standard está dirigido a los
desarrolladores de bibliotecas. Pretende garantizar la funcionalidad que está disponible a una biblioteca que tiene
como destino una versión de .NET Standard en cada implementación de .NET. .NET Core 1.x es compatible con la
versión 1.6 de .NET Standard; .NET Core 2.0 es compatible con la versión más reciente, .NET Standard 2.0. Para
más información, consulte .NET Standard.
.NET Standard 2.0 incluye más de 20 000 API más que las disponibles en .NET Standard 1.6. Gran parte de esta
área expuesta expandida es resultado de la incorporación de las API comunes de .NET Framework y Xamarin en
.NET Standard.
Las bibliotecas de clases .NET Standard 2.0 también pueden hacer referencia a bibliotecas de clases .NET
Framework siempre que llamen a las API que existen en .NET Standard 2.0. No es necesario realizar una nueva
compilación de las bibliotecas .NET Framework.
Si desea ver una lista de las API que se agregaron a .NET Standard desde la última versión, .NET Standard 1.6,
consulte el artículo de comparación entre .NET Standard 2.0 y 1.6.
Área expuesta expandida
La cantidad total de API disponibles en .NET Core 2.0 aumentó más del doble en comparación con .NET Core 1.1.
Además, con el paquete de compatibilidad de Windows, la migración desde .NET Framework ahora es mucho más
fácil.
Compatibilidad con las bibliotecas .NET Framework
El código de .NET Core puede hacer referencia a bibliotecas .NET Framework existentes, incluidos paquetes NuGet
existentes. Tenga en cuenta que las bibliotecas deben usar las API que se encuentran en .NET Standard.

integración de Visual Studio


Visual Studio 2017 versión 15.3 y, en algunos casos, Visual Studio para Mac, ofrecen varias mejoras importantes
para los desarrolladores de .NET Core.
Redestinación de aplicaciones .NET Core y bibliotecas .NET Standard
Si el SDK de .NET Core 2.0 SDK está instalado, puede redestinar los proyectos de .NET Core 1.x a .NET Core 2.0 y
las bibliotecas .NET Standard 1.x a .NET Standard 2.0.
Para redestinar el proyecto en Visual Studio, abra la pestaña Aplicación del cuadro de diálogo de propiedades del
proyecto y cambie el valor de plataforma de destino a .NET Core 2.0 o .NET Standard 2.0. También puede
cambiarlo si hace clic con el botón derecho en el proyecto y selecciona la opción Edit *.csproj file (Editar archivo
.csproj). Para más información, consulte la sección Herramientas anteriormente en este tema.
Compatibilidad con Live Unit Testing en .NET Core
Cada vez que modifique el código, Live Unit Testing ejecuta automáticamente y en segundo plano cualquier prueba
unitaria afectada y presenta los resultados y la cobertura de código en vivo en el entorno de Visual Studio. .NET
Core 2.0 ahora admite Live Unit Testing. Anteriormente, Live Unit Testing solo estaba disponible para aplicaciones
.NET Framework.
Para obtener más información, consulte Live Unit Testing con Visual Studio y las preguntas más frecuentes de Live
Unit Testing.
Mejor compatibilidad con varias plataformas de destino
Si compila un proyecto para varias plataformas de destino, ahora puede seleccionar la plataforma de destino en el
menú de nivel superior. En la figura siguiente, un proyecto llamado SCD1 tiene como destino macOS X 10.11 (
osx.10.11-x64 ) de 64 bits y Windows 10/Windows Server 2016 ( win10-x64 ) de 64 bits. Puede seleccionar la
plataforma de destino antes de seleccionar el botón del proyecto, en este caso para ejecutar una compilación de
depuración.
Compatibilidad en paralelo con SDK de .NET Core
Ahora es posible instalar el SDK de .NET Core de manera independiente de Visual Studio. Esto permite que una
versión única de Visual Studio compile proyectos que tienen como destino distintas versiones de .NET Core.
Anteriormente, Visual Studio y el SDK de .NET Core estaban estrechamente relacionados; una versión específica
del SDK acompañaba a una versión específica de Visual Studio.

Mejoras en la documentación
Arquitectura de aplicación de .NET
Arquitectura de aplicación de .NET le permite acceder a un conjunto de libros electrónicos que ofrecen orientación,
procedimientos recomendados y aplicaciones de ejemplo cuando use .NET para compilar:
Microservicios y contenedores Docker
Aplicaciones web con ASP.NET
Aplicaciones móviles con Xamarin
Aplicaciones que se implementan en la nube con Azure

Vea también
Novedades de ASP.NET Core 2.0
Cambios que afectan a la compatibilidad
10/01/2020 • 28 minutes to read • Edit Online

A lo largo de su historia, .NET ha intentado mantener un alto nivel de compatibilidad de versión a versión y a
través de los sabores de .NET. Esto sigue siendo cierto para .NET Core. Aunque .NET Core se puede considerar
como una nueva tecnología que es independiente de .NET Framework, hay dos factores principales que limitan la
capacidad de .NET Core para desviarse de .NET Framework:
Un gran número de desarrolladores desarrollaron originalmente o continúan desarrollando aplicaciones
.NET Framework. Esperan un comportamiento coherente en las implementaciones de .NET.
Los proyectos de bibliotecas .NET Standard permiten a los desarrolladores crear bibliotecas dirigidas a las
API comunes compartidas por .NET Core y .NET Framework. Los desarrolladores esperan que una
biblioteca utilizada en una aplicación .NET Core se comporte de forma idéntica a la misma biblioteca
utilizada en una aplicación .NET Framework.
Junto con la compatibilidad entre las implementaciones de .NET, los desarrolladores esperan un alto nivel de
compatibilidad entre las versiones .NET Core. En particular, el código escrito para una versión anterior de .NET
Core debería funcionar sin problemas en una versión posterior de .NET Core. De hecho, muchos desarrolladores
esperan que las nuevas API que se encuentran en las versiones más recientes de .NET Core también sean
compatibles con las versiones preliminares en las que se introdujeron dichas API.
En este artículo se describen las categorías de cambios de compatibilidad (o cambios importantes) y la forma en
que el equipo de .NET evalúa los cambios en cada una de estas categorías. Entender cómo el equipo de .NET
aborda los posibles cambios importantes es particularmente útil para los desarrolladores que abren solicitudes de
incorporación de cambios en el repositorio de GitHub dotnet/runtime que tienen por objetivo modificar el
comportamiento de las API existentes.

NOTE
Para una definición de las categorías de compatibilidad, como la compatibilidad binaria y la compatibilidad con versiones
anteriores, consulte Breaking change categories (Categorías de cambios importantes).

En las secciones siguientes se describen las categorías de los cambios realizados en las API de .NET Core y su
impacto sobre la compatibilidad de aplicaciones. El icono ✔ indica que se permite un determinado tipo de
cambio, indica que no se permite y indica un cambio que puede permitirse o no. Los cambios en esta última
categoría requieren un criterio y una evaluación de cuán predecible, obvio y coherente era el comportamiento
anterior.

NOTE
Además de servir como guía para evaluar los cambios en las bibliotecas .NET Core, los desarrolladores de bibliotecas también
pueden utilizar estos criterios para evaluar los cambios en sus bibliotecas que tienen como objetivo varias implementaciones y
versiones de .NET.

Modificaciones en el contrato público


Los cambios en esta categoría modifican el área expuesta pública de un tipo. No están permitidos la mayoría de los
cambios en esta categoría ya que infringen la compatibilidad con versiones anteriores (la capacidad de una
aplicación que se ha desarrollado con una versión anterior de una API para ejecutarse sin recompilación en una
versión posterior).
Tipos
✔ Supresión de una implementación de interfaz de un tipo cuando la interfaz ya está
implementada por un tipo base
Adición de una nueva implementación de interfaz a un tipo
Este es un cambio aceptable porque no afecta negativamente a los clientes existentes. Cualquier cambio en
el tipo debe funcionar dentro de los límites de los cambios aceptables definidos aquí para que la nueva
implementación siga siendo aceptable. Es necesario extremar las precauciones cuando se agregan interfaces
que afectan directamente a la capacidad de un diseñador o serializador para generar código o datos que no
se pueden consumir a un nivel inferior. Un ejemplo es la interfaz ISerializable.
Introducción a una nueva clase base
Un tipo puede introducirse en una jerarquía entre dos tipos existentes si no introduce nuevos miembros de
tipo abstract ni cambia la semántica o el comportamiento de los tipos existentes. Por ejemplo, en .NET
Framework 2.0, la clase DbConnection se ha convertido en una nueva clase base para SqlConnection, que
anteriormente había derivado directamente de Component.
✔ Traslado de un tipo de un ensamblado a otro
Tenga en cuenta que el ensamblado anterior debe estar marcado con TypeForwardedToAttribute que indica
el nuevo ensamblado.
✔ Cambio de un tipo struct a un tipo readonly struct

Tenga en cuenta que no se permite cambiar un tipo readonly struct a un tipo struct .
✔ Adición de la palabra clave sealed o abstract a un tipo cuando hay ningún constructor
accesible (público o protegido)
✔ Expansión de la visibilidad de un tipo
Cambio del espacio de nombres o del nombre de un tipo
Cambio de nombre o eliminación de un tipo público
Esto interrumpe todo el código que utiliza el tipo cuyo nombre se ha cambiado o quitado.
Cambio del tipo subyacente de una enumeración
Se trata de un cambio importante en tiempo de compilación y de comportamiento, así como de un cambio
importante binario que puede hacer que los argumentos de atributos no se puedan analizar.
Sellado de un tipo anteriormente no estaba sellado
Adición de una interfaz al conjunto de tipos base de una interfaz
Si una interfaz implementa una interfaz que antes no se implementaba, todos los tipos que implementaron
la versión original de la interfaz se interrumpen.
Eliminación de una clase del conjunto de clases base o una interfaz desde el conjunto de
interfaces implementadas
Hay una excepción a la regla para la eliminación de interfaces: puede agregar la implementación de una
interfaz que se derive de la interfaz eliminada. Por ejemplo, puede quitar IDisposable si el tipo o interfaz
ahora implementa IComponent, que implementa IDisposable.
Cambio de un tipo readonly struct a un tipo struct
Tenga en cuenta que se permite el cambio de un tipo struct a un tipo readonly struct .
Cambio de un tipo struct a un tipo ref struct y viceversa
Reducción de la visibilidad de un tipo
Sin embargo, se permite aumentar la visibilidad de un tipo.
Miembros
✔ Expansión de la visibilidad de un miembro que no es virtual

✔ Adición de un miembro de tipo abstract a un tipo público que no tiene ningún constructor
accesible (público o protegido) o el tipo sealed
Sin embargo, no se permite agregar un miembro de tipo abstract a un tipo que tenga constructores
accesibles (públicos o protegidos) y que no sea sealed .
✔ Restricción de la visibilidad de un miembro protegido cuando el tipo no tiene constructores
accesibles (públicos o protegidos) o el tipo es sellado .
✔ Desplazamiento de un miembro a una clase superior en la jerarquía que el tipo del que fue
eliminado
✔ Adición o eliminación de una invalidación
Tenga en cuenta que la introducción de una invalidación puede hacer que los consumidores anteriores
omitan la invalidación cuando llamen a la base.
✔ Adición de un constructor a una clase, junto con un constructor sin parámetros si la clase no
tenía previamente constructores
Sin embargo, no se permite agregar un constructor a una clase que antes no tenía constructores sin agregar
el constructor sin parámetros.
✔ Cambio de un miembro de tipo abstract a virtual
✔ Cambio de un valor devuelto ref readonly a un ref (excepto para los métodos o interfaces
virtuales)
✔ Eliminación de readonly desde un campo, a menos que el tipo estático del campo es un tipo
de valor mutable
✔ Llamada a un nuevo evento que no se ha definido anteriormente
Adición de un nuevo campo de instancia a un tipo
Este cambio afecta a la serialización.
Cambio de nombre o eliminación de un miembro o parámetro público
Esto interrumpe todo el código que utiliza el miembro o parámetro cuyo nombre se ha cambiado o quitado.
Tenga en cuenta que esto incluye el cambio de nombre o eliminación de un captador o establecedor de una
propiedad, así como el cambio de nombre o eliminación de los miembros de la enumeración.
Adición de un miembro a una interfaz
Cambio del valor de un miembro constante o de enumeración público
Cambio del tipo de una propiedad, campo, parámetro o valor devuelto
Adición, eliminación o cambio del orden de los parámetros
Adición o eliminación de la palabra clave in, out o ref en un parámetro
Cambio de nombre de un parámetro (incluido el cambio de mayúsculas y minúsculas)
Esto se considera importante por dos motivos:
Interrumpe los escenarios de enlace en tiempo de ejecución, como la característica de enlace en
tiempo de ejecución en Visual Basic y dinámica en C#.
Interrumpe la compatibilidad del origen cuando los desarrolladores utilizan los argumentos con
nombre.
Cambio de un valor ref devuelto a un valor ref readonly devuelto
Cambio de un valor ref readonly devuelto a un valor ref en una interfaz o método virtual
Adición o eliminación del tipo abstract de un miembro
Eliminación de la palabra clave virtual de un miembro
Aunque esto a menudo no es un cambio importante porque el compilador de C# tiende a emitir las
instrucciones de lenguaje intermedio (IL ) callvirt para llamar a métodos no virtuales ( callvirt realiza una
comprobación nula, mientras que una llamada normal no lo hace), este comportamiento no es invariable
por varias razones:
C# no es el único lenguaje al que se dirige .NET.
El compilador de C# intenta cada vez más optimizar callvirt para una llamada normal cuando el
método de destino no es virtual y probablemente no es nulo (como un método al que se accede a
través del operador de propagación nula ?).
Convertir un método en virtual significa que el código del consumidor a menudo acabaría llamándolo no
virtual.
Adición de la palabra clave virtual a un miembro
Conversión de un miembro virtual en tipo abstract
Un miembro virtual proporciona una implementación del método que se puede reemplazar por una clase
derivada. Un miembro abstract no proporciona ninguna implementación y debe ser reemplazado.
Adición de un miembro de tipo abstract a un tipo público que tiene constructores accesibles
(públicos o protegidos) y que no es de tipo sealed
Adición y eliminación de la palabra clave static de un miembro
Adición de una sobrecarga que impide una sobrecarga existente y define un comportamiento
diferente
Esto interrumpe a los clientes existentes que se enlazaron a la sobrecarga anterior. Por ejemplo, si una clase
tiene una versión única de un método que acepta un UInt32, un consumidor existente se enlazará
correctamente a esa sobrecarga al pasar un valor Int32. Sin embargo, si agrega una sobrecarga que acepte
un Int32, al volver a compilar o utilizar la característica de enlace en tiempo de ejecución, el compilador se
enlaza ahora a la nueva sobrecarga. Si se produce un comportamiento diferente, se trata de un cambio
importante.
Adición de un constructor a una clase que antes no tenía constructores sin agregar el constructor
sin parámetros
Adición de readonly a un campo
Reducción de la visibilidad de un miembro
Esto incluye la reducción de la visibilidad de un miembro protegido cuando hay constructores accesibles
(públicos o protegidos) y el tipo no es de tipo sealed. Si no es así, se permite reducir la visibilidad de un
miembro protegido.
Tenga en cuenta que se permite aumentar la visibilidad de un miembro.
Cambio del tipo de un miembro
El valor devuelto de un método o el tipo de propiedad o campo no se pueden modificar. Por ejemplo, la
firma de un método que devuelve un Object no se puede cambiar para devolver un String, o viceversa.
Adición de un campo a una estructura que previamente no tenía ningún estado
Las reglas de asignación definidas permiten el uso de variables no inicializadas siempre que el tipo de
variable sea una estructura sin estado. Si la estructura se realiza con estado, el código podría acabar con
datos sin inicializar. Esto es a la vez una posible interrupción del origen y un cambio importante de archivo
binario.
Desencadenamiento de un evento existente que nunca se desencadenó antes

Cambios de comportamiento
Ensamblados
✔ Portabilidad de un ensamblado cuando se siguen admitiendo las mismas plataformas

Cambio de nombre de un ensamblado


Cambio de la clave pública de un ensamblado
Propiedades, campos, parámetros y valores devueltos
✔ Cambio del valor de una propiedad, un campo, un valor devuelto o del parámetro out a un
tipo más derivado
Por ejemplo, un método que devuelve un tipo de Object puede devolver una instancia de String. (Sin
embargo, no se puede cambiar la firma del método).
✔ Aumento del intervalo de valores aceptados para una propiedad o parámetro si el miembro
no es virtual
Tenga en cuenta que mientras que el rango de valores que se pueden pasar al método o que se devuelven
por el miembro puede expandirse, el parámetro o tipo de miembro no pueden. Por ejemplo, mientras que
los valores pasados a un método pueden expandirse de 0-124 a 0-255, el tipo de parámetro no puede
cambiar de Byte a Int32.
Aumento del intervalo de valores aceptados para una propiedad o parámetro si el miembro es
virtual
Este cambio interrumpe los miembros invalidados existentes, que no funcionarán correctamente para la
gama extendida de valores.
Disminución del intervalo de valores aceptados para una propiedad o parámetro
Aumento del intervalo de valores devueltos para una propiedad, un campo, un valor devuelto o
el parámetro out
Cambio de los valores devueltos para una propiedad, un campo, un valor devuelto del método o
el parámetro out
Cambio del valor predeterminado de una propiedad, un campo o un parámetro
Cambio de la precisión de un valor devuelto numérico
Un cambio en el análisis de la entrada y el inicio de nuevas excepciones (incluso si el
comportamiento de análisis no está especificado en la documentación)
Excepciones
✔ Inicio de una excepción más derivada que una excepción existente

Debido a que la nueva excepción es una subclase de una excepción existente, el código de tratamiento de
excepciones anterior continúa controlando la excepción. Por ejemplo, en .NET Framework 4, los métodos de
creación y recuperación de la referencia cultural comenzaron a iniciar un CultureNotFoundException en
lugar de un ArgumentException si no se podía encontrar la referencia cultural. Dado que
CultureNotFoundException procede de ArgumentException, se trata de un cambio aceptable.
✔ Inicio de una excepción más específica que NotSupportedException,
NotImplementedException, NullReferenceException
✔ Inicio de una excepción que se considera irrecuperable
Las excepciones irrecuperables no deben capturarse, sino que deben tratarse por un controlador general de
alto nivel. Por lo tanto, no se espera que los usuarios tengan un código que capte estas excepciones
explícitas. Las excepciones irrecuperables son:
AccessViolationException
ExecutionEngineException
SEHException
StackOverflowException
✔ Inicio de una nueva excepción en una nueva ruta de acceso del código
La excepción debe aplicarse solo a una nueva ruta de acceso del código que se ejecute con nuevos valores o
estados de parámetros, y que no se pueda ejecutar por código existente que apunte a la versión anterior.
✔ Eliminación de una excepción para permitir un comportamiento más sólido o nuevos
escenarios
Por ejemplo, un método Divide que anteriormente solo trataba valores positivos e iniciaba un
ArgumentOutOfRangeException de lo contrario, puede cambiarse para admitir tanto valores negativos
como positivos sin iniciar una excepción.
✔ Cambio del texto de un mensaje de error
Los desarrolladores no deben confiar en el texto de los mensajes de error, que también cambian en función
de la referencia cultural del usuario.
Inicio de una excepción en cualquier otro caso no enumerado anteriormente
Eliminación de una excepción en cualquier otro caso no enumerado anteriormente
Atributos
✔ Cambio del valor de un atributo que no es observable

Cambio del valor de un atributo que es observable


Eliminación de un atributo
En la mayoría de los casos, la eliminación de un atributo (como NonSerializedAttribute) es un cambio
importante.
Compatibilidad con la plataforma
✔ Admisión de una operación en una plataforma que antes no era posible
No admitir o requerir ahora un Service Pack específico para una operación que antes estaba
admitida en una plataforma.

Cambios de implementación internos


Cambio del área expuesta de un tipo interno
Por lo general se permiten estos cambios, aunque interrumpan la reflexión privada. En algunos casos,
cuando las bibliotecas populares de terceros o un gran número de desarrolladores dependen de las API
internas, es posible que no se permitan dichos cambios.
Cambio de la implementación interna de un miembro
Por lo general se permiten estos cambios, aunque interrumpan la reflexión privada. En algunos casos,
cuando el código del cliente depende con frecuencia de una reflexión privada o cuando el cambio introduce
efectos secundarios no deseados, estos cambios pueden no estar permitidos.
✔ Mejora del rendimiento de una operación
La capacidad de modificar el rendimiento de una operación es esencial, pero tales cambios pueden
interrumpir el código que depende de la velocidad actual de una operación. Esto es particularmente cierto
en el caso del código que depende de la sincronización de las operaciones asincrónicas. Tenga en cuenta que
el cambio en el rendimiento no debería tener ningún efecto en otro comportamiento de la API en cuestión;
de lo contrario, el cambio se considerará importante.
✔ Modificación indirecta (y a menudo de forma adversa) del rendimiento de una operación
Si el cambio en cuestión no está clasificado como importante por algún otro motivo, esto es aceptable. A
menudo, es necesario tomar medidas que pueden incluir operaciones adicionales o que agregan nueva
funcionalidad. Esto casi siempre afectará al rendimiento, pero puede ser esencial para que la API en cuestión
funcione como se esperaba.
Cambio de una API sincrónica en asincrónica (y viceversa)

Cambios en el código
✔ Adición de params a un parámetro
Cambio de un tipo struct a un tipo class y viceversa
Adición de la palabra clave checked a un bloque de código
Este cambio puede causar que el código que se ejecutó previamente inicie un OverflowException y es
inaceptable.
Eliminación de params de un parámetro
Cambio del orden en el que se desencadenan los eventos
Los desarrolladores pueden esperar razonablemente que los eventos se desencadenen en el mismo orden, y
el código de desarrollador depende frecuentemente del orden en el que se desencadenen los eventos.
Eliminación del inicio de un evento en una acción determinada
Cambio del número de veces que se llaman los eventos dados
Adición de FlagsAttribute a un tipo de enumeración
Explore estos tutoriales para obtener información
sobre las herramientas de .NET Core y el SDK de
.NET Core
08/01/2020 • 2 minutes to read • Edit Online

Los siguientes tutoriales están disponibles para aprender sobre .NET Core.

Creación de aplicaciones con Visual Studio


Creación de una aplicación de consola Hola mundo
Depuración de la aplicación Hola mundo
Publicación de la aplicación Hola mundo
Compilación de una biblioteca de clases
Prueba de una biblioteca de clases
Uso de una biblioteca de clases
Azure Cosmos DB: Introducción a la API de SQL y .NET Core

Compilación de aplicaciones con Visual Studio Code


Introducción a C# y Visual Studio Code
Introducción a .NET Core en macOS

Compilación de aplicaciones con Visual Studio para Mac


Introducción a .NET Core en macOS con Visual Studio para Mac
Creación de una solución completa de .NET Core en macOS con Visual Studio para Mac

Creación de aplicaciones con las herramientas de la CLI de .NET Core


Introducción a .NET Core en Windows, Linux y macOS con las herramientas de CLI de .NET Core
Organización y prueba de proyectos con las herramientas de la CLI de .NET Core
Introducción a F#

Otros
Pruebas unitarias de .NET Core mediante pruebas de dotnet
Pruebas unitarias con MSTest y .NET Core
Desarrollo de bibliotecas con herramientas multiplataforma
Hospedaje de .NET Core desde código nativo
Creación de una plantilla personalizada para dotnet new
Para ver tutoriales sobre el desarrollo de aplicaciones web ASP.NET Core, vea la documentación de ASP.NET Core.
Tutorial: Creación de una plantilla de elemento
20/01/2020 • 10 minutes to read • Edit Online

Con .NET Core, puede crear e implementar plantillas que generan proyectos, archivos e inclusos recursos. Este
tutorial es el primero de una serie que enseña a crear, instalar y desinstalar plantillas para usarlas con el comando
dotnet new .

En esta parte de la serie, aprenderá a:


Crear una clase para una plantilla de elemento.
Crear el archivo y la carpeta de configuración de la plantilla.
Instalar una plantilla desde una ruta de acceso de archivo.
Probar una plantilla de elemento.
Desinstalar una plantilla de elemento.

Requisitos previos
SDK de .NET Core 2.2 o versiones posteriores.
Leer el artículo de referencia Plantillas personalizadas para dotnet new.
En el artículo de referencia se explican los aspectos básicos de las plantillas y cómo se unen. Parte de esta
información se repetirá en este tutorial.
Abra un terminal y vaya a la carpeta working\templates.

Creación de las carpetas necesarias


Esta serie usa una "carpeta de trabajo", donde se encuentra el origen de la plantilla, y una "carpeta de prueba" que
se usa para probar las plantillas. La carpeta de trabajo y la carpeta de prueba deben estar en la misma carpeta.
En primer lugar, cree la carpeta principal, no importa con qué nombre. Luego, cree una subcarpeta denominada
working (trabajo). Dentro de la carpeta working, cree una subcarpeta con el nombre templates (plantillas).
A continuación, cree una carpeta dentro de la carpeta principal con el nombre test (prueba). La estructura de
carpetas debe tener el siguiente aspecto:

parent_folder
├───test
└───working
└───templates

Creación de una plantilla de elemento


Una plantilla de elemento es un tipo de plantilla específico que contiene uno o varios archivos. Estos tipos de
plantillas son útiles cuando se quiere generar algún contenido como un archivo de solución, código o
configuración. En este ejemplo, creará una clase que agrega un método de extensión al tipo de cadena.
En el terminal, vaya a la carpeta working\templates y cree una subcarpeta llamada extensions. Entre a la carpeta.
working
└───templates
└───extensions

Cree un archivo nuevo denominado CommonExtensions.cs y ábralo con el editor de texto que prefiera. Esta clase
proporcionará un método de extensión denominado Reverse que invierte el contenido de una cadena. Pegue el
código siguiente y guarde el archivo:

using System;

namespace System
{
public static class StringExtensions
{
public static string Reverse(this string value)
{
var tempArray = value.ToCharArray();
Array.Reverse(tempArray);
return new string(tempArray);
}
}
}

Ahora que creó el contenido de la plantilla, debe crear su configuración en la carpeta raíz de la plantilla.

Creación de la configuración de una plantilla


En .NET Core, las plantillas se reconocen con una carpeta especial y un archivo de configuración que existen en la
raíz de la plantilla. En este tutorial, la carpeta de la plantilla se encuentra en working\templates\extensions.
Cuando se crea una plantilla, todos los archivos y las carpetas de la carpeta de la plantilla se incluyen como parte
de la plantilla, a excepción de la carpeta de configuración especial. Esta carpeta de configuración se denomina
.template.config.
En primer lugar, cree una subcarpeta con el nombre .template.config y entre en ella. Luego, cree un archivo
denominado template.json. La estructura de la carpeta debe verse así:

working
└───templates
└───extensions
└───.template.config
template.json

Abra template.json con el editor de texto que prefiera, pegue el código JSON siguiente y guárdelo:

{
"$schema": "http://json.schemastore.org/template",
"author": "Me",
"classifications": [ "Common", "Code" ],
"identity": "ExampleTemplate.StringExtensions",
"name": "Example templates: string extensions",
"shortName": "stringext",
"tags": {
"language": "C#",
"type": "item"
}
}
Este archivo de configuración contiene todos los valores de la plantilla. Puede ver los valores básicos, como name
y shortName , pero también hay un valor tags/type que está establecido en item . De este modo, la plantilla se
clasifica como una plantilla de elemento. No hay ninguna restricción en el tipo de plantilla que crea. Los valores
item y project son nombres comunes que .NET Core recomienda para que los usuarios puedan filtrar
fácilmente el tipo de plantilla que buscan.
El elemento classifications representa la columna tags que ve cuando ejecuta dotnet new y obtiene una lista
de plantillas. Los usuarios también pueden hacer una búsqueda según las etiquetas de clasificación. No confunda
la propiedad tags del archivo *.json con la lista de etiquetas classifications . Lamentablemente, son dos
elementos que tienen nombres similares. El esquema completo del archivo template.json puede encontrarse en el
Almacenamiento del esquema JSON. Para más información sobre el archivo template.json, consulte la wiki de
plantillas dotnet.
Ahora que tiene un archivo .template.config/template.json válido, la plantilla está lista para instalarla. En el
terminal, vaya a la carpeta extensions y ejecute el comando siguiente para instalar la plantilla ubicada en la
carpeta actual:
En Windows: dotnet new -i .\
En Linux o macOS: dotnet new -i ./

Este comando genera la lista de las plantillas instaladas, que debería incluir la suya.

C:\working\templates\extensions> dotnet new -i .\


Usage: new [options]

Options:
-h, --help Displays help for this command.
-l, --list Lists templates containing the specified name. If no name is specified, lists all
templates.

... cut to save space ...

Templates Short Name Language Tags


-------------------------------------------------------------------------------------------------------------
------------------
Example templates: string extensions stringext [C#] Common/Code
Console Application console [C#], F#, VB Common/Console
Class library classlib [C#], F#, VB Common/Library
WPF Application wpf [C#], VB Common/WPF
Windows Forms (WinForms) Application winforms [C#], VB Common/WinForms
Worker Service worker [C#] Common/Worker/Web

Prueba de la plantilla de elemento


Ahora que tiene instalada una plantilla de elemento, pruébela. Vaya a la carpeta test/ y cree una aplicación de
consola con dotnet new console . Esto genera un proyecto de trabajo que puede probar fácilmente con el
comando dotnet run .

C:\test> dotnet new console


The template "Console Application" was created successfully.

Processing post-creation actions...


Running 'dotnet restore' on C:\test\test.csproj...
Restore completed in 54.82 ms for C:\test\test.csproj.

Restore succeeded.
C:\test> dotnet run
Hello World!

Luego, ejecute dotnet new stringext para generar CommonExtensions.cs desde la plantilla.

C:\test> dotnet new stringext


The template "Example templates: string extensions" was created successfully.

Cambie el código en Program.cs para invertir la cadena "Hello World" con el método de extensión que se
proporciona en la plantilla.

Console.WriteLine("Hello World!".Reverse());

Vuelva a ejecutar el programa y verá que el resultado se invirtió.

C:\test> dotnet run


!dlroW olleH

¡ Enhorabuena! Ha creado e implementado una plantilla de elemento con .NET Core. Como preparación para la
próxima parte de esta serie de tutoriales, debe desinstalar la plantilla que creó. Asegúrese de eliminar también
todos los archivos de la carpeta test. Esto le permitirá volver a un estado limpio listo para la próxima sección
importante de este tutorial.

Desinstalación de la plantilla
Como instaló la plantilla a través de la ruta de acceso de archivo, debe desinstalarla con la ruta de acceso de
archivo absoluta. Ejecute el comando dotnet new -u para ver una lista de las plantillas instaladas. Su plantilla
debe aparecer en último lugar. Use la ruta de acceso mostrada para desinstalar la plantilla con el comando
dotnet new -u <ABSOLUTE PATH TO TEMPLATE DIRECTORY> .

C:\working> dotnet new -u


Template Instantiation Commands for .NET Core CLI

Currently installed items:


Microsoft.DotNet.Common.ItemTemplates
Templates:
dotnet gitignore file (gitignore)
global.json file (globaljson)
NuGet Config (nugetconfig)
Solution File (sln)
Dotnet local tool manifest file (tool-manifest)
Web Config (webconfig)

... cut to save space ...

NUnit3.DotNetNew.Template
Templates:
NUnit 3 Test Project (nunit) C#
NUnit 3 Test Item (nunit-test) C#
NUnit 3 Test Project (nunit) F#
NUnit 3 Test Item (nunit-test) F#
NUnit 3 Test Project (nunit) VB
NUnit 3 Test Item (nunit-test) VB
C:\working\templates\extensions
Templates:
Example templates: string extensions (stringext) C#
C:\working> dotnet new -u C:\working\templates\extensions

Pasos siguientes
En este tutorial, creó una plantilla de elemento. Para aprender a crear una plantilla de proyecto, siga con esta serie
de tutoriales.
Creación de una plantilla de proyecto
Tutorial: Creación de una plantilla de proyecto
20/01/2020 • 10 minutes to read • Edit Online

Con .NET Core, puede crear e implementar plantillas que generan proyectos, archivos e inclusos recursos. Este
tutorial es el segundo de una serie que enseña a crear, instalar y desinstalar plantillas para usarlas con el comando
dotnet new .

En esta parte de la serie, aprenderá a:


Crear los recursos de una plantilla de proyecto.
Crear el archivo y la carpeta de configuración de la plantilla.
Instalar una plantilla desde una ruta de acceso de archivo.
Probar una plantilla de elemento.
Desinstalar una plantilla de elemento.

Requisitos previos
Complete la parte 1 de esta serie de tutoriales.
Abra un terminal y vaya a la carpeta working\templates.

Creación de una plantilla de proyecto


Las plantillas de proyecto generan proyectos listos para ejecutarse que facilita a los usuarios empezar a trabajar
con un espacio de trabajo de código. .NET Core incluye algunas plantillas de proyecto, como una aplicación de
consola o una biblioteca de clases. En este ejemplo, creará un proyecto de consola nuevo que habilita C# 8.0 y
genera un punto de entrada async main .
En el terminal, vaya a la carpeta working\templates y cree una subcarpeta denominada consoleasync. Entre a la
subcarpeta y ejecute dotnet new console para generar la aplicación de consola estándar. Para crear una plantilla
nueva, tendrá que editar los archivos que genere esta plantilla.

working
└───templates
└───consoleasync
consoleasync.csproj
Program.cs

Modificación de Program.cs
Abra el archivo program.cs. El proyecto de la consola no usa un punto de entrada asincrónico, por lo que vamos a
agregarlo. Cambie el código por lo siguiente y guarde el archivo:
using System;
using System.Threading.Tasks;

namespace consoleasync
{
class Program
{
static async Task Main(string[] args)
{
await Console.Out.WriteAsync("Hello World with C# 8.0!");
}
}
}

Modificación de consoleasync.csproj
Actualicemos la versión del lenguaje C# que usa el proyecto a la versión 8.0. Edite el archivo consoleasync.csproj y
agregue el valor <LangVersion> a un nodo <PropertyGroup> .

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>

<LangVersion>8.0</LangVersion>

</PropertyGroup>

</Project>

Compilar el proyecto
Antes de completar una plantilla de proyecto, debe probarla para asegurarse de que se compila y ejecuta
correctamente. En el terminal, ejecute el comando dotnet run y debería ver la salida siguiente:

C:\working\templates\consoleasync> dotnet run


Hello World with C# 8.0!

Puede eliminar las carpetas obj y bin creadas si usa dotnet run . La eliminación de estos archivos garantizar que la
plantilla solo incluya los archivos relacionados con la plantilla y no cualquier archivo que resulte de una acción de
compilación.
Ahora que creó el contenido de la plantilla, debe crear su configuración en la carpeta raíz de la plantilla.

Creación de la configuración de una plantilla


En .NET Core, las plantillas se reconocen con una carpeta especial y un archivo de configuración que existen en la
raíz de la plantilla. En este tutorial, la carpeta de la plantilla se encuentra en working\templates\consoleasync.
Cuando se crea una plantilla, todos los archivos y las carpetas de la carpeta de la plantilla se incluyen como parte
de la plantilla, a excepción de la carpeta de configuración especial. Esta carpeta de configuración se denomina
.template.config.
En primer lugar, cree una subcarpeta con el nombre .template.config y entre en ella. Luego, cree un archivo
denominado template.json. La estructura de la carpeta debe verse así:
working
└───templates
└───consoleasync
└───.template.config
template.json

Abra template.json con el editor de texto que prefiera, pegue el código JSON siguiente y guárdelo:

{
"$schema": "http://json.schemastore.org/template",
"author": "Me",
"classifications": [ "Common", "Console", "C#8" ],
"identity": "ExampleTemplate.AsyncProject",
"name": "Example templates: async project",
"shortName": "consoleasync",
"tags": {
"language": "C#",
"type": "project"
}
}

Este archivo de configuración contiene todos los valores de la plantilla. Puede ver los valores básicos, como name
y shortName , pero también hay un valor tags/type que está establecido en project . Esto diseña la plantilla como
una plantilla de proyecto. No hay ninguna restricción en el tipo de plantilla que crea. Los valores item y project
son nombres comunes que .NET Core recomienda para que los usuarios puedan filtrar fácilmente el tipo de
plantilla que buscan.
El elemento classifications representa la columna tags que ve cuando ejecuta dotnet new y obtiene una lista
de plantillas. Los usuarios también pueden hacer una búsqueda según las etiquetas de clasificación. No confunda
la propiedad tags del archivo .json con la lista de etiquetas classifications . Lamentablemente, son dos
elementos que tienen nombres similares. El esquema completo del archivo template.json puede encontrarse en el
Almacenamiento del esquema JSON. Para más información sobre el archivo template.json, consulte la wiki de
plantillas dotnet.
Ahora que tiene un archivo .template.config/template.json válido, la plantilla está lista para instalarla. Antes de
instalar la plantilla, asegúrese de eliminar cualquier archivo o carpeta de archivos adicional que no quiere que se
incluya en la plantilla, como las carpetas bin o obj. En el terminal, vaya a la carpeta consoleasync y ejecute
dotnet new -i .\ para instalar la plantilla ubicada en la carpeta actual. Si usa un sistema operativo Linux o
MacOS, use una barra diagonal: dotnet new -i ./ .
Este comando genera la lista de las plantillas instaladas, que debería incluir la suya.
C:\working\templates\consoleasync> dotnet new -i .\
Usage: new [options]

Options:
-h, --help Displays help for this command.
-l, --list Lists templates containing the specified name. If no name is specified, lists all
templates.

... cut to save space ...

Templates Short Name Language Tags


--------------------------------------------------------------------------------------------------------------
-----------------
Console Application console [C#], F#, VB Common/Console
Example templates: async project consoleasync [C#] Common/Console/C#8
Class library classlib [C#], F#, VB Common/Library
WPF Application wpf [C#], VB Common/WPF
Windows Forms (WinForms) Application winforms [C#], VB Common/WinForms
Worker Service worker [C#] Common/Worker/Web

Prueba de la plantilla de proyecto


Ahora que tiene instalada una plantilla de elemento, pruébela. Vaya a la carpeta test/ y cree una aplicación de
consola con dotnet new consoleasync . Esto genera un proyecto de trabajo que puede probar fácilmente con el
comando dotnet run .

C:\test> dotnet new consoleasync


The template "Example templates: async project" was created successfully.

C:\test> dotnet run


Hello World with C# 8.0!

¡ Enhorabuena! Ha creado e implementado una plantilla de proyecto con .NET Core. Como preparación para la
próxima parte de esta serie de tutoriales, debe desinstalar la plantilla que creó. Asegúrese de eliminar también
todos los archivos de la carpeta test. Esto le permitirá volver a un estado limpio listo para la próxima sección
importante de este tutorial.
Desinstalación de la plantilla
Como instaló la plantilla a través de una ruta de acceso de archivo, debe desinstalarla con la ruta de acceso de
archivo absoluta. Ejecute el comando dotnet new -u para ver una lista de las plantillas instaladas. Su plantilla
debe aparecer en último lugar. Use la ruta de acceso mostrada para desinstalar la plantilla con el comando
dotnet new -u <ABSOLUTE PATH TO TEMPLATE DIRECTORY> .
C:\working> dotnet new -u
Template Instantiation Commands for .NET Core CLI

Currently installed items:


Microsoft.DotNet.Common.ItemTemplates
Templates:
dotnet gitignore file (gitignore)
global.json file (globaljson)
NuGet Config (nugetconfig)
Solution File (sln)
Dotnet local tool manifest file (tool-manifest)
Web Config (webconfig)

... cut to save space ...

NUnit3.DotNetNew.Template
Templates:
NUnit 3 Test Project (nunit) C#
NUnit 3 Test Item (nunit-test) C#
NUnit 3 Test Project (nunit) F#
NUnit 3 Test Item (nunit-test) F#
NUnit 3 Test Project (nunit) VB
NUnit 3 Test Item (nunit-test) VB
C:\working\templates\consoleasync
Templates:
Example templates: async project (consoleasync) C#

C:\working> dotnet new -u C:\working\templates\consoleasync

Pasos siguientes
En este tutorial creó una plantilla de proyecto. Para información sobre cómo empaquetar la plantilla de elemento y
la de proyecto en un archivo fácil de usar, continúe con esta serie de tutoriales.
Creación de un paquete de plantillas
Tutorial: Creación de un paquete de plantillas
20/01/2020 • 10 minutes to read • Edit Online

Con .NET Core, puede crear e implementar plantillas que generan proyectos, archivos e inclusos recursos. Este
tutorial es el tercero de una serie que enseña a crear, instalar y desinstalar plantillas para usarlas con el comando
dotnet new .

En esta parte de la serie, aprenderá a:


Crear un proyecto *.csproj para compilar un paquete de plantillas
Configurar el archivo del proyecto para el empaquetado.
Instalar una plantilla a partir de un archivo de paquete de NuGet.
Desinstalar una plantilla por el identificador del paquete.

Requisitos previos
Complete la parte 1 y la parte 2 de esta serie de tutoriales.
En este tutorial se usan las dos plantillas que se crearon en las dos primeras partes de este tutorial. Puede
usar otra plantilla siempre que la copie como una carpeta en la carpeta working\templates\ .
Abra un terminal y vaya a la carpeta working\ .

Creación de un proyecto de paquete de plantillas


Cuando se habla un paquete de plantillas, nos referimos a una o más plantillas empaquetadas en un archivo.
Cuando instala o desinstala un paquete, se agregan o quitan todas las plantillas del paquete, respectivamente. Las
partes anteriores de esta serie de tutoriales solo funcionan con plantillas individuales. Para compartir una plantilla
no empaquetada, tiene que copiar la carpeta de plantilla y realizar la instalación mediante esa carpeta. Como un
paquete de plantillas puede tener más de una plantilla y se trata de un solo archivo, compartirlo resulta sencillo.
Los paquetes de plantillas se representan con un archivo ( .nupkg) de paquete de NuGet. Y, al igual que lo que
ocurre con cualquier paquete de NuGet, puede cargar el paquete de plantillas a una fuente NuGet. El comando
dotnet new -i permite instalar un paquete de plantillas desde una fuente NuGet. Además, puede instalar un
paquete de plantillas directamente desde un archivo .nupkg.
Por lo general, se usa un archivo del proyecto de C# para compilar el código y generar un archivo binario. Pero el
proyecto también se puede usar para generar un paquete de plantillas. Si cambia la configuración del archivo
.csproj, puede impedir que compile código y, en su lugar, incluir todos los recursos de las plantillas como recursos.
Cuando se compila este proyecto, genera un paquete de NuGet de paquete de plantillas.
El paquete que va a crear incluirá la plantilla de elemento y la plantilla de paquete que creó anteriormente. Como
agrupamos ambas plantillas en la carpeta working\templates\ , podemos usar la carpeta working para el archivo
.csproj.
En el terminal, vaya a la carpeta working. Cree un proyecto nuevo y establezca el nombre en templatepack y la
carpeta de salida en la carpeta actual.

dotnet new console -n templatepack -o .

El parámetro -n establece el nombre del proyecto .csproj en templatepack.csproj y el parámetro -o crea los
archivos en el directorio actual. Verá un resultado similar a la salida siguiente.

C:\working> dotnet new console -n templatepack -o .


The template "Console Application" was created successfully.

Processing post-creation actions...


Running 'dotnet restore' on .\templatepack.csproj...
Restore completed in 52.38 ms for C:\working\templatepack.csproj.

Restore succeeded.

A continuación, abra el archivo templatepack.csproj en su editor favorito y reemplace el contenido por el XML
siguiente:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageType>Template</PackageType>
<PackageVersion>1.0</PackageVersion>
<PackageId>AdatumCorporation.Utility.Templates</PackageId>
<Title>AdatumCorporation Templates</Title>
<Authors>Me</Authors>
<Description>Templates to use when creating an application for Adatum Corporation.</Description>
<PackageTags>dotnet-new;templates;contoso</PackageTags>

<TargetFramework>netstandard2.0</TargetFramework>

<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
</PropertyGroup>

<ItemGroup>
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
<Compile Remove="**\*" />
</ItemGroup>

</Project>

El valor <PropertyGroup> del XML anterior se divide en tres grupos. El primer grupo trata con las propiedades
requeridas para un paquete de NuGet. Los tres valores <Package están relacionados con las propiedades del
paquete de NuGet para identificar el paquete en una fuente NuGet. En concreto, el valor <PacakgeId> se usa para
desinstalar el paquete de plantillas con un solo nombre en lugar de una ruta de acceso a un directorio. También se
puede usar para instalar el paquete de plantillas desde una fuente NuGet. Los valores restantes, como <Title> y
<Tags> , están relacionados con los metadatos que aparecen en la fuente NuGet. Para más información sobre la
configuración de NuGet, consulte el artículo sobre propiedades de NuGet y MSBuild.
La configuración <TargetFramework> se debe establecer de manera que MSBuild se ejecute correctamente al
ejecutar el comando pack para compilar y empaquetar el proyecto.
Los tres últimos valores están relacionados con la configuración correcta del proyecto para incluir las plantillas en
la carpeta correspondiente del paquete de NuGet cuando se crea.
<ItemGroup> contiene dos valores. En primer lugar, el valor <Content> incluye todo lo que hay en la carpeta
templates como contenido. También se establece para excluir cualquier carpeta bin o carpeta obj para evitar que se
incluya cualquier código compilado (si probó y compiló las plantillas). En segundo lugar, el valor <Compile>
excluye todos los archivos de código de la compilación, independientemente de dónde estén ubicados. Esto evita
que el proyecto que se usa para crear un paquete de plantillas intente compilar el código en la jerarquía de
carpetas templates.
Compilación e instalación
Guarde este archivo y, a continuación, ejecute el comando pack.

dotnet pack

Este comando compilará el proyecto y creará un paquete NuGet en la carpeta working\bin\Debug.

C:\working> dotnet pack


Microsoft (R) Build Engine version 16.2.0-preview-19278-01+d635043bd for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restore completed in 123.86 ms for C:\working\templatepack.csproj.

templatepack -> C:\working\bin\Debug\netstandard2.0\templatepack.dll


Successfully created package 'C:\working\bin\Debug\AdatumCorporation.Utility.Templates.1.0.0.nupkg'.

A continuación, instale el archivo del paquete de plantillas con el comando dotnet new -i PATH_TO_NUPKG_FILE .

C:\working> dotnet new -i C:\working\bin\Debug\AdatumCorporation.Utility.Templates.1.0.0.nupkg


Usage: new [options]

Options:
-h, --help Displays help for this command.
-l, --list Lists templates containing the specified name. If no name is specified, lists all
templates.

... cut to save space ...

Templates Short Name Language Tags


--------------------------------------------------------------------------------------------------------------
-----------------
Example templates: string extensions stringext [C#] Common/Code
Console Application console [C#], F#, VB Common/Console
Example templates: async project consoleasync [C#] Common/Console/C#8
Class library classlib [C#], F#, VB Common/Library

Si cargó el paquete de NuGet en una fuente NuGet, puede usar el comando dotnet new -i PACKAGEID , donde
PACKAGEID es igual que el valor <PackageId> del archivo .csproj. Este identificador de paquete es igual que el
identificador del paquete de NuGet.

Desinstalación del paquete de plantillas


Independientemente de cómo instaló el paquete de plantillas, ya sea directamente con el archivo .nupkg o
mediante la fuente NuGet, el proceso de quitar un paquete de plantillas es el mismo. Use el <PackageId> de la
plantilla que quiere desinstalar. Ejecute el comando dotnet new -u para ver una lista de las plantillas que están
instaladas.
C:\working> dotnet new -u
Template Instantiation Commands for .NET Core CLI

Currently installed items:


Microsoft.DotNet.Common.ItemTemplates
Templates:
dotnet gitignore file (gitignore)
global.json file (globaljson)
NuGet Config (nugetconfig)
Solution File (sln)
Dotnet local tool manifest file (tool-manifest)
Web Config (webconfig)

... cut to save space ...

NUnit3.DotNetNew.Template
Templates:
NUnit 3 Test Project (nunit) C#
NUnit 3 Test Item (nunit-test) C#
NUnit 3 Test Project (nunit) F#
NUnit 3 Test Item (nunit-test) F#
NUnit 3 Test Project (nunit) VB
NUnit 3 Test Item (nunit-test) VB
AdatumCorporation.Utility.Templates
Templates:
Example templates: async project (consoleasync) C#
Example templates: string extensions (stringext) C#

Ejecute dotnet new -u AdatumCorporation.Utility.Templates para desinstalar la plantilla. El comando dotnet new
generará información de ayuda sobre que debe omitir las plantillas que instaló previamente.
¡ Enhorabuena! Ya instaló y desinstaló un paquete de plantillas.

Pasos siguientes
Para más información sobre las plantillas, que en gran parte ya conoce, consulte el artículo Plantillas
personalizadas para dotnet new.
Wiki del repositorio de GitHub dotnet/templating
Repositorio de GitHub dotnet/dotnet-template-samples
Esquema template.json en el Almacenamiento del esquema JSON
Introducción a .NET Core en macOS con Visual
Studio para Mac
20/01/2020 • 4 minutes to read • Edit Online

Visual Studio para Mac proporciona un entorno de desarrollo integrado (IDE ) completo para el desarrollo de
aplicaciones .NET Core. Este artículo le guía en la creación de una aplicación de consola sencilla con Visual Studio
para Mac y .NET Core.

NOTE
Sus comentarios son muy importantes. Hay dos maneras de proporcionar comentarios al equipo de desarrollo de Visual
Studio para Mac:
En Visual Studio para Mac, seleccione Ayuda > Notificar un problema en el menú o Notificar un problema desde la
pantalla de bienvenida, que abre una ventana para presentar un informe de errores. Puede realizar un seguimiento de
sus comentarios en el portal de la Comunidad de desarrolladores.
Para hacer una sugerencia, seleccione Ayuda > Aportar una sugerencia en el menú o Aportar una sugerencia desde
la pantalla de bienvenida, que le lleva a la página web de la Comunidad de desarrolladores de Visual Studio para Mac.

Requisitos previos
Consulte el artículo Dependencias y requisitos de .NET Core.
Consulte el artículo Compatibilidad de .NET Core para asegurarse de que usa una versión compatible de .NET
Core.

Primeros pasos
Si ya ha instalado los requisitos previos y Visual Studio para Mac, omita esta sección y proceda con Creación de
un proyecto. Siga estos pasos para instalar los requisitos previos y Visual Studio para Mac:
Descargue el instalador de Visual Studio para Mac. Ejecute el instalador. Lea y acepte el contrato de licencia.
Durante la instalación, seleccione la opción de instalar .NET Core. Se le proporciona la oportunidad de instalar
Xamarin, una tecnología de desarrollo de aplicaciones móviles multiplataforma. La instalación de Xamarin y sus
componentes relacionados es opcional para el desarrollo de .NET Core. Para ver un tutorial del proceso de
instalación de Visual Studio para Mac, consulte la documentación de Visual Studio para Mac. Una vez completada
la instalación, inicie el IDE de Visual Studio para Mac.

Creación de un proyecto
1. Seleccione Nuevo en la ventana de inicio.
2. En el cuadro de diálogo Nuevo proyecto, seleccione Aplicación en el nodo .NET Core. Seleccione la
plantilla Aplicación de consola y haga clic en Siguiente.

3. Si tiene instalada más de una versión de .NET Core, seleccione el marco de destino del proyecto.
4. Escriba "HelloWorld" en Nombre de proyecto. Seleccione Crear.
5. Espere mientras se restauran las dependencias del proyecto. El proyecto tiene un único archivo de C#,
Program.cs, que contiene una clase Program con un método Main . La instrucción Console.WriteLine
genera la salida "¡ Hola a todos!" en la consola cuando se ejecuta la aplicación.

Ejecutar la aplicación
Ejecute la aplicación en modo de depuración con ⌘ ↵ (comando + ENTRAR ) o en modo de versión ⌘↵
(opción + comando + ENTRAR ).

Paso siguiente
El tema Creación de una solución completa de .NET Core en macOS con Visual Studio para Mac le muestra
cómo crear una solución completa de .NET Core que incluye una biblioteca reutilizable y pruebas unitarias.
Creación de una solución completa de .NET Core en
macOS con Visual Studio para Mac
20/01/2020 • 18 minutes to read • Edit Online

Visual Studio para Mac proporciona un entorno de desarrollo integrado (IDE ) completo para el desarrollo de
aplicaciones .NET Core. Este artículo le guía en la creación de una solución .NET Core que incluye una biblioteca
reutilizable y pruebas unitarias.
En este tutorial se muestra cómo crear una aplicación que acepte una palabra de búsqueda y una cadena de texto
del usuario, cuente el número de veces que la palabra de búsqueda aparece en la cadena utilizando un método en
una biblioteca de clases, y devuelva el resultado al usuario. La solución también incluye pruebas unitarias para la
biblioteca de clases como una introducción a los conceptos de pruebas unitarias. Si prefiere continuar usando el
tutorial con un ejemplo completo, descargue la solución de ejemplo. Para obtener instrucciones de descarga, vea
Ejemplos y tutoriales.

NOTE
Sus comentarios son muy importantes. Hay dos maneras de proporcionar comentarios al equipo de desarrollo de Visual
Studio para Mac:
En Visual Studio para Mac, seleccione Ayuda > Notificar un problema en el menú o Notificar un problema desde la
pantalla de bienvenida, que abre una ventana para presentar un informe de errores. Puede realizar un seguimiento de
sus comentarios en el portal de la Comunidad de desarrolladores.
Para hacer una sugerencia, seleccione Ayuda > Aportar una sugerencia en el menú o Aportar una sugerencia desde
la pantalla de bienvenida, que le lleva a la página web de la Comunidad de desarrolladores de Visual Studio para Mac.

Requisitos previos
SDK de .NET Core 3.1 o posterior
Visual Studio 2019 para Mac
Para obtener más información sobre los requisitos previos, vea Dependencias y requisitos de .NET Core. Para
consultar todos los requisitos del sistema de Visual Studio 2019 para Mac, vea Requisitos del sistema de la familia
de productos de Visual Studio 2019 para Mac.

Creación de una biblioteca


1. En la ventana de inicio, seleccione Nuevo proyecto. En el cuadro de diálogo Nuevo proyecto, en el nodo
.NET Core, seleccione la plantilla Biblioteca de .NET Standard. Este comando crea una biblioteca de
.NET Standard que tiene como destino .NET Core, así como cualquier otra implementación de .NET que
admite la versión 2.1 de .NET Standard. Si tiene varias versiones del SDK de .NET Core instaladas, puede
elegir diferentes versiones de .NET Standard para la biblioteca. Elija ".NET Standard 2.1" y seleccione
Siguiente.
2. Asigne al proyecto el nombre "TextUtils" (un nombre corto para "Text Utilities") y la solución
"WordCounter". Deje activada la opción Cree un directorio de proyecto dentro del directorio de la
solución. Seleccione Crear.

3. En el panel Solución, expanda el nodo TextUtils para mostrar el archivo de clase proporcionado por la
plantilla Class1.cs. Ctrl+clic en el archivo, seleccione Cambiar nombre en el menú contextual y
denomínelo WordCount.cs. Abra el archivo y reemplace el contenido por el código siguiente:
using System;
using System.Linq;

namespace TextUtils
{
public static class WordCount
{
public static int GetWordCount(string searchWord, string inputString)
{
// Null check these variables and determine if they have values.
if (string.IsNullOrEmpty(searchWord) || string.IsNullOrEmpty(inputString))
{
return 0;
}

// Convert the string into an array of words.


var source = inputString.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' },
StringSplitOptions.RemoveEmptyEntries);

// Create the query. Use ToLowerInvariant to match uppercase/lowercase strings.


var matchQuery = from word in source
where word.ToLowerInvariant() == searchWord.ToLowerInvariant()
select word;

// Count the matches, which executes the query. Return the result.
return matchQuery.Count();
}
}
}

4. Guarde el archivo mediante uno de estos tres métodos: use el método abreviado de teclado ⌘+s,
seleccione Archivo > Guardar en el menú o use Ctrl+clic en la pestaña del archivo y seleccione Guardar
en el menú contextual. La siguiente imagen muestra la ventana de IDE:

5. Seleccione Errores en el margen inferior de la ventana de IDE para abrir el panel Errores. Seleccione el
botón Salida de la compilación.
6. Seleccione Compilar > Compilar todo en el menú.
La solución se compila. El panel de salida de la compilación muestra que la compilación es correcta.

Creación de un proyecto de prueba


Las pruebas unitarias proporcionan pruebas de software automatizadas durante el desarrollo y la publicación. El
marco de pruebas que se utiliza en este tutorial es xUnit (versión 2.4.0 o una versión posterior), que se instala
automáticamente cuando el proyecto de prueba de xUnit se agrega a la solución en los pasos siguientes:
1. En la barra lateral Solución, use Ctrl+clic en la solución WordCounter y seleccione Agregar > Agregar
nuevo proyecto.
2. En el cuadro de diálogo Nuevo proyecto, seleccione Pruebas en el nodo .NET Core. Seleccione el
proyecto de prueba xUnit y haga clic en Siguiente.

3. Si tiene varias versiones del SDK de .NET Core, deberá seleccionar la versión para este proyecto.
Seleccione .NET Core 3.1. Asigne al nuevo proyecto el nombre "TestLibrary" y seleccione Crear.
4. Para que la biblioteca de prueba funcione con la clase WordCount , agregue una referencia al proyecto
TextUtils . En la barra lateral Solución, use Ctrl+clic en Dependencias en TestLibrary. Seleccione
Editar referencias en el menú contextual.
5. En el cuadro de diálogo Editar referencias, seleccione el proyecto TextUtils en la pestaña Proyectos.
Seleccione Aceptar.

6. En el proyecto TestLibrary, cambie el nombre del archivo UnitTest1.cs por TextUtilsTests.cs.


7. Abra el archivo y reemplace el código por el código siguiente:
using Xunit;
using TextUtils;
using System.Diagnostics;

namespace TestLibrary
{
public class TextUtils_GetWordCountShould
{
[Fact]
public void IgnoreCasing()
{
var wordCount = WordCount.GetWordCount("Jack", "Jack jack");

Assert.NotEqual(2, wordCount);
}
}
}

La siguiente imagen muestra el IDE con el código de prueba unitaria en su lugar. Preste atención a la
instrucción Assert.NotEqual .

Es importante que una prueba nueva no se supere por lo menos en una ocasión, ya que, de este modo, se
puede confirmar que su lógica de prueba es correcta. El método pasa el nombre "Jack" (en mayúsculas) y
una cadena con "Jack" y "jack" (mayúsculas y minúsculas). Si el método GetWordCount funciona
correctamente, devuelve un recuento de dos instancias de la palabra de búsqueda. Para que la prueba no se
supere a propósito, primero implementará la prueba afirmando que el método GetWordCount no devuelve
dos instancias de la palabra de búsqueda "Jack". Continúe con el paso siguiente para no superar la prueba
a propósito.
8. Abra el panel Pruebas unitarias en el lado derecho de la pantalla. En el menú, seleccione Ver > Pruebas.
9. Haga clic en el icono Acoplar para mantener abierto el panel. (Resaltado en la siguiente imagen).

10. Haga clic en el botón Ejecutar todas.


La prueba no se supera, que es el resultado correcto. El método de prueba afirma que dos instancias de
inputString , "Jack", no se devuelve de la cadena "Jack jack", proporciona al método GetWordCount . Puesto
que la distinción de mayúsculas y minúsculas se ha factorizado en el método GetWordCount , se devuelven
dos instancias. La aserción de que 2 no es igual a 2 produce un error. Este es el resultado correcto y la
lógica de nuestra prueba es buena.

11. Modifique el método de prueba IgnoreCasing cambiando Assert.NotEqual por Assert.Equal . Guarde el
archivo mediante el método abreviado de teclado Ctrl+s, Archivo > Guardar en el menú, o use Ctrl+clic
en la pestaña del archivo y seleccione Guardar en el menú contextual.
Se espera que el valor "Jack" de searchWord devuelva dos instancias con inputString "Jack jack" pasado a
GetWordCount . Vuelva a ejecutar la prueba; para ello, haga clic en el botón Ejecutar pruebas en el panel
Pruebas unitarias o en el botón Volver a ejecutar pruebas en el panel Resultados de pruebas en la
parte inferior de la pantalla. La prueba se supera. Hay dos instancias de "Jack" en la cadena "Jack jack" (se
omite la distinción de mayúsculas y minúsculas) y la aserción de prueba es true .

12. Probar los valores devueltos individuales con un elemento Fact es solo el comienzo de lo que se puede
hacer con las pruebas unitarias. Otra técnica eficaz le permite probar varios valores a la vez mediante un
elemento Theory . Agregue el siguiente método a la clase TextUtils_GetWordCountShould . Después de
agregar este método tiene dos métodos en la clase:
[Theory]
[InlineData(0, "Ting", "Does not appear in the string.")]
[InlineData(1, "Ting", "Ting appears once.")]
[InlineData(2, "Ting", "Ting appears twice with Ting.")]
public void CountInstancesCorrectly(int count,
string searchWord,
string inputString)
{
Assert.NotEqual(count, WordCount.GetWordCount(searchWord,
inputString));
}

El método CountInstancesCorrectly comprueba que el método GetWordCount cuenta correctamente. El


método InlineData proporciona un recuento, una palabra de búsqueda y una cadena de entrada para
comprobar. El método de prueba se ejecuta una vez por cada línea de datos. Una vez más, observe que está
afirmando un error primero mediante Assert.NotEqual , aunque sabe que los recuentos de los datos son
correctos y que los valores coincidirán con los recuentos devueltos por el método GetWordCount . Realizar el
paso de no superar la prueba a propósito podría parecer una pérdida de tiempo al principio, pero
comprobar la lógica de la prueba de esta manera es una comprobación importante en la lógica de las
pruebas. Si se encuentra con un método de prueba que se supera cuando espera que no lo haga, habrá
encontrado un error en la lógica de la prueba. Merece la pena el esfuerzo de realizar este paso cada vez que
crea un método de prueba.
13. Guarde el archivo y vuelva a ejecutar las pruebas. La prueba de distinción de mayúsculas y minúsculas se
supera pero las tres pruebas de recuento no. Este resultado es exactamente lo que espera que ocurra.

14. Modifique el método de prueba CountInstancesCorrectly cambiando Assert.NotEqual por Assert.Equal .


Guarde el archivo. Vuelva a ejecutar las pruebas. Todas las pruebas se superan.

Adición de una aplicación de consola


1. En la barra lateral Solución, use Ctrl+clic en la solución WordCounter . Agregue un nuevo proyecto de
aplicación de consola; para ello, seleccione la plantilla en .NET Core > Aplicación. Seleccione
Siguiente. Nombre al proyecto WordCounterApp. Seleccione Crear para crear el proyecto en la
solución.
2. En la barra lateral Soluciones, use Ctrl+clic en el nodo Dependencias del nuevo proyecto
WordCounterApp. En el cuadro de diálogo Editar referencias, marque TextUtils y seleccione Aceptar.
3. Abra el archivo Program.cs. Reemplace el código por el siguiente código:
using System;
using TextUtils;

namespace WordCounterApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a search word:");
var searchWord = Console.ReadLine();
Console.WriteLine("Provide a string to search:");
var inputString = Console.ReadLine();

var wordCount = WordCount.GetWordCount(searchWord, inputString);

var pluralChar = "s";


if (wordCount == 1)
{
pluralChar = string.Empty;
}

Console.WriteLine($"The search word {searchWord} appears " +


$"{wordCount} time{pluralChar}.");
}
}
}

4. Use Ctrl+clic en el proyecto WordCounterApp y seleccione Ejecutar el proyecto en el menú contextual. Al


ejecutar la aplicación, proporcione valores para la palabra de búsqueda y la cadena de entrada en los
mensajes de la ventana de consola. La aplicación indica el número de veces que aparece la palabra de
búsqueda en la cadena.

5. La última característica para explorar es la depuración con Visual Studio para Mac. Establezca un punto de
interrupción en la instrucción Console.WriteLine : selecciónelo en el margen izquierdo de la línea 23 y verá
un círculo de color rojo junto a la línea de código. Como alternativa, seleccione cualquier parte de la línea
de código y seleccione Ejecutar > Alternar puntos de interrupción en el menú.

6. Use Ctrl+clic en el proyecto WordCounterApp . Seleccione Iniciar depuración del proyecto en el menú
contextual. Cuando se ejecute la aplicación, escriba la palabra de búsqueda "cat" (gato) y la cadena "The
dog chased the cat, but the cat escaped" (El perro persiguió el gato, pero el gato se escapó) que se va a
buscar. Cuando se llegue a la instrucción Console.WriteLine , la ejecución del programa se detiene antes de
que se ejecute la instrucción. En la pestaña Variables locales, puede ver los valores searchWord ,
inputString , wordCount y pluralChar .
7. En el panel Inmediato, escriba "wordCount = 999;" y presione Entrar. Este comando asigna un valor
absurdo de 999 a la variable wordCount , lo que demuestra que puede sustituir valores de variables durante
la depuración.

8. En la barra de herramientas, haga clic en la flecha para continuar. Examine la salida en la ventana de
consola. Notifica el valor incorrecto de 999 que estableció cuando estaba depurando la aplicación.

Puede usar el mismo proceso para depurar el código mediante el proyecto de prueba unitaria. En lugar de iniciar
el proyecto de aplicación WordCount, use Ctrl+clic en el proyecto Biblioteca de pruebas y seleccione Iniciar
depuración del proyecto en el menú contextual. Visual Studio para Mac inicia el proyecto de prueba con el
depurador asociado. La ejecución se detendrá en cualquier punto de interrupción que haya agregado al proyecto
de prueba o al código de la biblioteca subyacente.

Vea también
Notas de la versión de Visual Studio 2019 para Mac
Introducción a .NET Core en Windows, Linux y
macOS con la línea de comandos
12/01/2020 • 10 minutes to read • Edit Online

En este artículo se muestra cómo empezar a desarrollar aplicaciones multiplataforma en su máquina con las
herramientas de la CLI de .NET Core.
Si no está familiarizado con el conjunto de herramientas de la CLI de .NET Core, vea la información general del
SDK de .NET Core.

Requisitos previos
SDK 3.1 de NET Core o versiones posteriores.
Un editor de texto o un editor de código de su elección.

Hola, aplicación de consola


Puede ver o descargar el código de ejemplo del repositorio dotnet/samples de GitHub. Para obtener instrucciones
de descarga, vea Ejemplos y tutoriales.
Abra un símbolo del sistema y cree una carpeta denominada Hello. Vaya a la carpeta que ha creado y escriba lo
siguiente:

dotnet new console


dotnet run

Veamos un tutorial rápido:


1. dotnet new console

dotnet new crea un archivo de proyecto Hello.csproj actualizado con las dependencias necesarias para
compilar una aplicación de consola. Además, también crea Program.cs, un archivo básico que contiene el
punto de entrada para la aplicación.
Hello.csproj:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

</Project>

El archivo de proyecto especifica todo lo que es necesario para restaurar las dependencias y compilar el
programa.
El elemento <OutputType> especifica que estamos creando un archivo ejecutable, es decir, una
aplicación de consola.
El elemento <TargetFramework> especifica el destino de la implementación de .NET. En un escenario
avanzado, con una sola operación puede especificar varios marcos de destino y compilar en todos ellos.
En este tutorial, nos centraremos en compilar únicamente para .NET Core 3.1.
Program.cs:

using System;

namespace Hello
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

El programa se inicia mediante using System , lo que significa "llevar cada cosa del espacio de nombres
System al ámbito de este archivo". El espacio de nombres System incluye la clase Console .

Después, definimos un espacio de nombres denominado Hello . Puede cambiar esto por cualquier cosa
que desee. Se define una clase denominada Program dentro del espacio de nombres, con un método Main
que toma una matriz de cadenas llamada args . Esta matriz contiene la lista de argumentos que se han
pasado cuando se ejecuta el programa. Esta matriz no se usa tal cual y el programa escribe simplemente el
texto "¡ Hola mundo!". en la consola. Después, realizaremos cambios en el código que usará este
argumento.
dotnet new llama a dotnet restore de forma implícita. dotnet restore llama a NuGet (el administrador de
paquetes de .NET) para restaurar el árbol de dependencias. NuGet analiza el archivo Hello.csproj, descarga
las dependencias descritas en el archivo (o las toma de la memoria caché del equipo) y escribe el archivo
obj/project.assets.json, que es necesario para compilar y ejecutar el ejemplo.
2. dotnet run

dotnet run llama a dotnet build para garantizar que se han creado los destinos de compilación y, luego,
llama a dotnet <assembly.dll> para ejecutar la aplicación de destino.

dotnet run

Hello World!

También puede ejecutar dotnet build para compilar el código sin ejecutar las aplicaciones de consola de
compilación. El resultado es una aplicación compilada, como un archivo DLL, basada en el nombre del
proyecto. En este caso, el archivo creado se llama Hello.dll. Esta aplicación se puede ejecutar con
dotnet bin\Debug\netcoreapp3.1\Hello.dll en Windows (use / con sistemas que no son Windows).

dotnet bin\Debug\netcoreapp3.1\Hello.dll

Hello World!

Cuando se compila la aplicación, se crea un archivo ejecutable específico del sistema operativo junto con
Hello.dll . En Windows, sería Hello.exe ; en Linux o macOS, sería hello . Con el ejemplo anterior, el
archivo se designa con Hello.exe o Hello . Puede ejecutar ese archivo ejecutable directamente.
.\bin\Debug\netcoreapp3.1\Hello.exe

Hello World!

Modificación del programa


Cambiemos un poco el programa. Los números Fibonacci son divertidos, así que vamos a agregarlos y a usar
además el argumento para saludar a la persona que ejecuta la aplicación.
1. Reemplace el contenido de su archivo Program.cs por el código siguiente:

using System;

namespace Hello
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine($"Hello {args[0]}!");
}
else
{
Console.WriteLine("Hello!");
}

Console.WriteLine("Fibonacci Numbers 1-15:");

for (int i = 0; i < 15; i++)


{
Console.WriteLine($"{i + 1}: {FibonacciNumber(i)}");
}
}

static int FibonacciNumber(int n)


{
int a = 0;
int b = 1;
int tmp;

for (int i = 0; i < n; i++)


{
tmp = a;
a = b;
b += tmp;
}

return a;
}

}
}

2. Ejecute dotnet build para compilar los cambios.


3. Para ejecutar el programa, pase un parámetro a la aplicación. Cuando use el comando dotnet para
ejecutar una aplicación, agregue -- al final. Todo lo que quede a la derecha de -- se pasará como un
parámetro a la aplicación. En el ejemplo siguiente, el valor John se pasa a la aplicación.
$ dotnet run -- John
Hello John!
Fibonacci Numbers 1-15:
1: 0
2: 1
3: 1
4: 2
5: 3
6: 5
7: 8
8: 13
9: 21
10: 34
11: 55
12: 89
13: 144
14: 233
15: 377

Y listo. Puede modificar Program.cs como prefiera.

Trabajar con varios archivos


Los archivos únicos son adecuados para programas sencillos de uso único, pero, si va a crear una aplicación más
compleja, probablemente llegue a tener varios archivos de código en el proyecto. Se compilará sobre el ejemplo
de Fibonacci anterior mediante el almacenamiento en caché de algunos valores de Fibonacci y la adición de varias
características recursivas.
1. Agregue un archivo nuevo dentro del directorio Hello denominado FibonacciGenerator.cs con el código
siguiente:

using System;
using System.Collections.Generic;

namespace Hello
{
public class FibonacciGenerator
{
private Dictionary<int, int> _cache = new Dictionary<int, int>();

private int Fib(int n) => n < 2 ? n : FibValue(n - 1) + FibValue(n - 2);

private int FibValue(int n)


{
if (!_cache.ContainsKey(n))
{
_cache.Add(n, Fib(n));
}

return _cache[n];
}

public IEnumerable<int> Generate(int n)


{
for (int i = 0; i < n; i++)
{
yield return FibValue(i);
}
}
}
}
2. Cambie el método Main en su archivo Program.cs para crear una instancia de la nueva clase y llamar a su
método como se muestra en el ejemplo siguiente:

using System;

namespace Hello
{
class Program
{
static void Main(string[] args)
{
var generator = new FibonacciGenerator();
foreach (var digit in generator.Generate(15))
{
Console.WriteLine(digit);
}
}
}
}

3. Ejecute dotnet build para compilar los cambios.


4. Ejecute su aplicación mediante la ejecución de dotnet run. A continuación se muestra el resultado del
programa:

$ dotnet run
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377

Publicar la aplicación
Cuando esté listo para distribuir la aplicación, use el comando dotnet publish_para generar la carpeta_publish en
\bin\debug\netcoreapp3.1\publish / (para sistemas que no son Windows). Puede distribuir el contenido de la
carpeta publish en otras plataformas siempre y cuando ya haya instalado el entorno de ejecución de dotnet.

dotnet publish
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restore completed in 20 ms for C:\Code\Temp\Hello\Hello.csproj.


Hello -> C:\Code\Temp\Hello\bin\Debug\netcoreapp3.1\Hello.dll
Hello -> C:\Code\Temp\Hello\bin\Debug\netcoreapp3.1\publish\

Puede que la salida anterior no sea igual por la carpeta y el sistema operativo actuales, pero el resultado será
parecido.
Puede ejecutar la aplicación publicada con el comando dotnet:
dotnet bin\Debug\netcoreapp3.1\publish\Hello.dll

Hello World!

Como se ha mencionado al comienzo de este artículo, se ha creado un archivo ejecutable específico del sistema
operativo junto con Hello.dll . En Windows, sería Hello.exe ; en Linux o macOS, sería hello . Con el ejemplo
anterior, el archivo se designa con Hello.exe o Hello . Puede ejecutar este archivo ejecutable publicado
directamente.

.\bin\Debug\netcoreapp3.1\Hello.exe

Hello World!

Conclusión
Y listo. Ahora, puede empezar a usar los conceptos básicos que ha aprendido aquí para crear sus propios
programas.

Vea también
Organización y prueba de proyectos con las herramientas de la CLI de .NET Core
Publicación de aplicaciones .NET Core con la CLI
Más información acerca de la implementación
Organización y prueba de proyectos con la línea de
comandos de .NET Core
12/01/2020 • 11 minutes to read • Edit Online

Este tutorial sigue al tutorial Introducción a .NET Core en Windows, Linux y macOS con la línea de comandos
dirigiéndole más allá de la creación de una aplicación de consola sencilla para desarrollar aplicaciones más
avanzadas y bien organizadas. Después de mostrarle cómo usar carpetas para organizar su código, este tutorial le
muestra cómo ampliar una aplicación de consola con el marco de pruebas de xUnit.

Uso de carpetas para organizar el código


Si quiere introducir nuevos tipos en una aplicación de consola, puede hacerlo agregando archivos que contienen
los tipos en la aplicación. Por ejemplo, si agrega archivos que contienen tipos AccountInformation y
MonthlyReportRecords en su proyecto, la estructura del archivo del proyecto es plana y fácil desplazarse por él:

/MyProject
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

En cambio, esto solo funciona bien cuando el tamaño del proyecto es relativamente pequeño. ¿Puede imaginar
qué pasará si agrega 20 tipos al proyecto? Definitivamente no será fácil desplazarse por el proyecto ni mantenerlo
con tantos archivos depositados en el directorio raíz del proyecto.
Para organizar el proyecto, cree una carpeta nueva y denomínela Models para contener los archivos de tipo.
Coloque los archivos de tipo en la carpeta Models:

/MyProject
|__/Models
|__AccountInformation.cs
|__MonthlyReportRecords.cs
|__MyProject.csproj
|__Program.cs

Es fácil desplazarse por los proyectos que agrupan archivos en carpetas de manera lógica, así como mantenerlos.
En la sección siguiente, creará un ejemplo más complejo con carpetas y pruebas unitarias.

Organizar y probar con el ejemplo de NewTypes Pets


Compilar el ejemplo
Para los pasos siguientes, puede seguir con el ejemplo de NewTypes Pets o crear sus propios archivos y carpetas.
Los tipos se organizan de manera lógica en una estructura de carpetas que permite la adición de más tipos
posteriormente, y las pruebas también se colocan de manera lógica en carpetas que permiten la adición de más
pruebas después.
El ejemplo contiene dos tipos, Dog y Cat , y tiene implementada una interfaz común, IPet . Para el proyecto
NewTypes , su objetivo es organizar los tipos relacionados con las mascotas en una carpeta Pets. Si se agrega
después otro conjunto de tipos, WildAnimals por ejemplo, se colocan en la carpeta NewTypes junto a la carpeta
Pets. La carpeta WildAnimals puede contener tipos de animales que no son mascotas, como los tipos Squirrel y
Rabbit . De la manera en que se agregan los tipos, el proyecto sigue estando bien organizado.
Cree la siguiente estructura de carpetas con el contenido del archivo indicado:

/NewTypes
|__/src
|__/NewTypes
|__/Pets
|__Dog.cs
|__Cat.cs
|__IPet.cs
|__Program.cs
|__NewTypes.csproj

IPet.cs:

using System;

namespace Pets
{
public interface IPet
{
string TalkToOwner();
}
}

Dog.cs:

using System;

namespace Pets
{
public class Dog : IPet
{
public string TalkToOwner() => "Woof!";
}
}

Cat.cs:

using System;

namespace Pets
{
public class Cat : IPet
{
public string TalkToOwner() => "Meow!";
}
}

Program.cs:
using System;
using Pets;
using System.Collections.Generic;

namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
List<IPet> pets = new List<IPet>
{
new Dog(),
new Cat()
};

foreach (var pet in pets)


{
Console.WriteLine(pet.TalkToOwner());
}
}
}
}

NewTypes.csproj:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

</Project>

Ejecute el siguiente comando:

dotnet run

Obtenga el siguiente resultado:

Woof!
Meow!

Ejercicio opcional: puede agregar un nuevo tipo de mascota, como Bird , si amplía este proyecto. Haga que el
método TalkToOwner de las aves proporcione Tweet! al propietario. Ejecute la aplicación de nuevo. El resultado
incluirá Tweet! .
Probar el ejemplo
El proyecto NewTypes está en su lugar y lo ha organizado manteniendo los tipos relacionados con las mascotas en
una carpeta. Después, cree su proyecto de prueba y comience a escribir pruebas con el marco de pruebas de xUnit.
Las pruebas unitarias le permiten comprobar automáticamente el comportamiento de sus tipos de mascota para
confirmar que están funcionando correctamente.
Vuelva a la carpeta src y cree una carpeta test con una carpeta NewTypesTests en su interior. En un símbolo del
sistema desde la carpeta NewTypesTests, ejecute dotnet new xunit . Esto genera dos archivos:
NewTypesTests.csproj y UnitTest1.cs.
El proyecto de prueba no puede probar actualmente los tipos de NewTypes y necesita una referencia del proyecto
para el proyecto NewTypes . Para agregar una referencia del proyecto, use el comando dotnet add reference :

dotnet add reference ../../src/NewTypes/NewTypes.csproj

O bien, también tiene la opción de agregar manualmente la referencia del proyecto si agrega un nodo
<ItemGroup> al archivo NewTypesTests.csproj:

<ItemGroup>
<ProjectReference Include="../../src/NewTypes/NewTypes.csproj" />
</ItemGroup>

NewTypesTests.csproj:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../../src/NewTypes/NewTypes.csproj"/>
</ItemGroup>

</Project>

El archivo NewTypesTests.csproj contiene lo siguiente:


Referencia del paquete a Microsoft.NET.Test.Sdk , la infraestructura de pruebas de .NET
Referencia del paquete a xunit , el marco de pruebas de xUnit
Referencia del paquete a xunit.runner.visualstudio , el ejecutor de pruebas
Referencia del proyecto a NewTypes , el código que se va a probar

Cambie el nombre de UnitTest1.cs a PetTests.cs y reemplace el código en el archivo por lo siguiente:


using System;
using Xunit;
using Pets;

public class PetTests


{
[Fact]
public void DogTalkToOwnerReturnsWoof()
{
string expected = "Woof!";
string actual = new Dog().TalkToOwner();

Assert.NotEqual(expected, actual);
}

[Fact]
public void CatTalkToOwnerReturnsMeow()
{
string expected = "Meow!";
string actual = new Cat().TalkToOwner();

Assert.NotEqual(expected, actual);
}
}

Ejercicio opcional: si ha agregado un tipo Bird anteriormente que da como resultado Tweet! para el propietario,
agregue un método de prueba al archivo PetTests.cs, BirdTalkToOwnerReturnsTweet , para comprobar que el método
TalkToOwner funciona correctamente para el tipo Bird .

NOTE
Aunque espere que los valores expected y actual sean iguales, la aserción inicial con la comprobación
Assert.NotEqual especifica que estos valores no son iguales. Cree siempre inicialmente una prueba que resulte fallida para
comprobar la lógica de la prueba. Después de confirmar que la prueba falla, ajuste la aserción para permitir que se supere la
prueba.

A continuación se muestra la estructura del proyecto completo:

/NewTypes
|__/src
|__/NewTypes
|__/Pets
|__Dog.cs
|__Cat.cs
|__IPet.cs
|__Program.cs
|__NewTypes.csproj
|__/test
|__NewTypesTests
|__PetTests.cs
|__NewTypesTests.csproj

Comience en el directorio test/NewTypesTests. Restaure el proyecto de prueba con el comando dotnet restore .
Ejecute las pruebas con el comando dotnet test . Este comando inicia el ejecutor de pruebas especificado en el
archivo del proyecto.
NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

Como se esperaba, se producen errores en las pruebas y la consola muestra el siguiente resultado:

Test run for c:\Users\ronpet\repos\samples\core\console-


apps\NewTypesMsBuild\test\NewTypesTests\bin\Debug\netcoreapp2.1\NewTypesTests.dll(.NETCoreApp,Version=v2.1)
Microsoft (R) Test Execution Command Line Tool Version 15.8.0
Copyright (c) Microsoft Corporation. All rights reserved.

Starting test execution, please wait...


[xUnit.net 00:00:00.77] PetTests.DogTalkToOwnerReturnsWoof [FAIL]
[xUnit.net 00:00:00.78] PetTests.CatTalkToOwnerReturnsMeow [FAIL]
Failed PetTests.DogTalkToOwnerReturnsWoof
Error Message:
Assert.NotEqual() Failure
Expected: Not "Woof!"
Actual: "Woof!"
Stack Trace:
at PetTests.DogTalkToOwnerReturnsWoof() in c:\Users\ronpet\repos\samples\core\console-
apps\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 13
Failed PetTests.CatTalkToOwnerReturnsMeow
Error Message:
Assert.NotEqual() Failure
Expected: Not "Meow!"
Actual: "Meow!"
Stack Trace:
at PetTests.CatTalkToOwnerReturnsMeow() in c:\Users\ronpet\repos\samples\core\console-
apps\NewTypesMsBuild\test\NewTypesTests\PetTests.cs:line 22

Total tests: 2. Passed: 0. Failed: 2. Skipped: 0.


Test Run Failed.
Test execution time: 1.7000 Seconds

Cambie las aserciones de sus pruebas de Assert.NotEqual a Assert.Equal :


using System;
using Xunit;
using Pets;

public class PetTests


{
[Fact]
public void DogTalkToOwnerReturnsWoof()
{
string expected = "Woof!";
string actual = new Dog().TalkToOwner();

Assert.Equal(expected, actual);
}

[Fact]
public void CatTalkToOwnerReturnsMeow()
{
string expected = "Meow!";
string actual = new Cat().TalkToOwner();

Assert.Equal(expected, actual);
}
}

Vuelva a ejecutar las pruebas con el comando dotnet test y obtenga el siguiente resultado:

Test run for c:\Users\ronpet\repos\samples\core\console-


apps\NewTypesMsBuild\test\NewTypesTests\bin\Debug\netcoreapp2.1\NewTypesTests.dll(.NETCoreApp,Version=v2.1)
Microsoft (R) Test Execution Command Line Tool Version 15.8.0
Copyright (c) Microsoft Corporation. All rights reserved.

Starting test execution, please wait...

Total tests: 2. Passed: 2. Failed: 0. Skipped: 0.


Test Run Successful.
Test execution time: 1.6029 Seconds

Se pasan las pruebas. Los métodos de los tipos de mascota devuelven los valores correctos al dirigirse al
propietario.
Ha obtenido información sobre las técnicas para organizar y probar proyectos con xUnit. Continúe con estas
técnicas aplicándolas en sus propios proyectos. Disfrute programando.
Desarrollar bibliotecas con herramientas
multiplataforma
20/01/2020 • 22 minutes to read • Edit Online

En este artículo se explica cómo escribir bibliotecas para .NET mediante el uso de herramientas multiplataforma
de la CLI. La CLI proporciona una experiencia eficaz y de bajo nivel que funciona en todos los SO compatibles. De
todos modos puede seguir compilando bibliotecas con Visual Studio; si esa es la experiencia de su preferencia,
consulte la guía sobre Visual Studio.

Requisitos previos
Necesita la CLI y el SDK de .NET Core que están instalados en la máquina.
En las secciones de este documento que se refieren a las versiones de .NET Framework, necesita tener instalado
.NET Framework en una máquina con Windows.
Además, si desea admitir destinos de .NET Framework anteriores, deberá instalar paquetes de destino o
desarrollador desde la página de archivos de descarga de .NET. Consulte la tabla siguiente:

VERSIÓN DE .NET FRAMEWORK QUÉ DEBE DESCARGAR

4.6.1 Paquete de compatibilidad de .NET Framework 4.6.1

4.6 Paquete de compatibilidad de .NET Framework 4.6

4.5.2 Paquete de desarrollador de .NET Framework 4.5.2

4.5.1 Paquete de desarrollador de .NET Framework 4.5.1

4.5 Kit de desarrollo de software de Windows para Windows 8

4.0 Windows SDK para Windows 7 y .NET Framework 4

2.0, 3.0 y 3.5 Entorno de ejecución de .NET Framework 3.5 SP1 (o una
versión posterior a Windows 8)

Estándar .NET como destino


Si no conoce .NET Standard, consulte el tema .NET Standard para más información.
En ese artículo podrá ver una tabla que asigna las versiones de .NET Standard a diversas implementaciones:

.NET
STANDA
RD 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0 2.1

.NET 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0 3.0
Core
.NET
STANDA
RD 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0 2.1

.NET 4.5 4.5 4.5.1 4.6 4.6.1 4.6.1 2 4.6.1 2 4.6.1 2 N/A3
Framew
ork 1

Mono 4.6 4.6 4.6 4.6 4.6 4.6 4.6 5.4 6.4

Xamarin. 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.14 12.16
iOS

Xamarin. 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.8 5.16
Mac

Xamarin. 7.0 7.0 7.0 7.0 7.0 7.0 7.0 8.0 10.0
Android

Platafor 10.0 10.0 10.0 10.0 10.0 10.0.162 10.0.162 10.0.162 TBD
ma 99 99 99
universa
l de
Window
s

Unity 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 TBD

1 Las versiones que se muestran de .NET Framework se aplican al SDK de .NET Core 2.0 y versiones posteriores de la herramienta. Las versiones
anteriores usaban una asignación diferente para .NET Standard 1.5 y versiones posteriores. Puede descargar herramientas para .NET Core para Visual
Studio 2015 si no se puede actualizar a Visual Studio 2017 ni a una versión posterior.

2 Las versiones siguientes representan las reglas que usa NuGet para determinar si una determinada biblioteca de .NET Standard es aplicable. Aunque
NuGet considera a .NET Framework 4.6.1 compatible con .NET Standard (versiones 1.5 a 2.0) hay varios problemas con el consumo de bibliotecas de
.NET Standard que se compilaron para esas versiones desde proyectos de .NET Framework 4.6.1. Para los proyectos de .NET Framework que tengan
que usar estas bibliotecas, se recomienda actualizar el proyecto para destinarlo a .NET Framework 4.7.2 o una versión posterior.

3 .NET Framework no admitirá .NET Standard 2.1 o versiones posteriores. Para más detalles, vea el anuncio de .NET Standard 2.1.

Las columnas representan las versiones de .NET Standard. Cada celda de encabezado es un vínculo a un
documento que muestra qué API se han agregado en esa versión de .NET Standard.
Las filas representan las diferentes implementaciones de .NET.
El número de versión de cada celda indica la versión mínima de la implementación que necesitará para tener
como destino dicha versión de .NET Standard.
Para ver una tabla interactiva, consulte Versiones de .NET Standard.
Este es el significado de la tabla para crear una biblioteca:
La versión de .NET Standard que elija será un equilibrio entre el acceso a las API más recientes y la capacidad de
apuntar a más implementaciones .NET y más versiones de .NET Standard. Puede controlar el intervalo de
versiones y plataformas de destino si elige una versión de netstandardX.X (donde X.X es un número de versión)
y la agrega al archivo del proyecto ( .csproj o .fsproj ).
En función de sus necesidades, tiene tres opciones principales cuando el destino es .NET Standard.
1. Puede usar la versión predeterminada de .NET Standard que se proporciona con plantillas, netstandard1.4 ,
que le permite acceder a la mayoría de API en .NET Standard mientras sigue siendo compatible con UWP,
.NET Framework 4.6.1 y .NET Standard 2.0.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
</Project>

2. Puede usar una versión anterior o posterior de .NET Standard modificando el valor en el nodo
TargetFramework de su archivo del proyecto.

Las versiones del estándar .NET son compatibles con versiones anteriores. Eso significa que las bibliotecas
netstandard1.0 se pueden ejecutar en plataformas netstandard1.1 y versiones superiores. Sin embargo,
no hay compatibilidad con versiones posteriores. Las plataformas de .NET Standard anteriores no pueden
hacer referencia a las posteriores. Esto significa que las bibliotecas netstandard1.0 no pueden hacer
referencia a las bibliotecas que tienen como destino netstandard1.1 o una versión superior. Seleccione la
versión estándar que tiene la combinación adecuada de compatibilidad con API y plataformas que necesita.
Por ahora le recomendamos netstandard1.4 .
3. Si desea tener como destino .NET Framework versión 4.0 o inferior, o bien desea usar una API disponible
en .NET Framework pero no disponible en el estándar .NET (por ejemplo, System.Drawing ), lea las
secciones siguientes y sepa cómo tener compatibilidad con múltiples versiones.

Uso de .NET Framework como destino


NOTE
En estas instrucciones se supone que tiene instalado .NET Framework en su máquina. Consulte los requisitos previos para
instalar las dependencias.

Tenga en cuenta que algunas de las versiones de .NET Framework que se usan aquí ya no cuentan con soporte
técnico. Consulte las P+F sobre la directiva del ciclo de vida de soporte técnico de .NET Framework sobre las
versiones sin soporte técnico.
Si quiere llegar a la mayor cantidad posible de desarrolladores y proyectos, use .NET Framework 4.0 como el
destino de línea base. Para tener .NET Framework como destino, comience utilizando el moniker de la plataforma
de destino (TFM ) correcto que corresponda a la versión de .NET Framework que desea admitir.

VERSIÓN DE .NET FRAMEWORK TFM

.NET Framework 2.0 net20

.NET Framework 3.0 net30

.NET Framework 3,5 net35

.NET Framework 4.0 net40

.NET Framework 4.5 net45

.NET Framework 4.5.1 net451

.NET Framework 4.5.2 net452


VERSIÓN DE .NET FRAMEWORK TFM

.NET Framework 4.6 net46

.NET Framework 4.6.1 net461

.NET Framework 4.6.2 net462

.NET Framework 4.7 net47

.NET Framework 4.8 net48

Después, inserte el TFM en la sección TargetFramework de su archivo del proyecto. El siguiente es un ejemplo de
cómo podría escribir una biblioteca que tenga como destino .NET Framework 4.0:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net40</TargetFramework>
</PropertyGroup>
</Project>

Y listo. Aunque esto solo hace la compilación para .NET Framework 4, puede usar la biblioteca en las versiones
más recientes de .NET Framework.

Cómo lograr la compatibilidad con varias versiones


NOTE
Las instrucciones siguientes suponen que tiene instalado .NET Framework en su máquina. Consulte la sección de requisitos
previos para información sobre las dependencias que debe instalar y dónde descargarlas.

Es posible que deba tener como destino versiones anteriores de .NET Framework cuando el proyecto admite .NET
Framework y .NET Core. En este escenario, si desea usar API más recientes y construcciones de lenguaje para los
destinos más recientes, use las directivas #if en el código. También es posible que tenga que agregar distintos
paquetes y dependencias para cada plataforma que tiene como destino para incluir las distintas API necesarias
para cada caso.
Por ejemplo, digamos que tiene una biblioteca que realiza operaciones de red a través de HTTP. En el estándar
.NET y .NET Framework versión 4.5 o superiores, puede usar la clase HttpClient del espacio de nombres
System.Net.Http . Sin embargo, las versiones anteriores de .NET Framework no tienen la clase HttpClient , por lo
que, en su lugar, podría usar la clase WebClient del espacio de nombres System.Net para esas versiones.
Su archivo del proyecto podría tener la siguiente apariencia:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.4;net40;net45</TargetFrameworks>
</PropertyGroup>

<!-- Need to conditionally bring in references for the .NET Framework 4.0 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<Reference Include="System.Net" />
</ItemGroup>

<!-- Need to conditionally bring in references for the .NET Framework 4.5 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>

Observará tres cambios principales aquí:


1. El nodo TargetFramework se ha reemplazado por TargetFrameworks , y se expresan tres TFM dentro.
2. Existe un nodo <ItemGroup> para el destino net40 que se dirige a una referencia de .NET Framework.
3. Existe un nodo <ItemGroup> para el destino net45 que se dirige a dos referencias de .NET Framework.

El sistema de compilación conoce los siguientes símbolos del preprocesador que se usan en las directivas #if :

VERSIONES DE .NET FRAMEWORK DE DESTINO SÍMBOLOS

.NET Framework NETFRAMEWORK , NET20 , NET35 , NET40 , NET45 , NET451 ,


NET452 , NET46 , NET461 , NET462 , NET47 , NET471 ,
NET472 , NET48

.NET Standard NETSTANDARD , NETSTANDARD1_0 , NETSTANDARD1_1 ,


NETSTANDARD1_2 , NETSTANDARD1_3 , NETSTANDARD1_4 ,
NETSTANDARD1_5 , NETSTANDARD1_6 , NETSTANDARD2_0 ,
NETSTANDARD2_1

.NET Core NETCOREAPP , NETCOREAPP1_0 , NETCOREAPP1_1 ,


NETCOREAPP2_0 , NETCOREAPP2_1 , NETCOREAPP2_2 ,
NETCOREAPP3_0 , NETCOREAPP3_1

Aquí se muestra un ejemplo en el que se usa la compilación condicional por destino:


using System;
using System.Text.RegularExpressions;
#if NET40
// This only compiles for the .NET Framework 4 targets
using System.Net;
#else
// This compiles for all other targets
using System.Net.Http;
using System.Threading.Tasks;
#endif

namespace MultitargetLib
{
public class Library
{
#if NET40
private readonly WebClient _client = new WebClient();
private readonly object _locker = new object();
#else
private readonly HttpClient _client = new HttpClient();
#endif

#if NET40
// .NET Framework 4.0 does not have async/await
public string GetDotNetCount()
{
string url = "https://www.dotnetfoundation.org/";

var uri = new Uri(url);

string result = "";

// Lock here to provide thread-safety.


lock(_locker)
{
result = _client.DownloadString(uri);
}

int dotNetCount = Regex.Matches(result, ".NET").Count;

return $"Dotnet Foundation mentions .NET {dotNetCount} times!";


}
#else
// .NET 4.5+ can use async/await!
public async Task<string> GetDotNetCountAsync()
{
string url = "https://www.dotnetfoundation.org/";

// HttpClient is thread-safe, so no need to explicitly lock here


var result = await _client.GetStringAsync(url);

int dotNetCount = Regex.Matches(result, ".NET").Count;

return $"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";


}
#endif
}
}

Si crea este proyecto con dotnet build , observará tres directorios en la carpeta bin/ :

net40/
net45/
netstandard1.4/
Cada uno de ellos contiene los archivos .dll para cada destino.

Prueba de las bibliotecas en .NET Core


Es importante poder probar las plataformas. Puede usar xUnit o MSTest de fábrica. Ambos son perfectamente
adecuados para las pruebas unitarias de su biblioteca en .NET Core. Cómo configurar la solución con proyectos de
prueba dependerá de la estructura de la solución. En el ejemplo siguiente se presupone que los directorios de
origen y de prueba residen en el mismo directorio de nivel superior.

NOTE
Esto usa algunos comandos de la CLI de .NET Core. Vea dotnet new y dotnet sln para obtener más información.

1. Configure la solución. Puede hacerlo con los siguientes comandos:

mkdir SolutionWithSrcAndTest
cd SolutionWithSrcAndTest
dotnet new sln
dotnet new classlib -o MyProject
dotnet new xunit -o MyProject.Test
dotnet sln add MyProject/MyProject.csproj
dotnet sln add MyProject.Test/MyProject.Test.csproj

Esto creará proyectos y se vincularán conjuntamente en una solución. Su directorio para


SolutionWithSrcAndTest debe tener el siguiente aspecto:

/SolutionWithSrcAndTest
|__SolutionWithSrcAndTest.sln
|__MyProject/
|__MyProject.Test/

2. Vaya al directorio del proyecto de prueba y agregue una referencia a MyProject.Test desde MyProject .

cd MyProject.Test
dotnet add reference ../MyProject/MyProject.csproj

3. Restaurar paquetes y crear proyectos:

dotnet restore
dotnet build

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente
todos los comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y
dotnet run . Sigue siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración
explícita, como las compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación
que necesitan controlar explícitamente la hora a la que se produce la restauración.

4. Compruebe que xUnit se ejecuta mediante la ejecución del comando dotnet test . Si decide usar MSTest,
entonces debe ejecutarse en su lugar el ejecutor de la consola de MSTest.
Y listo. Ahora puede probar la biblioteca en todas las plataformas; para ello, use herramientas de línea de
comandos. Para seguir con las pruebas ahora que ya está todo configurado, probar la biblioteca es un proceso
muy simple:
1. Haga los cambios en la biblioteca.
2. Ejecute las pruebas desde la línea de comandos, en el directorio de prueba, con el comando dotnet test .

El código se recompilará automáticamente cuando invoque el comando dotnet test .

Uso de varios proyectos


Una necesidad en común de las bibliotecas de mayor tamaño es ubicar la funcionalidad en distintos proyectos.
Imagine que desea compilar una biblioteca que se pudiera consumir en C# y F# idiomático. Eso significaría que los
usuarios de las bibliotecas las consumirían de manera natural para C# o F#. Por ejemplo, en C#, podría consumir
la biblioteca de la siguiente manera:

using AwesomeLibrary.CSharp;

public Task DoThings(Data data)


{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}

En F#, sería de la siguiente manera:

open AwesomeLibrary.FSharp

let doWork data = async {


let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method
// do something with result
}

Escenarios de consumo similares a este significan que las API a las que se tiene acceso deben tener una estructura
distinta para C# y para F#. Un enfoque común para lograrlo es factorizar toda la lógica de una biblioteca en un
proyecto central, con los proyectos de C# y F# definiendo los niveles de API que hacen llamadas a ese proyecto
central. En el resto de la sección se usarán los siguientes nombres:
AwesomeLibrary.Core: un proyecto central que contiene toda la lógica de la biblioteca
AwesomeLibrary.CSharp: un proyecto con API públicas pensado para el consumo en C#
AwesomeLibrary.FSharp: un proyecto con API públicas pensado para el consumo en F#
Puede ejecutar los siguientes comandos en su terminal para generar la misma estructura de esta guía:

mkdir AwesomeLibrary && cd AwesomeLibrary


dotnet new sln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnet new classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnet new classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnet new classlib -lang "F#"
cd ..
dotnet sln add AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnet sln add AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnet sln add AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj

Esto agregará los tres proyectos anteriores y un archivo de solución que los vincula conjuntamente. Crear el
archivo de solución y vincular los proyectos le permitirá restaurar y crear proyectos desde un nivel superior.
Referencias entre proyectos
La mejor manera de hacer referencia a un proyecto es usar la CLI de .NET Core para agregar una referencia de
proyecto. Desde los directorios del proyecto AwesomeLibrary.CSharp y AwesomeLibrary.FSharp, puede
ejecutar el siguiente comando:

dotnet add reference ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj

Los archivos del proyecto para AwesomeLibrary.CSharp y AwesomeLibrary.FSharp ahora harán referencia a
AwesomeLibrary.Core como un destino ProjectReference . Puede comprobar esto inspeccionando los archivos
del proyecto y observando lo siguiente en ellos:

<ItemGroup>
<ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>

Puede agregar esta sección a cada archivo del proyecto manualmente si prefiere no usar la CLI de .NET Core.
Estructura de una solución
Otro aspecto importante de las soluciones de varios proyectos es establecer una buena estructura de proyecto
general. Puede organizar el código de la manera que quiera, y siempre y cuando vincule cada proyecto a su
archivo de solución con dotnet sln add , podrá ejecutar dotnet restore y dotnet build en el nivel de solución.
Creación de una aplicación de .NET Core con
complementos
25/11/2019 • 15 minutes to read • Edit Online

Este tutorial muestra cómo crear un contexto AssemblyLoadContext personalizado para cargar complementos. Se
usa un elemento AssemblyDependencyResolver para resolver las dependencias del complemento. El tutorial aísla
correctamente las dependencias del complemento de la aplicación host. Aprenderá a:
Estructurar un proyecto para admitir los complementos.
Crear un elemento AssemblyLoadContext personalizado para cargar cada complemento.
Usar el tipo System.Runtime.Loader.AssemblyDependencyResolver para permitir que los complementos tengan
dependencias.
Crear complementos que se puedan implementar fácilmente con solo copiar los artefactos de compilación.

Requisitos previos
Instale el SDK de .NET Core 3.0 o una versión más reciente.

Crear la aplicación
El primer paso es crear la aplicación:
1. Cree una carpeta nueva y, en ella, ejecute el siguiente comando:

dotnet new console -o AppWithPlugin

2. Para facilitar la compilación del proyecto, cree un archivo de solución de Visual Studio en la misma carpeta.
Ejecute el siguiente comando:

dotnet new sln

3. Ejecute el siguiente comando para agregar el proyecto de aplicación a la solución:

dotnet sln add AppWithPlugin/AppWithPlugin.csproj

Ahora ya se puede rellenar el esqueleto de la aplicación. Reemplace el código del archivo


AppWithPlugin/Program.cs con el código siguiente:
using PluginBase;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace AppWithPlugin
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length == 1 && args[0] == "/d")
{
Console.WriteLine("Waiting for any key...");
Console.ReadLine();
}

// Load commands from plugins.

if (args.Length == 0)
{
Console.WriteLine("Commands: ");
// Output the loaded commands.
}
else
{
foreach (string commandName in args)
{
Console.WriteLine($"-- {commandName} --");

// Execute the command with the name passed as an argument.

Console.WriteLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}

Creación de las interfaces de complemento


El paso siguiente en la creación de una aplicación con complementos consiste en definir la interfaz que los
complementos tienen que implementar. Se recomienda crear una biblioteca de clases que contenga los tipos que se
van a usar para la comunicación entre la aplicación y los complementos. Esta división permite publicar la interfaz de
complemento como un paquete sin tener que enviar la aplicación completa.
En la carpeta raíz del proyecto, ejecute . Además, ejecute
dotnet new classlib -o PluginBase
dotnet sln add PluginBase/PluginBase.csproj para agregar el proyecto al archivo de la solución. Elimine el archivo
PluginBase/Class1.cs y cree uno en la carpeta PluginBase con el nombre ICommand.cs con la definición de interfaz
siguiente:
namespace PluginBase
{
public interface ICommand
{
string Name { get; }
string Description { get; }

int Execute();
}
}

Esta interfaz ICommand es la que van a implementar todos los complementos.


Ahora que se ha definido la interfaz ICommand , el proyecto de aplicación se puede rellenar un poco más. Agregue
una referencia desde el proyecto AppWithPlugin al proyecto PluginBase con el comando
dotnet add AppWithPlugin\AppWithPlugin.csproj reference PluginBase\PluginBase.csproj desde la carpeta raíz.

Reemplace el comentario // Load commands from plugins con el fragmento de código siguiente para habilitarlo para
cargar complementos desde rutas de acceso de archivo determinadas:

string[] pluginPaths = new string[]


{
// Paths to plugins to load.
};

IEnumerable<ICommand> commands = pluginPaths.SelectMany(pluginPath =>


{
Assembly pluginAssembly = LoadPlugin(pluginPath);
return CreateCommands(pluginAssembly);
}).ToList();

Después, reemplace el comentario // Output the loaded commands por el fragmento de código siguiente:

foreach (ICommand command in commands)


{
Console.WriteLine($"{command.Name}\t - {command.Description}");
}

Reemplace el comentario // Execute the command with the name passed as an argument por el fragmento de código
siguiente:

ICommand command = commands.FirstOrDefault(c => c.Name == commandName);


if (command == null)
{
Console.WriteLine("No such command is known.");
return;
}

command.Execute();

Y, por último, agregue los métodos estáticos denominados LoadPlugin y CreateCommands a la clase Program , como
se muestra aquí:
static Assembly LoadPlugin(string relativePath)
{
throw new NotImplementedException();
}

static IEnumerable<ICommand> CreateCommands(Assembly assembly)


{
int count = 0;

foreach (Type type in assembly.GetTypes())


{
if (typeof(ICommand).IsAssignableFrom(type))
{
ICommand result = Activator.CreateInstance(type) as ICommand;
if (result != null)
{
count++;
yield return result;
}
}
}

if (count == 0)
{
string availableTypes = string.Join(",", assembly.GetTypes().Select(t => t.FullName));
throw new ApplicationException(
$"Can't find any type which implements ICommand in {assembly} from {assembly.Location}.\n" +
$"Available types: {availableTypes}");
}
}

Carga de complementos
Ahora la aplicación puede cargar correctamente y crear instancias de los comandos a partir de los ensamblados de
complemento cargados, pero todavía no puede cargar los ensamblados de complemento. Cree un archivo
denominado PluginLoadContext.cs en la carpeta AppWithPlugin con el contenido siguiente:
using System;
using System.Reflection;
using System.Runtime.Loader;

namespace AppWithPlugin
{
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;

public PluginLoadContext(string pluginPath)


{
_resolver = new AssemblyDependencyResolver(pluginPath);
}

protected override Assembly Load(AssemblyName assemblyName)


{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}

return null;
}

protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)


{
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}

return IntPtr.Zero;
}
}
}

El tipo PluginLoadContext se deriva de AssemblyLoadContext. El tipo AssemblyLoadContext es un tipo especial en el


runtime que permite a los desarrolladores aislar los ensamblados cargados en grupos diferentes para asegurarse
de que las versiones de ensamblado no entren en conflicto. Además, un elemento AssemblyLoadContext
personalizado puede elegir otras rutas de acceso desde las que cargar los ensamblados e invalidar el
comportamiento predeterminado. El elemento PluginLoadContext usa una instancia del tipo
AssemblyDependencyResolver que se introdujo en .NET Core 3.0 para resolver los nombres de ensamblado en rutas
de acceso. El objeto AssemblyDependencyResolver se construye con la ruta de acceso a una biblioteca de clases .NET.
Resuelve los ensamblados y las bibliotecas nativas en sus rutas de acceso relativas en función del archivo deps.json
para la biblioteca de clases cuya ruta de acceso se haya pasado al constructor AssemblyDependencyResolver . El
elemento AssemblyLoadContext personalizado permite que los complementos tengan sus propias dependencias y el
elemento AssemblyDependencyResolver facilita la tarea de cargar correctamente las dependencias.
Ahora que el proyecto AppWithPlugin tiene el tipo PluginLoadContext , actualice el método Program.LoadPlugin con
el cuerpo siguiente:
static Assembly LoadPlugin(string relativePath)
{
// Navigate up to the solution root
string root = Path.GetFullPath(Path.Combine(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));

string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\',


Path.DirectorySeparatorChar)));
Console.WriteLine($"Loading commands from: {pluginLocation}");
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);
return loadContext.LoadFromAssemblyName(new
AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
}

Al usar una instancia de PluginLoadContext diferente para cada complemento, los complementos puede tener
dependencias diferentes o incluso en conflicto sin ningún problema.

Complemento simple sin dependencias


En la carpeta raíz, siga estos pasos:
1. Ejecute el siguiente comando para crear un nuevo proyecto de biblioteca de clases denominado
HelloPlugin :

dotnet new classlib -o HelloPlugin

2. Ejecute el siguiente comando para agregar el proyecto a la solución AppWithPlugin :

dotnet sln add HelloPlugin/HelloPlugin.csproj

3. Reemplace el archivo HelloPlugin/Class1.cs con un archivo denominado HelloCommand.cs con el contenido


siguiente:

using PluginBase;
using System;

namespace HelloPlugin
{
public class HelloCommand : ICommand
{
public string Name { get => "hello"; }
public string Description { get => "Displays hello message."; }

public int Execute()


{
Console.WriteLine("Hello !!!");
return 0;
}
}
}

Ahora, abra el archivo HelloPlugin.csproj. Debería tener un aspecto similar al siguiente:


<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

</Project>

Entre las etiquetas <Project> , agregue los elementos siguientes:

<ItemGroup>
<ProjectReference Include="..\PluginBase\PluginBase.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>

El elemento <Private>false</Private> es importante. Indica a MSBuild que no copie PluginBase.dll en el directorio


de salida para HelloPlugin. Si el ensamblado PluginBase.dll está presente en el directorio de salida,
PluginLoadContext encontrará el ensamblado y lo cargará cuando cargue el ensamblado HelloPlugin.dll. En este
momento, el tipo HelloPlugin.HelloCommand implementará la interfaz ICommand de PluginBase.dll en el directorio de
salida del proyecto HelloPlugin , no la interfaz ICommand que se carga en el contexto de carga predeterminado.
Como el runtime considera que estos dos tipos son tipos diferentes de ensamblados distintos, el método
AppWithPlugin.Program.CreateCommands no encontrará los comandos. Como resultado, los metadatos
<Private>false</Private> son necesarios para la referencia al ensamblado que contiene las interfaces de
complemento.
Ahora que se ha completado el proyecto HelloPlugin , se debe actualizar el proyecto AppWithPlugin para saber
dónde se puede encontrar el complemento HelloPlugin . Después del comentario // Paths to plugins to load ,
agregue @"HelloPlugin\bin\Debug\netcoreapp3.0\HelloPlugin.dll" como un elemento de la matriz pluginPaths .

Complemento con dependencias de biblioteca


Casi todos los complementos son más complejos que un simple ejemplo "Hola mundo", y muchos tienen
dependencias en otras bibliotecas. En los proyectos de complemento JsonPlugin y OldJson del ejemplo se
muestran dos ejemplos de complementos con dependencias de paquetes NuGet en Newtonsoft.Json . Los propios
archivos del proyecto no tienen información especial para las referencias del proyecto y, después de agregar las
rutas de acceso de complemento a la matriz pluginPaths , los complementos se ejecutan perfectamente, incluso en
la misma ejecución de la aplicación AppWithPlugin. Pero estos proyectos no copian los ensamblados a los que se
hace referencia en su directorio de salida, por lo que los ensamblados deben estar presentes en la máquina del
usuario para que los complementos funcionen. Hay dos maneras de solucionar este problema. La primera opción
consiste en usar el comando dotnet publish para publicar la biblioteca de clases. Como alternativa, si quiere poder
usar la salida de dotnet build para el complemento, puede agregar la propiedad
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> entre las etiquetas <PropertyGroup> del archivo
de proyecto del complemento. Vea el proyecto de complemento XcopyablePlugin para obtener un ejemplo.

Otros ejemplos en la muestra


Puede encontrar el código fuente completo para este tutorial en el repositorio dotnet/samples. El ejemplo completo
incluye algunos otros ejemplos de comportamiento AssemblyDependencyResolver . Por ejemplo, el objeto
AssemblyDependencyResolver también puede resolver las bibliotecas nativas, así como los ensamblados satélite
localizados en paquetes NuGet. UVPlugin y FrenchPlugin en el repositorio de ejemplos demuestran estos
escenarios.
Referencia a un complemento desde un paquete NuGet
Supongamos que hay una aplicación A que tiene una interfaz de complemento definida en el paquete NuGet
denominado A.PluginBase . ¿Cómo se hace referencia correctamente al paquete en el proyecto de complemento?
Para las referencias de proyecto, el uso de los metadatos <Private>false</Private> en el elemento
ProjectReference del archivo de proyecto ha impedido que el archivo DLL se copiara en la salida.

Para hacer referencia correctamente al paquete A.PluginBase , le interesará cambiar el elemento


<PackageReference> del archivo de proyecto por lo siguiente:

<PackageReference Include="A.PluginBase" Version="1.0.0">


<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>

Esto evita que los ensamblados A.PluginBase se copien en el directorio de salida del complemento y asegura que
el complemento use la versión de A.PluginBase la aplicación A.

Recomendaciones para plataformas de destino de complemento


Como en la carga de dependencias de complemento se usa el archivo deps.json, hay un problema relacionado con
la plataforma de destino del complemento. En concreto, los complementos deben tener como destino un runtime
como .NET Core 3.0, en lugar de una versión de .NET Standard. El archivo .deps.json se genera en función de la
plataforma de destino del proyecto y, como muchos paquetes compatibles con .NET Standard incluyen
ensamblados de referencia para compilar en .NET Standard y ensamblados de implementación para runtimes
específicos, es posible que el archivo .deps.json no vea correctamente los ensamblados de implementación, o bien
que tome la versión de .NET Standard de un ensamblado en lugar de la de .NET Core que se espera.

Referencias del marco de trabajo de complementos


En la actualidad, los complementos no pueden introducir nuevos marcos en el proceso. Por ejemplo, no puede
cargar un complemento que use el marco Microsoft.AspNetCore.App en una aplicación en la que solo se use el
marco Microsoft.NETCore.App raíz. La aplicación host debe declarar referencias a todos los marcos de trabajo
necesarios para los complementos.
Introducción a ASP.NET Core
12/01/2020 • 2 minutes to read • Edit Online

Para ver tutoriales sobre el desarrollo de aplicaciones web ASP.NET Core, vea los tutoriales de ASP.NET Core.
Escritura de un host personalizado de .NET Core
para controlar el entorno de tiempo de ejecución de
.NET desde el código nativo
20/01/2020 • 36 minutes to read • Edit Online

Como todo el código administrado, las aplicaciones de .NET Core se ejecutan mediante un host. El host es
responsable de iniciar el entorno de ejecución (incluidos componentes como el JIT y el recolector de elementos no
utilizados) y de invocar puntos de entrada administrados.
Hospedar el runtime de .NET Core es un escenario avanzado y, en la mayoría de los casos, los desarrolladores de
.NET Core no necesitan preocuparse sobre el hospedaje porque los procesos de compilación de .NET Core
proporcionan un host predeterminado para ejecutar aplicaciones de .NET Core. En cambio, en algunas
circunstancias especializadas, puede ser útil hospedar explícitamente el runtime de .NET Core, como un medio
para invocar código administrado en un proceso nativo o para obtener más control sobre el funcionamiento del
runtime.
En este artículo se proporciona información general sobre los pasos necesarios para iniciar el entorno de ejecución
.NET Core desde código nativo y ejecutar código administrado en él.

Requisitos previos
Como los hosts son aplicaciones nativas, este tutorial trata la creación de una aplicación de C++ para hospedar
.NET Core. Necesitará un entorno de desarrollo de C++ (como el que se proporciona mediante Visual Studio).
También querrá una aplicación de .NET Core sencilla con la que probar el host, por lo que debe instalar el SDK de
.NET Core y crear una pequeña aplicación de prueba de .NET Core (como una aplicación "Hola a todos"). La
aplicación "Hola a todos" que se ha creado mediante la nueva plantilla de proyecto de la consola de .NET Core es
suficiente.

API de hospedaje
Hay tres API distintas que pueden usarse para hospedar .NET Core. En este artículo (y sus ejemplos asociados) se
tratan todas las opciones.
El método preferido para hospedar el tiempo de ejecución de .NET Core en .NET Core 3.0 y superior es con las
APIs de las bibliotecas nethost y hostfxr . Estos puntos de entrada tratan la complejidad de buscar y
configurar el entorno de ejecución para la inicialización y permiten tanto el inicio de una aplicación
administrada como la llamada a un método administrado estático.
El método preferido para hospedar el entorno de ejecución .NET Core antes de la versión .NET Core 3.0 es con
CoreClrHost.h API. Esta API expone funciones para iniciar y detener fácilmente el entorno de ejecución e
invocar código administrado (ya sea mediante el inicio de un archivo .exe administrado o una llamada a
métodos estáticos administrados).
.NET Core también se puede hospedar con la interfaz ICLRRuntimeHost4 de mscoree.h. Esta API se emplea
desde antes que CoreClrHost.h, así que es posible que haya visto que hosts antiguos la usaban. Aún funciona y
ofrece un poco más de control sobre el proceso de hospedaje que CoreClrHost. Pero en la mayoría de los
escenarios se prefiere CoreClrHost.h, ya que tiene API más sencillas.

Hosts de ejemplo
Hay hosts de ejemplo que muestran los pasos descritos en los tutoriales siguientes en el repositorio
dotnet/samples de GitHub. Los comentarios de los ejemplos asocian claramente los pasos numerados de estos
tutoriales con el lugar donde se realizan en el ejemplo. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Tenga en cuenta que los hosts de ejemplo están pensados para usarse con fines de aprendizaje, por lo que pasan
por encima de la comprobación de errores y están diseñados para enfatizar la legibilidad sobre la eficacia.

Creación de un host con NetHost.h y HostFxr.h


En los siguientes pasos se explica cómo usar las bibliotecas nethost y hostfxr para iniciar el entorno de
ejecución de .NET Core en una aplicación nativa y llamar a un método estático administrado. En el ejemplo se
utiliza el encabezado nethost y la biblioteca instalados con el SDK de .NET así como copias de los archivos
coreclr_delegates.h y hostfxr.h del repositorio dotnet/core-setup.

Paso 1: Carga de HostFxr y obtención de funciones de hospedaje exportadas


La biblioteca nethost proporciona la función get_hostfxr_path para buscar la biblioteca hostfxr . La biblioteca
hostfxr expone funciones para hospedar el entorno de ejecución de .NET Core. Encontrará la lista completa de
funciones en hostfxr.h y en el documento de diseño de hospedaje nativo. El ejemplo y este tutorial usan lo
siguiente:
hostfxr_initialize_for_runtime_config : Inicializa un contexto de host y se prepara para la inicialización del
entorno de ejecución de .NET Core mediante la configuración del entorno de ejecución especificado.
hostfxr_get_runtime_delegate : Obtiene un delegado para la funcionalidad del entorno de ejecución.
hostfxr_close : Cierra un contexto del host.

La biblioteca hostfxr se encuentra mediante get_hostfxr_path . Después, se carga y se recuperan las


exportaciones.

// Using the nethost library, discover the location of hostfxr and get exports
bool load_hostfxr()
{
// Pre-allocate a large buffer for the path to hostfxr
char_t buffer[MAX_PATH];
size_t buffer_size = sizeof(buffer) / sizeof(char_t);
int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
if (rc != 0)
return false;

// Load hostfxr and get desired exports


void *lib = load_library(buffer);
init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib,
"hostfxr_initialize_for_runtime_config");
get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close");

return (init_fptr && get_delegate_fptr && close_fptr);


}

Paso 2: Inicialización e inicio del entorno de ejecución de .NET Core


Las funciones hostfxr_initialize_for_runtime_config y hostfxr_get_runtime_delegate inicializan e inician el
entorno de ejecución de .NET Core con la configuración del entorno de ejecución para el componente
administrado que se va a cargar. La función hostfxr_get_runtime_delegate se utiliza para obtener un delegado del
entorno de ejecución que permite cargar un ensamblado administrado y obtener un puntero de función para un
método estático en ese ensamblado.
// Load and initialize .NET Core and get desired function pointer for scenario
load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t *config_path)
{
// Load .NET Core
void *load_assembly_and_get_function_pointer = nullptr;
hostfxr_handle cxt = nullptr;
int rc = init_fptr(config_path, nullptr, &cxt);
if (rc != 0 || cxt == nullptr)
{
std::cerr << "Init failed: " << std::hex << std::showbase << rc << std::endl;
close_fptr(cxt);
return nullptr;
}

// Get the load assembly function pointer


rc = get_delegate_fptr(
cxt,
hdt_load_assembly_and_get_function_pointer,
&load_assembly_and_get_function_pointer);
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
std::cerr << "Get delegate failed: " << std::hex << std::showbase << rc << std::endl;

close_fptr(cxt);
return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer;
}

Paso 3: Carga del ensamblado administrado y obtención un puntero de función a un método administrado
Se llama al delegado del entorno de ejecución para cargar el ensamblado administrado y obtener un puntero de
función a un método administrado. El delegado necesita la ruta de acceso de ensamblado, el nombre del tipo y el
nombre del método como entradas y devuelve un puntero de función que se puede utilizar para llamar al método
administrado.

// Function pointer to managed delegate


component_entry_point_fn hello = nullptr;
int rc = load_assembly_and_get_function_pointer(
dotnetlib_path.c_str(),
dotnet_type,
dotnet_type_method,
nullptr /*delegate_type_name*/,
nullptr,
(void**)&hello);

Al pasar nullptr como nombre de tipo de delegado al llamar al delegado del entorno de ejecución, el ejemplo
utiliza una firma predeterminada para el método administrado:

public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);

Se puede utilizar una firma diferente si se especifica el nombre del tipo de delegado al llamar al delegado en
entorno de ejecución.
Paso 4: Ejecutar el código administrado
El host nativo ahora puede llamar al método administrado y pasarle los parámetros deseados.
lib_args args
{
STR("from host!"),
i
};

hello(&args, sizeof(args));

Creación de un host mediante CoreClrHost.h


En los siguientes pasos se explica cómo usar la API CoreClrHost.h para iniciar el entorno de ejecución .NET Core
en una aplicación nativa y llamar a un método administrado estático. Los fragmentos de código de este documento
usan algunas API específicas de Windows, pero el host de ejemplo completo muestra las rutas de acceso de código
de Windows y Linux.
El host Unix CoreRun muestra un ejemplo más complejo y real de hospedaje mediante coreclrhost.h.
Paso 1: Buscar y cargar CoreCLR
Las API del entorno de ejecución .NET Core están en coreclr.dll (en Windows), en libcoreclr.so (en Linux) o en
libcoreclr.dylib (en macOS ). El primer paso para el hospedaje de .NET Core es cargar la biblioteca de CoreCLR.
Algunos hosts sondean diferentes rutas de acceso o usan parámetros de entrada para buscar la biblioteca,
mientras que otros saben cargarla desde una ruta de acceso determinada (junto al host, por ejemplo, o desde una
ubicación de todo el equipo).
Una vez encontrada, la biblioteca se carga con LoadLibraryEx (en Windows) o dlopen (en Linux o macOS ).

HMODULE coreClr = LoadLibraryExA(coreClrPath.c_str(), NULL, 0);

Paso 2: Obtener las funciones de hospedaje de .NET Core


CoreClrHost tiene varios métodos importantes de utilidad para el hospedaje de .NET Core:
coreclr_initialize : Inicia el entorno de ejecución .NET Core y configura el valor AppDomain predeterminado
(y único).
coreclr_execute_assembly : Ejecuta un ensamblado administrado.
coreclr_create_delegate : Crea un puntero de función a un método administrado.
coreclr_shutdown : Cierra el entorno de ejecución .NET Core.
coreclr_shutdown_2 : Es igual que coreclr_shutdown , pero además recupera el código de salida del código
administrado.
Después de cargar la biblioteca de CoreCLR, el siguiente paso es obtener referencias a estas funciones mediante
GetProcAddress (en Windows) o dlsym (en Linux o macOS ).

coreclr_initialize_ptr initializeCoreClr = (coreclr_initialize_ptr)GetProcAddress(coreClr,


"coreclr_initialize");
coreclr_create_delegate_ptr createManagedDelegate = (coreclr_create_delegate_ptr)GetProcAddress(coreClr,
"coreclr_create_delegate");
coreclr_shutdown_ptr shutdownCoreClr = (coreclr_shutdown_ptr)GetProcAddress(coreClr, "coreclr_shutdown");

Paso 3: Preparar las propiedades del entorno de ejecución


Antes de iniciar el entorno de ejecución, es necesario preparar algunas propiedades para especificar el
comportamiento (especialmente las relacionadas con el cargador de ensamblados).
Algunas propiedades comunes incluyen:
TRUSTED_PLATFORM_ASSEMBLIES Esta es una lista de rutas de acceso de ensamblado (delimitadas por ";" en
Windows y ":" en Linux) que el entorno de ejecución puede resolver de forma predeterminada. Algunos hosts
tienen manifiestos codificados de forma rígida que enumeran los ensamblados que pueden cargar. Otros
colocan cualquier biblioteca en determinadas ubicaciones (junto a coreclr.dll, por ejemplo) en esta lista.
APP_PATHS Esta es una lista de rutas de acceso para explorar un ensamblado si este no puede encontrarse en la
lista de ensamblados de plataforma de confianza (TPA). Dado que el host tiene más control sobre los
ensamblados que se cargan mediante la lista TPA, es recomendable que los hosts determinen qué ensamblados
esperan cargar y los muestren de forma explícita. Pero si es necesario sondear en tiempo de ejecución, esta
propiedad puede habilitar ese escenario.
APP_NI_PATHS Esta lista es similar a APP_PATHS, excepto que son las rutas de acceso las que se sondean en
busca de imágenes nativas.
NATIVE_DLL_SEARCH_DIRECTORIES Esta propiedad es una lista de rutas de acceso que el cargador debe sondear
cuando busca bibliotecas nativas llamadas mediante p/invoke.
PLATFORM_RESOURCE_ROOTS Esta lista incluye rutas de acceso que se van a explorar para ensamblados satélite de
recursos (en subdirectorios específicos de la referencia cultural).
En este host de ejemplo, la lista TPA se construye simplemente mediante la enumeración de todas las bibliotecas
del directorio actual:

void BuildTpaList(const char* directory, const char* extension, std::string& tpaList)


{
// This will add all files with a .dll extension to the TPA list.
// This will include unmanaged assemblies (coreclr.dll, for example) that don't
// belong on the TPA list. In a real host, only managed assemblies that the host
// expects to load should be included. Having extra unmanaged assemblies doesn't
// cause anything to fail, though, so this function just enumerates all dll's in
// order to keep this sample concise.
std::string searchPath(directory);
searchPath.append(FS_SEPARATOR);
searchPath.append("*");
searchPath.append(extension);

WIN32_FIND_DATAA findData;
HANDLE fileHandle = FindFirstFileA(searchPath.c_str(), &findData);

if (fileHandle != INVALID_HANDLE_VALUE)
{
do
{
// Append the assembly to the list
tpaList.append(directory);
tpaList.append(FS_SEPARATOR);
tpaList.append(findData.cFileName);
tpaList.append(PATH_DELIMITER);

// Note that the CLR does not guarantee which assembly will be loaded if an assembly
// is in the TPA list multiple times (perhaps from different paths or perhaps with different
NI/NI.dll
// extensions. Therefore, a real host should probably add items to the list in priority order and
only
// add a file if it's not already present on the list.
//
// For this simple sample, though, and because we're only loading TPA assemblies from a single
path,
// and have no native images, we can ignore that complication.
}
while (FindNextFileA(fileHandle, &findData));
FindClose(fileHandle);
}
}
Dado que el ejemplo es simple, solo necesita la propiedad TRUSTED_PLATFORM_ASSEMBLIES :

// Define CoreCLR properties


// Other properties related to assembly loading are common here,
// but for this simple sample, TRUSTED_PLATFORM_ASSEMBLIES is all
// that is needed. Check hosting documentation for other common properties.
const char* propertyKeys[] = {
"TRUSTED_PLATFORM_ASSEMBLIES" // Trusted assemblies
};

const char* propertyValues[] = {


tpaList.c_str()
};

Paso 4: Iniciar el entorno de ejecución


A diferencia de la API de hospedaje mscoree.h (que se describe a continuación), las API CoreCLRHost.h inician el
entorno de ejecución y crean el valor AppDomain predeterminado con una sola llamada. La función
coreclr_initialize toma una ruta de acceso base, un nombre y las propiedades descritas anteriormente y
devuelve un manipulador al host a través del parámetro hostHandle .

void* hostHandle;
unsigned int domainId;

// This function both starts the .NET Core runtime and creates
// the default (and only) AppDomain
int hr = initializeCoreClr(
runtimePath, // App base path
"SampleHost", // AppDomain friendly name
sizeof(propertyKeys) / sizeof(char*), // Property count
propertyKeys, // Property names
propertyValues, // Property values
&hostHandle, // Host handle
&domainId); // AppDomain ID

Paso 5: Ejecutar el código administrado


Con el entorno de ejecución iniciado, el host puede llamar al código administrado. Esta operación se puede realizar
de diferentes maneras. El código de ejemplo vinculado a este tutorial usa la función coreclr_create_delegate para
crear un delegado para un método administrado estático. Esta API toma el nombre del ensamblado, el nombre de
tipo calificado por el espacio de nombres y el nombre del método como entradas y devuelve un delegado que
puede usarse para invocar al método.

doWork_ptr managedDelegate;

// The assembly name passed in the third parameter is a managed assembly name
// as described at https://docs.microsoft.com/dotnet/framework/app-domains/assembly-names
hr = createManagedDelegate(
hostHandle,
domainId,
"ManagedLibrary, Version=1.0.0.0",
"ManagedLibrary.ManagedWorker",
"DoWork",
(void**)&managedDelegate);

En este ejemplo, el host ya puede llamar a managedDelegate para ejecutar el método ManagedWorker.DoWork .
También se puede usar la función coreclr_execute_assembly para iniciar un archivo ejecutable administrado. Esta
API toma una ruta de acceso de ensamblado y una matriz de argumentos como parámetros de entrada. Carga el
ensamblado en esa ruta de acceso e invoca a su método principal.
int hr = executeAssembly(
hostHandle,
domainId,
argumentCount,
arguments,
"HelloWorld.exe",
(unsigned int*)&exitCode);

Paso 6: Cerrar y limpiar


Por último, cuando el host termina de ejecutar el código administrado, el entorno de ejecución .NET Core se cierra
con coreclr_shutdown o coreclr_shutdown_2 .

hr = shutdownCoreClr(hostHandle, domainId);

CoreCLR no admite la reinicialización ni la descarga. No vuelva a llamar a coreclr_initialize ni descargue la


biblioteca de CoreCLR.

Creación de un host con Mscoree.h


Como se ha mencionado anteriormente, CoreClrHost.h es ahora el método preferido para hospedar el entorno de
ejecución .NET Core. Pero todavía se puede usar la interfaz ICLRRuntimeHost4 si las interfaces de CoreClrHost.h no
bastan (si se necesitan marcas de inicio no estándar, por ejemplo, o si se necesita un valor AppDomainManager en
el dominio predeterminado). Estas instrucciones le guían durante el proceso de hospedaje de .NET Core mediante
mscoree.h.
El host CoreRun muestra un ejemplo más complejo y real de hospedaje mediante mscoree.h.
Una nota sobre mscoree.h
La interfaz de hospedaje de .NET Core ICLRRuntimeHost4 se define en MSCOREE.IDL. Se genera una versión de
encabezado de este archivo (mscoree.h), que su host necesitará para hacer referencias, mediante MIDL cuando se
compila el runtime de .NET Core. Si no quiere compilar el runtime de .NET Core, mscoree.h también está
disponible como un encabezado pregenerado en el repositorio dotnet/runtime.
Paso 1: Identificar el punto de entrada administrado
Después de hacer referencia a los encabezados necesarios (mscoree.h y stdio.h, por ejemplo), una de las primeras
cosas que un host de .NET Core debe hacer es localizar el punto de entrada administrado que va a usar. En nuestro
host de ejemplo, esto se realiza simplemente tomando el primer argumento de la línea de comandos para nuestro
host como la ruta de acceso a un archivo binario administrado cuyo método main se va a ejecutar.

// The managed application to run should be the first command-line parameter.


// Subsequent command line parameters will be passed to the managed app later in this host.
wchar_t targetApp[MAX_PATH];
GetFullPathNameW(argv[1], MAX_PATH, targetApp, NULL);

Paso 2: Buscar y cargar CoreCLR


Las API del runtime de .NET Core están en CoreCLR.dll (en Windows). Para obtener nuestra interfaz de hospedaje
( ICLRRuntimeHost4 ), es necesario buscar y cargar CoreCLR.dll. Depende del host definir una convención sobre
cómo localizar CoreCLR.dll. Algunos hosts esperan que el archivo esté presente en una ubicación bien conocida de
todo el equipo (como %programfiles%\dotnet\shared\Microsoft.NETCore.App\2.1.6). Otros esperan que
CoreCLR.dll se cargará desde una ubicación junto al propio host o a la aplicación que se va a hospedar. Y otros
pueden consultar una variable de entorno para buscar la biblioteca.
En Linux o macOS, la biblioteca en tiempo de ejecución principal es libcoreclr.so o libcoreclr.dylib, respectivamente.
Nuestro host de ejemplo explora algunas ubicaciones comunes para CoreCLR.dll. Una vez que lo encuentra, debe
cargarse mediante LoadLibrary (o dlopen en Linux/macOS ).

HMODULE ret = LoadLibraryExW(coreDllPath, NULL, 0);

Paso 3: Obtención de una instancia de ICLRRuntimeHost4


La interfaz de hospedaje de ICLRRuntimeHost4 se recupera llamando a GetProcAddress (o dlsym en Linux/macOS )
en GetCLRRuntimeHost y, después, invocando esa función.

ICLRRuntimeHost4* runtimeHost;

FnGetCLRRuntimeHost pfnGetCLRRuntimeHost =
(FnGetCLRRuntimeHost)::GetProcAddress(coreCLRModule, "GetCLRRuntimeHost");

if (!pfnGetCLRRuntimeHost)
{
printf("ERROR - GetCLRRuntimeHost not found");
return -1;
}

// Get the hosting interface


HRESULT hr = pfnGetCLRRuntimeHost(IID_ICLRRuntimeHost4, (IUnknown**)&runtimeHost);

Paso 4: Establecimiento de marcas de inicio e inicio del entorno de ejecución


Con ICLRRuntimeHost4 disponible, ahora podemos especificar marcas de inicio en el runtime e iniciarlo. Las marcas
de inicio determinan qué recolector de elementos no utilizados (GC ) se va a usar (simultáneo o servidor), si se usa
un solo valor AppDomain o varios y qué directiva de optimización del cargador se va a usar (para la carga de
ensamblados con dominio neutro).

hr = runtimeHost->SetStartupFlags(
// These startup flags control runtime-wide behaviors.
// A complete list of STARTUP_FLAGS can be found in mscoree.h,
// but some of the more common ones are listed below.
static_cast<STARTUP_FLAGS>(
// STARTUP_FLAGS::STARTUP_SERVER_GC | // Use server GC
// STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN | // Maximize domain-neutral loading
// STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | // Domain-neutral loading for
strongly-named assemblies
STARTUP_FLAGS::STARTUP_CONCURRENT_GC | // Use concurrent GC
STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN | // All code executes in the default AppDomain
// (required to use the runtimeHost-
>ExecuteAssembly helper function)
STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN // Prevents domain-neutral loading
)
);

El runtime se inicia con una llamada a la función Start .

hr = runtimeHost->Start();

Paso 5: Preparar la configuración de AppDomain


Una vez que se inicie el runtime, querremos configurar un AppDomain. En cambio, existen varias opciones que
deben especificarse a la hora de crear un AppDomain de .NET, por lo que es necesario prepararlas primero.
Las marcas de AppDomain especifican comportamientos de AppDomain relacionados con la seguridad y la
interoperabilidad. Los hosts antiguos de Silverlight usaban esta configuración en el código de usuario de espacio
aislado, pero los hosts de .NET Core más modernos ejecutan el código de usuario como de plena confianza y
habilitan la interoperabilidad.

int appDomainFlags =
// APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS | // Do not pump messages during wait
// APPDOMAIN_SECURITY_SANDBOXED | // Causes assemblies not from the TPA list to be loaded as partially
trusted
APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS | // Enable platform-specific assemblies to run
APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP | // Allow PInvoking from non-TPA assemblies
APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT; // Entirely disables transparency checks

Después de decidir qué marcas de AppDomain se van a usar, deben definirse sus propiedades. Las propiedades
son pares clave-valor de cadenas. Muchas de las propiedades se refieren a la manera en que AppDomain cargará
ensamblados.
Las propiedades comunes de AppDomain incluyen:
TRUSTED_PLATFORM_ASSEMBLIES Esta es una lista de rutas de acceso de ensamblado (delimitada por ; en
Windows y : en Linux o macOS ) cuya carga debe priorizar AppDomain y a las que debe otorgar plena
confianza (incluso en dominios de confianza parcial). Esta lista está diseñada para contener ensamblados de
"Framework" y otros módulos de confianza, similares a los GAC en escenarios de .NET Framework. Algunos
hosts colocarán una biblioteca junto a coreclr.dll en esta lista, otros tienen manifiestos codificados de forma
rígida que enumeran ensamblados de confianza para sus fines.
APP_PATHS Esta es una lista de rutas de acceso para explorar un ensamblado si este no puede encontrarse en la
lista de ensamblados de plataforma de confianza (TPA). Dado que el host tiene más control sobre los
ensamblados que se cargan mediante la lista TPA, es recomendable que los hosts determinen qué ensamblados
esperan cargar y los muestren de forma explícita. Pero si es necesario sondear en tiempo de ejecución, esta
propiedad puede habilitar ese escenario.
APP_NI_PATHS Esta lista es muy similar a APP_PATHS excepto que está diseñada para ser rutas de acceso que se
explorarán para imágenes nativas.
NATIVE_DLL_SEARCH_DIRECTORIES Esta propiedad es una lista de rutas de acceso que el cargador debe explorar
cuando busca archivos DLL nativos que se han llamado mediante p/invoke.
PLATFORM_RESOURCE_ROOTS Esta lista incluye rutas de acceso que se van a explorar para ensamblados satélite de
recursos (en subdirectorios específicos de la referencia cultural).
En nuestro host de ejemplo sencillo, estas propiedades se configuran de la siguiente manera:

// TRUSTED_PLATFORM_ASSEMBLIES
// "Trusted Platform Assemblies" are prioritized by the loader and always loaded with full trust.
// A common pattern is to include any assemblies next to CoreCLR.dll as platform assemblies.
// More sophisticated hosts may also include their own Framework extensions (such as AppDomain managers)
// in this list.
size_t tpaSize = 100 * MAX_PATH; // Starting size for our TPA (Trusted Platform Assemblies) list
wchar_t* trustedPlatformAssemblies = new wchar_t[tpaSize];
trustedPlatformAssemblies[0] = L'\0';

// Extensions to probe for when finding TPA list files


const wchar_t *tpaExtensions[] = {
L"*.dll",
L"*.exe",
L"*.winmd"
};

// Probe next to CoreCLR.dll for any files matching the extensions from tpaExtensions and
// add them to the TPA list. In a real host, this would likely be extracted into a separate function
// and perhaps also run on other directories of interest.
for (int i = 0; i < _countof(tpaExtensions); i++)
{
// Construct the file name search pattern
// Construct the file name search pattern
wchar_t searchPath[MAX_PATH];
wcscpy_s(searchPath, MAX_PATH, coreRoot);
wcscat_s(searchPath, MAX_PATH, L"\\");
wcscat_s(searchPath, MAX_PATH, tpaExtensions[i]);

// Find files matching the search pattern


WIN32_FIND_DATAW findData;
HANDLE fileHandle = FindFirstFileW(searchPath, &findData);

if (fileHandle != INVALID_HANDLE_VALUE)
{
do
{
// Construct the full path of the trusted assembly
wchar_t pathToAdd[MAX_PATH];
wcscpy_s(pathToAdd, MAX_PATH, coreRoot);
wcscat_s(pathToAdd, MAX_PATH, L"\\");
wcscat_s(pathToAdd, MAX_PATH, findData.cFileName);

// Check to see if TPA list needs expanded


if (wcsnlen(pathToAdd, MAX_PATH) + (3) + wcsnlen(trustedPlatformAssemblies, tpaSize) >= tpaSize)
{
// Expand, if needed
tpaSize *= 2;
wchar_t* newTPAList = new wchar_t[tpaSize];
wcscpy_s(newTPAList, tpaSize, trustedPlatformAssemblies);
trustedPlatformAssemblies = newTPAList;
}

// Add the assembly to the list and delimited with a semi-colon


wcscat_s(trustedPlatformAssemblies, tpaSize, pathToAdd);
wcscat_s(trustedPlatformAssemblies, tpaSize, L";");

// Note that the CLR does not guarantee which assembly will be loaded if an assembly
// is in the TPA list multiple times (perhaps from different paths or perhaps with different
NI/NI.dll
// extensions. Therefore, a real host should probably add items to the list in priority order and
only
// add a file if it's not already present on the list.
//
// For this simple sample, though, and because we're only loading TPA assemblies from a single
path,
// we can ignore that complication.
}
while (FindNextFileW(fileHandle, &findData));
FindClose(fileHandle);
}
}

// APP_PATHS
// App paths are directories to probe in for assemblies which are not one of the well-known Framework
assemblies
// included in the TPA list.
//
// For this simple sample, we just include the directory the target application is in.
// More complex hosts may want to also check the current working directory or other
// locations known to contain application assets.
wchar_t appPaths[MAX_PATH * 50];

// Just use the targetApp provided by the user and remove the file name
wcscpy_s(appPaths, targetAppPath);

// APP_NI_PATHS
// App (NI) paths are the paths that will be probed for native images not found on the TPA list.
// It will typically be similar to the app paths.
// For this sample, we probe next to the app and in a hypothetical directory of the same name with 'NI'
suffixed to the end.
suffixed to the end.
wchar_t appNiPaths[MAX_PATH * 50];
wcscpy_s(appNiPaths, targetAppPath);
wcscat_s(appNiPaths, MAX_PATH * 50, L";");
wcscat_s(appNiPaths, MAX_PATH * 50, targetAppPath);
wcscat_s(appNiPaths, MAX_PATH * 50, L"NI");

// NATIVE_DLL_SEARCH_DIRECTORIES
// Native dll search directories are paths that the runtime will probe for native DLLs called via PInvoke
wchar_t nativeDllSearchDirectories[MAX_PATH * 50];
wcscpy_s(nativeDllSearchDirectories, appPaths);
wcscat_s(nativeDllSearchDirectories, MAX_PATH * 50, L";");
wcscat_s(nativeDllSearchDirectories, MAX_PATH * 50, coreRoot);

// PLATFORM_RESOURCE_ROOTS
// Platform resource roots are paths to probe in for resource assemblies (in culture-specific sub-directories)
wchar_t platformResourceRoots[MAX_PATH * 50];
wcscpy_s(platformResourceRoots, appPaths);

Paso 6: Crear el AppDomain


Una vez que todas las propiedades y marcas de AppDomain están preparadas,
ICLRRuntimeHost4::CreateAppDomainWithManager puede usarse para configurar el AppDomain. De manera opcional,
esta función toma un nombre completo del ensamblado y el nombre de tipo que se va a usar como el
administrador de AppDomain del dominio. Un administrador de AppDomain puede permitir un host para
controlar algunos aspectos del comportamiento de AppDomain y puede proporcionar puntos de entrada para
iniciar el código administrado si el host no pretende invocar el código de usuario directamente.

DWORD domainId;

// Setup key/value pairs for AppDomain properties


const wchar_t* propertyKeys[] = {
L"TRUSTED_PLATFORM_ASSEMBLIES",
L"APP_PATHS",
L"APP_NI_PATHS",
L"NATIVE_DLL_SEARCH_DIRECTORIES",
L"PLATFORM_RESOURCE_ROOTS"
};

// Property values which were constructed in step 5


const wchar_t* propertyValues[] = {
trustedPlatformAssemblies,
appPaths,
appNiPaths,
nativeDllSearchDirectories,
platformResourceRoots
};

// Create the AppDomain


hr = runtimeHost->CreateAppDomainWithManager(
L"Sample Host AppDomain", // Friendly AD name
appDomainFlags,
NULL, // Optional AppDomain manager assembly name
NULL, // Optional AppDomain manager type (including namespace)
sizeof(propertyKeys) / sizeof(wchar_t*),
propertyKeys,
propertyValues,
&domainId);

Paso 7: Ejecutar el código administrado


Con un AppDomain en funcionamiento, ahora el host puede comenzar a ejecutar el código administrado. La
manera más sencilla de hacer esto es usar ICLRRuntimeHost4::ExecuteAssembly para invocar un método de punto de
entrada del ensamblado administrado. Tenga en cuenta que esta función solo funciona en escenarios de dominio
único.

DWORD exitCode = -1;


hr = runtimeHost->ExecuteAssembly(domainId, targetApp, argc - 1, (LPCWSTR*)(argc > 1 ? &argv[1] : NULL),
&exitCode);

Otra opción, si ExecuteAssembly no satisface las necesidades del host, es usar CreateDelegate para crear un
puntero de función a un método administrado estático. Esto requiere que el host conozca la firma del método al
que está llamando (para crear el tipo de puntero de función), pero permite a los hosts tener flexibilidad para
invocar código que no sea el punto de entrada del ensamblado. El nombre del ensamblado proporcionado en el
segundo parámetro es el nombre del ensamblado administrado completo de la biblioteca que se va a cargar.

void *pfnDelegate = NULL;


hr = runtimeHost->CreateDelegate(
domainId,
L"HW, Version=1.0.0.0, Culture=neutral", // Target managed assembly
L"ConsoleApplication.Program", // Target managed type
L"Main", // Target entry point (static method)
(INT_PTR*)&pfnDelegate);

((MainMethodFp*)pfnDelegate)(NULL);

Paso 8: Limpiar
Por último, el host debe limpiarse después descargando AppDomains, deteniendo el runtime y lanzando la
referencia ICLRRuntimeHost4 .

runtimeHost->UnloadAppDomain(domainId, true /* Wait until unload complete */);


runtimeHost->Stop();
runtimeHost->Release();

CoreCLR no admite la descarga. No descargue la biblioteca de CoreCLR.

Conclusión
Una vez que se ha compilado el host, este puede probarse si se ejecuta desde la línea de comandos y se pasa
cualquier argumento que espere el host (como la aplicación administrada que se va a ejecutar para el host de
ejemplo mscoree). Al especificar la aplicación de .NET Core para el host que se va a ejecutar, asegúrese de usar el
archivo .dll que ha generado dotnet build . Los archivos ejecutables (archivos .exe) que ha generado
dotnet publish para las aplicaciones autocontenidas son realmente el host de .NET Core predeterminado (de
manera que la aplicación pueda iniciarse directamente desde la línea de comandos en escenarios principales); el
código de usuario se compila en un archivo .dll del mismo nombre.
Si las cosas no funcionan inicialmente, vuelva a comprobar que coreclr.dll está disponible en la ubicación que
espera el host, que todas las bibliotecas de Framework necesarias están en la lista TPA y que el valor de bits de
CoreCLR (32 o 64 bits) coincide con la manera en que se ha compilado el host.
Hospedar el runtime de .NET Core es un escenario avanzado que muchos desarrolladores no necesitarán, pero
para los que necesiten iniciar el código administrado desde un proceso nativo, o que necesiten más control sobre
el comportamiento del runtime de .NET Core, puede resultar muy útil.
Opciones de configuración en tiempo de ejecución
de .NET Core
05/12/2019 • 3 minutes to read • Edit Online

.NET Core admite el uso de archivos de configuración y variables de entorno para configurar el comportamiento
de las aplicaciones .NET Core en tiempo de ejecución. La configuración en tiempo de ejecución es una opción
atractiva si:
No se posee ni controla el código fuente de una aplicación y, por tanto, no puede configurarlo mediante
programación.
Varias instancias de la aplicación se ejecutan al mismo tiempo en un solo sistema y se quiere configurar cada
una para un rendimiento óptimo.

NOTE
Esta documentación está en desarrollo. Si observa que la información que se presenta aquí está incompleta o es inexacta,
abra una incidencia para informarnos sobre ella o envíe una solicitud de incorporación de cambios para solucionarla. Para
obtener información sobre el envío de solicitudes de incorporación de cambios para el repositorio dotnet/docs, consulte la
guía del colaborador.

.NET Core ofrece los siguientes mecanismos para configurar aplicaciones en tiempo de ejecución:
El archivo runtimeconfig.json
Variables de entorno
Los artículos de esta sección de la documentación incluida están organizados por categoría, como, por ejemplo,
depuración y recolección de elementos no utilizados. Si procede, las opciones de configuración disponibles se
muestran para runtimeconfig.json (solo .NET Core), app.config (solo .NET Framework) y las variables de entorno.

runtimeconfig.json
Especifique las opciones de configuración en tiempo de ejecución en la sección configProperties del archivo
runtimeconfig.json de la aplicación. Esta sección tiene el formato siguiente:

{
"runtimeOptions": {
"configProperties": {
"config-property-name1": "config-value1",
"config-property-name2": "config-value2"
}
}
}

Aquí tiene un archivo de ejemplo:


{
"runtimeOptions": {
"configProperties": {
"System.GC.Concurrent": true,
"System.GC.RetainVM": true,
"System.Threading.ThreadPool.MinThreads": "4",
"System.Threading.ThreadPool.MaxThreads": "25"
}
}
}

El archivo runtimeconfig.json se crea automáticamente en el directorio de compilación mediante el comando


dotnet build. También se crea al seleccionar la opción de menú Compilar en Visual Studio. Una vez creado, puede
editar el archivo.
Algunos valores de configuración también se pueden establecer mediante programación llamando al
método AppContext.SetSwitch.

Variables de entorno
Las variables de entorno se pueden usar para proporcionar información de configuración del entorno de ejecución.
Los botones de configuración especificados como variables de entorno generalmente tienen el prefijo COMPlus_ .
Puede definir variables de entorno desde el Panel de control de Windows, en la línea de comandos o mediante
programación llamando al método Environment.SetEnvironmentVariable(String, String) en sistemas basados en
Windows y Unix.
En los siguientes ejemplos se muestra cómo establecer una variable de entorno en la línea de comandos:

# Windows
set COMPlus_GCRetainVM=1

# Powershell
$env:COMPlus_GCRetainVM="1"

# Unix
export COMPlus_GCRetainVM=1
Opciones de configuración del entorno de ejecución
para compilación
18/12/2019 • 2 minutes to read • Edit Online

Compilación en niveles
Configura si el compilador JIT utiliza la compilación en niveles.
En la versión 3.0 de .NET Core y posteriores, la compilación en niveles está habilitada de forma predeterminada.
En las versiones 2.1 y 2.2 de .NET Core, la compilación en niveles está deshabilitada de forma predeterminada.

NOMBRE DEL VALOR VALORES

runtimeconfig.json System.Runtime.TieredCompilation true : habilitado.


false : deshabilitado.

Variable del entorno COMPlus_TieredCompilation 1 : habilitado.


0 : deshabilitado.
Opciones de configuración del ejecución para la
depuración y la generación de perfiles
18/12/2019 • 2 minutes to read • Edit Online

Habilitación de diagnósticos
Configura si el depurador, el generador de perfiles y los diagnósticos de EventPipe están habilitados o
deshabilitados.
Predeterminado: habilitado ( 1 ).

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno COMPlus_EnableDiagnostics 1 : habilitado.


0 : deshabilitado.

Habilitación de la generación de perfiles


Configura si la generación de perfiles está habilitada para el proceso que se ejecuta actualmente.
Predeterminado: deshabilitado ( 0 ).

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno CORECLR_ENABLE_PROFILING 0 : deshabilitado.


1 : habilitado.

GUID de generador de perfiles


Especifica el GUID del generador de perfiles que se va a cargar en el proceso que se ejecuta actualmente.

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno CORECLR_PROFILER string-guid

Ubicación del generador de perfiles


Especifica la ruta de acceso a la biblioteca de vínculos dinámicos del generador de perfiles que se va a cargar en
el proceso que se ejecuta actualmente (proceso de 32 bits o de 64 bits).
Si se establece más de una variable, las variables concretas de valor de bits tienen prioridad. Especifican el valor
de bits del generador de perfiles que se va a cargar.
Para obtener más información, vea Búsqueda de la biblioteca del generador de perfiles.
NOMBRE DEL VALOR VALORES

Variable del entorno CORECLR_PROFILER_PATH string-path

Variable del entorno CORECLR_PROFILER_PATH_32 string-path

Variable del entorno CORECLR_PROFILER_PATH_64 string-path

Escritura del mapa de rendimiento


Habilita o deshabilita la escritura de /tmp/perf-$pid.map en los sistemas Linux.
Predeterminado: deshabilitado ( 0 ).

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno COMPlus_PerfMapEnabled 0 : deshabilitado.


1 : habilitado.

Marcadores del registro de rendimiento


Cuando COMPlus_PerfMapEnabled se establece en 1 , habilita o deshabilita la señal especificada que se va a
aceptar y omitir como marcador en los registros de rendimiento.
Predeterminado: deshabilitado ( 0 ).

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno COMPlus_PerfMapIgnoreSignal 0 : deshabilitado.


1 : habilitado.
Opciones de configuración del entorno de ejecución
para la recolección de elementos no utilizados
20/01/2020 • 17 minutes to read • Edit Online

Esta página contiene información sobre la configuración del recolector de elementos no utilizados (GC ) que se
puede cambiar en el entorno de ejecución. Si intenta lograr el máximo rendimiento de una aplicación en ejecución,
valore la posibilidad de usar esta configuración. Sin embargo, los valores predeterminados proporcionan un
rendimiento óptimo para la mayoría de aplicaciones en situaciones habituales.
En esta página, la configuración se organiza en grupos. La configuración de cada grupo se usa normalmente junto
con las otras para lograr un resultado concreto.

NOTE
La aplicación también puede cambiar dinámicamente esta configuración mientras se ejecuta, por lo que se puede invalidar
cualquier valor del entorno de ejecución que haya establecido.
Por lo general, algunos valores de configuración, como el nivel de latencia, se establecen únicamente a través de la API en
tiempo de diseño. Estos valores se omiten en esta página.
En el caso de los valores numéricos, use la notación decimal para la configuración del archivo runtimeconfig.json y la
notación hexadecimal para la configuración de las variables de entorno. Para los valores hexadecimales, puede
especificarlos con o sin el prefijo "0x".

Tipos de recolección de elementos no utilizados


Los dos tipos principales de recolección de elementos no utilizados son la GC de estación de trabajo y la de
servidor. Para obtener más información sobre la diferencia entre estos dos tipos, vea Fundamentos de la
recolección de elementos no utilizados.
Los subtipos de la recolección de elementos no utilizados son en segundo plano y no simultáneos.
Use la configuración siguiente para seleccionar los tipos de la recolección de elementos no utilizados:
System.GC.Server/COMPlus_gcServer
Configura si la aplicación usa la recolección de elementos no utilizados de estación de trabajo o la de servidor.
Predeterminado: recolección de elementos no utilizados de estación de trabajo ( false ).

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.Server false : estación de trabajo. .NET Core 1.0


true : servidor.

Variable del entorno COMPlus_gcServer 0 : estación de trabajo. .NET Core 1.0


1 : servidor.

app.config para .NET GCServer false : estación de trabajo.


Framework true : servidor.

Ejemplo:
{
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
}
}

System.GC.Concurrent/COMPlus_gcConcurrent
Configura si está habilitada la recolección de elementos no utilizados en segundo plano (simultánea).
Predeterminado: habilitado ( true ).
Para obtener más información, vea Recolección de elementos no utilizados en segundo plano y Recolección de
elementos no utilizados de servidor en segundo plano.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.Concurrent true : GC en segundo .NET Core 1.0


plano.
false : GC no simultáneo.

Variable del entorno COMPlus_gcConcurrent true : GC en segundo .NET Core 1.0


plano.
false : GC no simultáneo.

app.config para .NET gcConcurrent true : GC en segundo


Framework plano.
false : GC no simultáneo.

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.Concurrent": false
}
}
}

Administración del uso de recursos


Use los valores descritos en esta sección para administrar el uso del procesador y la memoria del recolector de
elementos no utilizados.
Para obtener más información sobre algunos de estos valores, vea la entrada de blog en la que se detalla el
término medio entre la GC de la estación de trabajo y del servidor.
System.GC.HeapCount/COMPlus_GCHeapCount
Limita el número de montones creados por el recolector de elementos no utilizados.
Solo se aplica a la recolección de elementos no utilizados del servidor.
Si la afinidad del procesador de GC está habilitada, que es el valor predeterminado de esta opción, el valor del
recuento de montones establece afinidad entre n montones o subprocesos de GC en los primeros n
procesadores. (Utilice la configuración pertinente para establecer la afinidad entre una máscara o entre rangos
para especificar exactamente los procesadores entre los que se va a establecer afinidad).
Si está deshabilitada la afinidad del procesador de GC, esta configuración limita el número de montones de GC.
Para obtener más información, vea la sección Comentarios de GCHeapCount.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.HeapCount valor decimal .NET Core 3.0

Variable del entorno COMPlus_GCHeapCount valor hexadecimal .NET Core 3.0

app.config para .NET GCHeapCount valor decimal .NET Framework 4.6.2


Framework

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.HeapCount": 16
}
}
}

TIP
Si configura la opción en runtimeconfig.json, especifique un valor decimal. Si configura la opción como una variable de
entorno, especifique un valor hexadecimal. Por ejemplo, para limitar el número de montones a 16, los valores serían 16 para
el archivo JSON y 0x10 o 10 para la variable de entorno.

System.GC.HeapAffinitizeMask/COMPlus_GCHeapAffinitizeMask
Especifica los procesadores exactos que deben usar los subprocesos del recolector de elementos no utilizados.
Si la afinidad del procesador está deshabilitada estableciendo System.GC.NoAffinitize en true , esta
configuración se omite.
Solo se aplica a la recolección de elementos no utilizados del servidor.
El valor es una máscara de bits que define los procesadores que están disponibles para el proceso. Por ejemplo,
un valor decimal de 1023 (o un valor hexadecimal de 0x3FF o 3FF si utiliza la variable de entorno) es 0011
1111 1111 en notación binaria. Esto especifica que se usarán los 10 primeros procesadores. Para especificar los
10 procesadores siguientes, es decir, los procesadores 10-19, especifique un valor decimal de 1047552 (o un
valor hexadecimal de 0xFFC00 o FFC00), que es equivalente a un valor binario de 1111 1111 1100 0000 0000.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.HeapAffinitizeMask valor decimal .NET Core 3.0

Variable del entorno COMPlus_GCHeapAffinitizeMask valor hexadecimal .NET Core 3.0

app.config para .NET GCHeapAffinitizeMask valor decimal .NET Framework 4.6.2


Framework

Ejemplo:
{
"runtimeOptions": {
"configProperties": {
"System.GC.HeapAffinitizeMask": 1023
}
}
}

System.GC.GCHeapAffinitizeRanges/COMPlus_GCHeapAffinitizeRanges
Especifica la lista de procesadores que se van a usar para los subprocesos del recolector de elementos no
utilizados.
Este valor es similar a System.GC.HeapAffinitizeMask , salvo que permite especificar más de 64 procesadores.
En el caso de los sistemas operativos Windows, agregue el prefijo con el grupo de CPU correspondiente al
número o el rango del procesador, por ejemplo, "0:1-10,0:12,1:50-52,1:70".
Si la afinidad del procesador está deshabilitada estableciendo System.GC.NoAffinitize en true , esta
configuración se omite.
Solo se aplica a la recolección de elementos no utilizados del servidor.
Para obtener más información, vea el artículo del blog de Maoni Stephens sobre la mejora de la configuración
de la CPU para la GC en máquinas con > 64 CPU.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json Lista separada por comas de


System.GC.GCHeapAffinitizeRanges .NET Core 3.0
números de procesador o
rangos de números de
procesador.
Ejemplo de Unix: "1-
10,12,50-52,70"
Ejemplo de Windows: "0:1-
10,0:12,1:50-52,1:70"

Variable del entorno Lista separada por comas de


COMPlus_GCHeapAffinitizeRanges .NET Core 3.0
números de procesador o
rangos de números de
procesador.
Ejemplo de Unix: "1-
10,12,50-52,70"
Ejemplo de Windows: "0:1-
10,0:12,1:50-52,1:70"

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.GCHeapAffinitizeRanges": "0:1-10,0:12,1:50-52,1:70"
}
}
}

COMPlus_GCCpuGroup
Configura si el recolector de elementos no utilizados usa grupos de CPU o no.
Cuando un equipo Windows de 64 bits tiene varios grupos de CPU, es decir, hay más de 64 procesadores, la
habilitación de este elemento amplía la recolección de elementos no utilizados en todos los grupos de CPU.
El recolector de elementos no utilizados usa todos los núcleos para crear y equilibrar montones.
Solo se aplica a la recolección de elementos no utilizados del servidor en sistemas operativos Windows de
64 bits.
Predeterminado: deshabilitado ( 0 ).
Para obtener más información, vea el artículo del blog de Maoni Stephens sobre la mejora de la
configuración de la CPU para la GC en máquinas con > 64 CPU.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json N/D N/D N/D

Variable del entorno COMPlus_GCCpuGroup 0 : deshabilitado. .NET Core 1.0


1 : habilitado.

app.config para .NET GCCpuGroup false : deshabilitado.


Framework true : habilitado.

NOTE
Para configurar Common Language Runtime (CLR) con el fin de distribuir también los subprocesos del grupo de subprocesos
entre todos los grupos de CPU, habilite la opción Elemento Thread_UseAllCpuGroups. En el caso de las aplicaciones de .NET
Core, se puede habilitar esta opción estableciendo el valor de la variable de entorno COMPlus_Thread_UseAllCpuGroups en
1 .

System.GC.NoAffinitize/COMPlus_GCNoAffinitize
Especifica si establecer afinidad entre subprocesos de recolección de elementos no utilizados con procesadores.
El hecho de establecer afinidad entre un subproceso de GC significa que solo puede ejecutarse en su CPU
concreta. Se crea un montón para cada subproceso de GC.
Solo se aplica a la recolección de elementos no utilizados del servidor.
Predeterminado: establecer afinidad entre subprocesos de recolección de elementos no utilizados con
procesadores ( false ).

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.NoAffinitize false : establecer afinidad. .NET Core 3.0


true : no establecer
afinidad.

Variable del entorno COMPlus_GCNoAffinitize 0 : establecer afinidad. .NET Core 3.0


1 : no establecer afinidad.

app.config para .NET GCNoAffinitize false : establecer afinidad. .NET Framework 4.6.2
Framework true : no establecer
afinidad.

Ejemplo:
{
"runtimeOptions": {
"configProperties": {
"System.GC.NoAffinitize": true
}
}
}

System.GC.HeapHardLimit/COMPlus_GCHeapHardLimit
Especifica el tamaño máximo de confirmación, en bytes, para el montón de GC y la contabilidad de GC.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.HeapHardLimit valor decimal .NET Core 3.0

Variable del entorno COMPlus_GCHeapHardLimit valor hexadecimal .NET Core 3.0

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.HeapHardLimit": 209715200
}
}
}

TIP
Si configura la opción en runtimeconfig.json, especifique un valor decimal. Si configura la opción como una variable de
entorno, especifique un valor hexadecimal. Por ejemplo, para especificar un límite de montón de 200 mebibytes (MiB), los
valores serían 209715200 para el archivo JSON y 0xC800000 o C800000 para la variable de entorno.

System.GC.HeapHardLimitPercent/COMPlus_GCHeapHardLimitPercent
Especifica el uso del montón de GC como porcentaje de la memoria total.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json valor decimal


System.GC.HeapHardLimitPercent .NET Core 3.0

Variable del entorno valor hexadecimal


COMPlus_GCHeapHardLimitPercent .NET Core 3.0

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.HeapHardLimitPercent": 30
}
}
}
TIP
Si configura la opción en runtimeconfig.json, especifique un valor decimal. Si configura la opción como una variable de
entorno, especifique un valor hexadecimal. Por ejemplo, para limitar el uso del montón al 30 %, los valores serían 30 para el
archivo JSON y 0x1E o 1E para la variable de entorno.

System.GC.RetainVM/COMPlus_GCRetainVM
Configura si los segmentos que se deben eliminar se ponen en una lista en espera para usarlos en el futuro o se
devuelven al sistema operativo (SO ).
Predeterminado: devolver los segmentos al sistema operativo ( false ).

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.RetainVM false : liberar al sistema .NET Core 1.0


operativo.
true : poner en espera.

Variable del entorno COMPlus_GCRetainVM 0 : liberar al sistema .NET Core 1.0


operativo.
1 : poner en espera.

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.RetainVM": true
}
}
}

Páginas grandes
COMPlus_GCLargePages
Especifica si se deben usar páginas grandes cuando se establece un límite máximo de montones.
Predeterminado: deshabilitado ( 0 ).
Se trata de un valor de configuración experimental.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json N/D N/D N/D

Variable del entorno COMPlus_GCLargePages 0 : deshabilitado. .NET Core 3.0


1 : habilitado.

Objetos grandes
COMPlus_gcAllowVeryLargeObjects
Configura la compatibilidad del recolector de elementos no utilizados en plataformas de 64 bits para matrices
de más de 2 gigabytes (GB ) de tamaño total.
Predeterminado: habilitado ( 1 ).
Esta opción puede quedar obsoleta en una versión futura de .NET.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json N/D N/D N/D

Variable del entorno 1 : habilitado.


COMPlus_gcAllowVeryLargeObjects .NET Core 1.0
0 : deshabilitado.

app.config para .NET gcAllowVeryLargeObjects 1 : habilitado. .NET Framework 4.5


Framework 0 : deshabilitado.

Umbral del montón de objetos grandes


System.GC.LOHThreshold/COMPlus_GCLOHThreshold
Especifica el tamaño del umbral, en bytes, que provoca que los objetos vayan al montón de objetos grandes
(LOH).
El valor predeterminado del umbral es de 85 000 bytes.
El valor que especifique debe ser mayor que el umbral predeterminado.

NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json System.GC.LOHThreshold valor decimal .NET Core 1.0

Variable del entorno COMPlus_GCLOHThreshold valor hexadecimal .NET Core 1.0

app.config para .NET GCLOHThreshold valor decimal .NET Framework 4.8


Framework

Ejemplo:

{
"runtimeOptions": {
"configProperties": {
"System.GC.LOHThreshold": 120000
}
}
}

TIP
Si configura la opción en runtimeconfig.json, especifique un valor decimal. Si configura la opción como una variable de
entorno, especifique un valor hexadecimal. Por ejemplo, para establecer un tamaño de umbral de 120 000 bytes, los valores
serían 120000 para el archivo JSON y 0x1D4C0 o 1D4C0 para la variable de entorno.

GC independiente
COMPlus_GCName
Especifica una ruta de acceso a la biblioteca que contiene el recolector de elementos no utilizados que el
entorno de ejecución pretende cargar.
Para obtener más información, vea Diseño del cargador de GC independiente.
NOMBRE DE VALOR VALORES VERSIÓN INTRODUCIDA

runtimeconfig.json N/D N/D N/D

Variable del entorno COMPlus_GCName string_path .NET Core 2.0


Opciones de configuración del entorno de ejecución
para globalización
20/01/2020 • 2 minutes to read • Edit Online

Modo invariable
Determina si una aplicación de .NET Core se ejecuta en modo invariable de globalización sin tener acceso a los
datos y el comportamiento concretos de la referencia cultural, o bien si tiene acceso a los datos culturales.
Predeterminado: ejecutar la aplicación con acceso a los datos culturales ( false ).
Para obtener más información, vea Modo invariable de globalización de .NET Core.

NOMBRE DE VALOR VALORES

runtimeconfig.json System.Globalization.Invariant false : acceder a los datos culturales.


true : ejecutar en modo invariable.

Variable del entorno DOTNET_SYSTEM_GLOBALIZATION_INVARIANT 0 : acceder a los datos culturales.


1 : ejecutar en modo invariable.

Rangos de años de la era


Determina si las comprobaciones de rango para los calendarios que admiten varias eras son relajadas o si las
fechas que desbordan el intervalo de fechas de una era producen un elemento
ArgumentOutOfRangeException.
Predeterminado: las comprobaciones de intervalo son relajadas ( false ).
Para obtener más información, vea Calendarios, eras e intervalos de fechas: comprobaciones de intervalos
relajadas.

NOMBRE DE VALOR VALORES

runtimeconfig.json false : comprobaciones de intervalos


Switch.System.Globalization.EnforceJapaneseEraYearRanges
relajadas.
true : los desbordamientos causan
una excepción.

Variable del entorno N/D N/D

Análisis de fechas japonesas


Determina si una cadena cuyo valor del año contiene "1" o "Gannen" se analiza correctamente o si solo se
admite "1".
Predeterminado: analizar cadenas que contengan "1" o "Gannen" como año ( false ).
Para obtener más información, vea Representación de fechas en calendarios con varias eras.

NOMBRE DE VALOR VALORES


NOMBRE DE VALOR VALORES

runtimeconfig.json false : se admite "Gannen" o "1".


Switch.System.Globalization.EnforceLegacyJapaneseDateParsing
true : solo se admite "1".

Variable del entorno N/D N/D

Formato de año japonés


Determina si el primer año de una era de calendario japonés tiene formato "Gannen" o un número.
Predeterminado: dar formato al primer año como "Gannen" ( false ).
Para obtener más información, vea Representación de fechas en calendarios con varias eras.

NOMBRE DE VALOR VALORES

runtimeconfig.json false : dar formato como "Gannen".


Switch.System.Globalization.FormatJapaneseFirstYearAsANumber
true : dar formato como número.

Variable del entorno N/D N/D


Opciones de configuración del entorno de ejecución
para las redes
18/12/2019 • 2 minutes to read • Edit Online

Protocolo HTTP/2
Configura si está habilitada la compatibilidad con el protocolo HTTP/2.
Predeterminado: deshabilitado ( false ).
Introducido en .NET Core 3.0.

NOMBRE DEL VALOR VALORES

runtimeconfig.json false : deshabilitado.


System.Net.Http.SocketsHttpHandler.Http2Support
true : habilitado.

Variable del entorno 0 : deshabilitado.


DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2SUPPORT
1 : habilitado.

Controlador HTTP de sockets


Configura si las API de redes de alto nivel, como HttpClient, usan System.Net.Http.SocketsHttpHandler o la
implementación de System.Net.Http.HttpClientHandler basada en libcurl.
Predeterminado: usar System.Net.Http.SocketsHttpHandler ( true ).
Se puede configurar este valor mediante programación llamando al método AppContext.SetSwitch.

NOMBRE DEL VALOR VALORES

runtimeconfig.json System.Net.Http.UseSocketsHttpHandler true : habilita el uso de


SocketsHttpHandler.
false : habilita el uso de
HttpClientHandler.

Variable del entorno 1 : habilita el uso de


DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
SocketsHttpHandler.
0 : habilita el uso de
HttpClientHandler.
Opciones de configuración del entorno de ejecución
para subprocesos
18/12/2019 • 2 minutes to read • Edit Online

Grupos de CPU
Configura si los subprocesos se distribuyen automáticamente entre los grupos de CPU.
Predeterminado: deshabilitado ( 0 ).

NOMBRE DEL VALOR VALORES

runtimeconfig.json N/D N/D

Variable del entorno COMPlus_Thread_UseAllCpuGroups 0 : deshabilitado.


1 : habilitado.

Mínimo de subprocesos
Especifica el número mínimo de subprocesos para el grupo de subprocesos de trabajo.
Corresponde al método ThreadPool.SetMinThreads.

NOMBRE DEL VALOR VALORES

runtimeconfig.json System.Threading.ThreadPool.MinThreads Entero que representa el número


mínimo de subprocesos.

Variable del entorno N/D N/D

Máximo de subprocesos
Especifica el número máximo de subprocesos para el grupo de subprocesos de trabajo.
Corresponde al método ThreadPool.SetMaxThreads.

NOMBRE DEL VALOR VALORES

runtimeconfig.json System.Threading.ThreadPool.MaxThreads Entero que representa el número


máximo de subprocesos.

Variable del entorno N/D N/D


Exposición de los componentes de .NET Core a COM
25/11/2019 • 5 minutes to read • Edit Online

En .NET Core, el proceso de exposición de los objetos .NET a COM se ha simplificado significativamente en
comparación con .NET Framework. El siguiente proceso le guiará a través de la exposición de una clase a COM. En
este tutorial se muestra cómo realizar las siguientes acciones:
Exponer una clase a COM desde .NET Core.
Generar un servidor COM como parte de la creación de la biblioteca de .NET Core.
Generar automáticamente un manifiesto de servidor en paralelo para COM sin registro.

Requisitos previos
Instale el SDK de .NET Core 3.0 o una versión más reciente.

Crear la biblioteca
El primer paso consiste en crear la biblioteca.
1. Cree una carpeta nueva y, en ella, ejecute el siguiente comando:

dotnet new classlib

2. Abra Class1.cs .
3. Agregue using System.Runtime.InteropServices; a la parte superior del archivo.
4. Cree una interfaz denominada IServer . Por ejemplo:

using System;
using System.Runtime.InteropServices;

[ComVisible(true)]
[Guid(ContractGuids.ServerInterface)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServer
{
/// <summary>
/// Compute the value of the constant Pi.
/// </summary>
double ComputePi();
}

5. Agregue el atributo [Guid("<IID>")] a la interfaz con el GUID de la interfaz para la interfaz COM que está
implementando. Por ejemplo, [Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")] . Tenga en cuenta que este
GUID debe ser único, ya que es el único identificador de esta interfaz para COM. En Visual Studio, puede
generar un GUID desde Herramientas > Crear GUID para abrir la herramienta de creación de GUID.
6. Agregue el atributo [InterfaceType] a la interfaz y especifique qué interfaces COM base debe implementar
la interfaz.
7. Cree una clase denominada Server que implemente IServer .
8. Agregue el atributo [Guid("<CLSID>")] a la clase, con el identificador de clase GUID para la clase COM que
está implementando. Por ejemplo, [Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")] . Igual que sucede con la
interfaz GUID, este GUID debe ser único, ya que es el único identificador de esta interfaz para COM.
9. Agregue el atributo [ComVisible(true)] a la interfaz y a la clase.

IMPORTANT
A diferencia de lo que ocurre en .NET Framework, en .NET Core debe especificar el CLSID de cualquier clase que le interese
que se pueda activar mediante COM.

Generar el host de COM


1. Abra el archivo de proyecto .csproj y agregue <EnableComHosting>true</EnableComHosting> en una etiqueta
<PropertyGroup></PropertyGroup> .
2. Compile el proyecto.
El resultado contendrá un archivo ProjectName.dll , ProjectName.deps.json , ProjectName.runtimeconfig.json y
ProjectName.comhost.dll .

Registrar el host COM para COM


Abra un símbolo del sistema con privilegios elevados y ejecute regsvr32 ProjectName.comhost.dll . Esto registrará
todos los objetos .NET expuestos con COM.

Habilitar RegFree COM


1. Abra el archivo de proyecto .csproj y agregue <EnableRegFreeCom>true</EnableRegFreeCom> en una etiqueta
<PropertyGroup></PropertyGroup> .
2. Compile el proyecto.
Ahora el resultado también contendrá un archivo ProjectName.X.manifest . Este archivo es el manifiesto en paralelo
que se podrá usar con COM sin registro.

Muestra
Puede encontrar un ejemplo de servidor COM totalmente funcional en el repositorio dotnet/samples de GitHub.

Notas adicionales
A diferencia de lo que ocurre en .NET Framework, .NET Core no admite la generación de una biblioteca de tipos
COM (TLB ) a partir de un ensamblado de .NET Core. La instrucción es escribir manualmente un archivo IDL o un
encabezado C/C++ para las declaraciones nativas de las interfaces COM.
Además, la carga de .NET Framework y .NET Core en el mismo proceso presenta limitaciones de diagnóstico. La
limitación principal es la depuración de componentes administrados, ya que no es posible depurar .NET
Framework y .NET Core al mismo tiempo. Asimismo, las dos instancias en tiempo de ejecución no comparten
ensamblados administrados. Esto significa que no es posible compartir tipos de .NET reales entre los dos tiempos
de ejecución, por lo que todas las interacciones deben restringirse a los contratos de interfaz COM expuestos.
Paquetes, metapaquetes y marcos de trabajo
12/01/2020 • 17 minutes to read • Edit Online

.NET Core es una plataforma conformada por paquetes NuGet. Algunas experiencias del producto se benefician
de la definición específica de los paquetes, mientras que otras lo hacen de la definición general de las mismas. Para
dar cabida a esta dualidad, el producto se distribuye como un conjunto específico de paquetes y en fragmentos
más generales con un tipo de paquete que recibe informalmente el nombre de metapaquete.
Cada uno de los paquetes de .NET Core admite su ejecución en varias implementaciones .NET, que se representan
como marcos de trabajo. Algunos de estos son marcos de trabajo tradicionales, como net46 , que representa a
.NET Framework. Otro conjunto son marcos de trabajo nuevos que se pueden considerar "marcos de trabajo
basados en paquete", que establecen un modelo nuevo para definir los marcos de trabajo. Estos marcos de trabajo
basados en paquete están completamente formadas y definidas como paquetes, lo que establece una fuerte
relación entre los paquetes y los marcos de trabajo.

Paquetes
.NET Core se divide en un conjunto de paquetes, que proporcionan primitivas, tipos de datos de nivel superior,
tipos de composición de aplicaciones y utilidades comunes. Cada uno de estos paquetes representa un solo
ensamblado con el mismo nombre. Por ejemplo, System.Runtime contiene System.Runtime.dll.
Hay ventajas si los paquetes se definen de manera específica:
Los paquetes específicos se pueden enviar según su propia programación con una prueba relativamente
limitada de los otros paquetes.
Los paquetes específicos pueden brindar compatibilidad con distintos SO y CPU.
Los paquetes específicos pueden tener dependencias específicas solo para una biblioteca.
Las aplicaciones son más pequeñas, porque los paquetes a los que no se hace referencia no forman parte de la
distribución de aplicaciones.
Algunas de estas ventajas solo se usan bajo ciertas circunstancias. Por ejemplo, los paquetes de .NET Core
normalmente se envían en la misma programación con la misma compatibilidad de plataforma. En el caso del
mantenimiento, las correcciones se pueden distribuir e instalar como pequeñas actualizaciones de paquetes
únicos. Debido al alcance limitado del cambio, la validación y el tiempo para que una corrección esté disponible
están limitados a las necesidades de una biblioteca única.
A continuación se muestra una lista de los paquetes NuGet clave para .NET Core:
System.Runtime: el paquete más fundamental de .NET Core, que incluye Object, String, Array, Action y
IList<T>.
System.Collections: un conjunto de colecciones genéricas (principalmente), que incluye List<T> y
Dictionary<TKey,TValue>.
System.Net.Http: un conjunto de tipos de comunicación de red HTTP, que incluye HttpClient y
HttpResponseMessage.
System.IO.FileSystem: un conjunto de tipos de lectura y escritura en un almacenamiento basado en disco local
o en red, y que incluye File y Directory.
System.Linq: un conjunto de tipos para consultar objetos, que incluye Enumerable y ILookup<TKey,TElement>.
System.Reflection: un conjunto de tipos para cargar, inspeccionar y activar tipos, que incluye Assembly,
TypeInfo y MethodInfo.
Normalmente, en lugar de incluir cada paquete, es más fácil y más sólido incluir un metapaquete. En cambio,
cuando necesite un solo paquete, puede incluirlo como en el ejemplo siguiente, que hace referencia al paquete
System.Runtime.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Runtime" Version="4.3.0" />
</ItemGroup>
</Project>

Metapaquetes
Los metapaquetes son una conversión de paquetes NuGet que se usa para describir un conjunto de paquetes que
tienen sentido juntos. Para representar este conjunto de paquetes, los transforman en dependencias. De manera
opcional, pueden especificar un marco de trabajo a fin de establecer uno para este conjunto de paquetes.
De manera predeterminada, las versiones anteriores de las herramientas de .NET Core (las herramientas basadas
en project.json y csproj) especificaban un marco y un metapaquete. Pero, actualmente, el marco de destino hace
referencia implícitamente al metapaquete, de manera que cada uno está asociado a un marco de destino. Por
ejemplo, el marco netstandard1.6 hace referencia al metapaquete de la versión 1.6.0 de NetStandard.Library. De
manera similar, el marco netcoreapp2.1 hace referencia al metapaquete de la versión 2.1.0 de
Microsoft.NETCore.App. Para obtener más información, vea Implicit metapackage package reference in the .NET
Core SDK (Referencia del paquete implícita del metapaquete en el SDK de .NET Core).
Dirigirse a un marco y hacer referencia implícitamente a un metapaquete significa que realmente está agregando
una referencia a cada uno de sus paquetes dependientes como un gesto único. Esto hace que todas las bibliotecas
de esos paquetes estén disponibles para IntelliSense (o una experiencia similar) y para publicar la aplicación.
Usar metapaquetes tiene ventajas:
Proporciona una experiencia del usuario adecuada para hacer referencia a un gran conjunto de paquetes
específicos.
Define un conjunto de paquetes (incluidas las versiones específicas) que se prueban y trabajan correctamente
en conjunto.
El metapaquete del estándar .NET es:
NETStandard.Library: describe las bibliotecas que forman parte del "estándar .NET". Se aplica a todas las
implementaciones .NET (por ejemplo, .NET Framework, .NET Core y Mono) que admiten el estándar .NET.
Establece el marco de trabajo "netstandard".
Los metapaquetes principales de .NET Core son:
Microsoft.NETCore.App: describe las bibliotecas que forman parte de la distribución de .NET Core. Establece el
.NETCoreApp marco de trabajo. Depende del NETStandard.Library más pequeño.
Microsoft.AspNetCore.All: incluye todos los paquetes admitidos de ASP.NET Core y Entity Framework Core,
excepto aquellos que contienen dependencias de terceros. Vea Metapaquete Microsoft.AspNetCore.All para
ASP.NET Core para más información.
Microsoft.AspNetCore.All: incluye todos los paquetes admitidos de ASP.NET Core, Entity Framework Core y
las dependencias internas y de terceros que usan ASP.NET Core y Entity Framework Core. Consulte
Microsoft.AspNetCore.All metapackage for ASP.NET Core 2.x (Metapaquete Microsoft.AspNetCore.All para
ASP.NET Core 2.x) para obtener más información.
Microsoft.NETCore.Portable.Compatibility: un conjunto de fachadas de compatibilidad que permite que las
Bibliotecas de clases portables (PCL ) basadas en mscorlib se ejecuten en .NET Core.

Marcos de trabajo
Cada paquete de .NET Core admite un conjunto de marcos en tiempo de ejecución. Los marcos de trabajo
describen un conjunto de API disponible (y posiblemente también otras características) en que puede basarse
cuando tiene como destino un marco de trabajo determinado. Se crean versiones suyas cada vez que se agregan
API nuevas.
Por ejemplo, System.IO.FileSystem admite los siguientes marcos de trabajo:
.NETFramework,Version=4.6
.NETStandard,Version=1.3
6 plataformas Xamarin (por ejemplo, xamarinios10)
Es útil contrastar los dos primeros de estos marcos de trabajo, debido a que son ejemplos de las dos formas
distintas en que se definen los marcos de trabajo.
El marco de trabajo .NETFramework,Version=4.6 representa las API disponibles en .NET Framework 4.6. Puede
generar bibliotecas compiladas con los ensamblados de referencia de .NET Framework 4.6 y, luego, distribuir esas
bibliotecas en paquetes NuGet en una carpeta net46 lib. Se usará para las aplicaciones que tienen como destino
.NET Framework 4.6 o que son compatibles con esa plataforma. Esta es la forma de trabajar tradicional de todos
los marcos de trabajo.
El marco de trabajo .NETStandard,Version=1.3 está basado en paquete. Se basa en paquetes que tienen como
destino el marco de trabajo para definir y exponer las API en términos del marco de trabajo.

Marcos de trabajo basados en paquete


Existe una relación recíproca entre los marcos de trabajo y los paquetes. La primera parte es definir las API
disponibles para un marco de trabajo determinado, por ejemplo, netstandard1.3 . Los paquetes que tienen como
destino netstandard1.3 (o marcos de trabajo compatibles, como netstandard1.0 ) definen las API disponibles para
netstandard1.3 . Esto puede parecer una definición circular, pero no lo es. En virtud de estar "basada en paquete",
la definición de API del marco de trabajo proviene de los paquetes. El marco de trabajo mismo no define a
ninguna API.
La segunda parte de la relación es la selección de recursos. Los paquetes pueden incluir recursos para varios
marcos de trabajo. Dada una referencia a un conjunto de paquetes o metapaquetes, el marco de trabajo es
necesario para determinar el recurso que se debe seleccionar, por ejemplo net46 o netstandard1.3 . Es
importante seleccionar el recurso correcto. Por ejemplo, es poco probable que un recurso de net46 sea
compatible con .NET Framework 4.0 o .NET Core 1.0.
Puede ver esta relación en la imagen siguiente. La API tiene como destino el marco de trabajo y lo define. El
marco de trabajo se usa para la selección de recursos. El recurso le brinda la API.
Los dos principales marcos de trabajo basados en paquete que se usan con .NET Core son los siguientes:
netstandard
netcoreapp

.NET Standard
El marco .NET Standard (moniker de la plataforma de destino: netstandard ) representa las API definidas por .NET
Standard y que se basan en esta especificación. Las bibliotecas diseñadas para ejecutarse en varios entornos de
ejecución deben tener como destino este marco de trabajo. Se admitirán en cualquier entorno de ejecución
compatible con el estándar .NET, como .NET Core, .NET Framework y Mono/Xamarin. Cada uno de estos
entornos de ejecución admite un conjunto de versiones del estándar .NET, en función de las API que implementan.
El marco netstandard hace referencia implícitamente al metapaquete NETStandard.Library . Por ejemplo, el
siguiente archivo del proyecto de MSBuild indica que el proyecto tiene como destino netstandard1.6 , que hace
referencia al metapaquete de la versión 1.6 de NETStandard.Library .

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
</Project>

En cambio, las referencias del metapaquete y el marco en el archivo del proyecto no necesitan coincidir, y puede
usar el elemento <NetStandardImplicitPackageVersion> en su archivo del proyecto para especificar una versión de
marco que sea anterior a la del metapaquete. Por ejemplo, el siguiente archivo del proyecto es válido.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
</PropertyGroup>
</Project>
Puede parecer extraño establecer netstandard1.3 como destino pero usa la versión 1.6.0 de NETStandard.Library .
Se trata de un caso de uso válido, debido a que el metapaquete mantiene la compatibilidad con versiones
anteriores de netstandard . Podría ser el caso que estandarizó en la versión 1.6.0 del metapaquete y úselo para
todas las bibliotecas, que establecen como destino distintas versiones de netstandard . Con este enfoque, solo
necesita restaurar NETStandard.Library 1.6.0 y no las versiones anteriores.
Lo contrario no sería válido: establecer netstandard1.6 como destino con la versión 1.3.0 de NETStandard.Library .
No puede establecer como destino un marco de trabajo superior con un metapaquete inferior, debido a que el
metapaquete de una versión inferior no expondrá ningún recurso para ese marco de trabajo superior. El esquema
de control de versiones para los metapaquetes afirma que estos coinciden con la versión más reciente del marco
de trabajo que describen. En virtud del esquema de control de versiones, la primera versión de
NETStandard.Library es v1.6.0, siempre que contenga recursos de netstandard1.6 . La versión v1.3.0 se usa en el
ejemplo anterior, para lograr una simetría con el ejemplo anterior, pero no existe realmente.
Aplicación .NET Core
El marco .NET Core (moniker de la plataforma de destino: netcoreapp ) representa los paquetes y las API
asociadas que se incluyen en la distribución de .NET Core y el modelo de aplicación de consola que proporciona.
Las aplicaciones .NET Core deben usar este marco de trabajo, debido a que intentan establecer el modelo de
aplicación de consola como destino, al igual que las bibliotecas que se pretende ejecutar solo en .NET Core. Usar
este marco de trabajo restringe a las aplicaciones y bibliotecas solo a su ejecución en .NET Core.
El metapaquete Microsoft.NETCore.App tiene como destino el marco de trabajo netcoreapp . Proporciona acceso
aproximadamente a 60 bibliotecas, de las cuales el paquete NETStandard.Library proporciona unas 40, además de
otras 20. Puede hacer referencia a bibliotecas adicionales que establecen como destino a netcoreapp o marcos de
trabajo compatibles, como netstandard , para obtener acceso a API adicionales.
La mayoría de las bibliotecas adicionales que Microsoft.NETCore.App proporciona también establecen como
destino a netstandard , dado que otras bibliotecas netstandard satisfacen sus dependencias. Esto significa que las
bibliotecas netstandard también pueden hacer referencia a esos paquetes como dependencias.
Introducción de alto nivel de los cambios en las
herramientas de .NET Core
23/10/2019 • 9 minutes to read • Edit Online

En este documento se describen los cambios asociados con el traslado de project.json a MSBuild y al sistema del
proyecto csproj con información sobre los cambios realizados en las capas de las herramientas de .NET Core y en
la implementación de los comandos de la CLI. Estos cambios se han producido con la versión de .NET Core SDK
1.0 y Visual Studio 2017 de 7 de marzo de 2017 (vea el anuncio), pero se han implementado inicialmente con la
versión de .NET Core SDK Preview 3.

Abandono de project.json
El cambio más importante en las herramientas para .NET Core es ciertamente el abandono de project.json en
favor de csproj como sistema de proyectos. Las últimas versiones de las herramientas de línea de comandos no
admiten archivos project.json. Esto significa que no puede utilizarse para compilar, ejecutar o publicar bibliotecas y
aplicaciones basadas en project.json. Para poder utilizar esta versión de las herramientas, debe migrar los
proyectos existentes o iniciar otros nuevos.
Como parte de este proceso, el motor de compilación personalizado que se desarrolló para compilar proyectos de
project.json se ha reemplazado por un motor de compilación maduro y totalmente compatible llamado MSBuild.
MSBuild es un motor conocido en la comunidad. NET, ya que ha sido una tecnología clave desde el primer
lanzamiento de la plataforma. Por supuesto, como debe compilar aplicaciones .NET Core, MSBuild se ha
trasladado a .NET Core y puede utilizarse en cualquier plataforma donde se ejecute .NET Core. Una de las
promesas principales de .NET Core es una pila de desarrollo multiplataforma, y nos hemos asegurado de que esta
transición no rompa esa promesa.

NOTE
Si no está familiarizado con MSBuild y quiere aprender más al respecto, puede empezar por leer el artículo Conceptos de
MSBuild.

Las capas de herramientas


Cuando nos alejamos del sistema de proyecto existente y pensamos en la compilación de modificadores del motor,
la pregunta que surge de manera natural es: ¿cambiarán algunos de estos cambios la "disposición en capas"
general del ecosistema completo de herramientas de .NET Core? ¿Hay nuevos bits y componentes?
Comencemos con un repaso rápido de la disposición en capas de Preview 2, como se muestra en la siguiente
imagen:
La disposición en capas de las herramientas es bastante sencilla. En la parte inferior, tenemos como base las
herramientas de línea de comandos de .NET Core. Todas las demás herramientas de mayor nivel, como Visual
Studio o Visual Studio Code, dependen de la CLI para compilar proyectos, restaurar dependencias, etc. Esto
significa que si, por ejemplo, se quisiera realizar una operación de restauración con Visual Studio, se llamaría al
comando dotnet restore (vea la nota) de la CLI.
Con el paso al nuevo sistema de proyecto, el diagrama anterior cambia:

La principal diferencia es que la CLI ya no es la base; este papel es ocupado ahora por el "componente de SDK
compartido". Este componente de SDK compartido es un conjunto de destinos y tareas asociadas que son
responsables de compilar el código y publicarlo, de empaquetar paquetes de NuGet, etc. El propio SDK es código
abierto y está disponible en GitHub en el repositorio de SDK.

NOTE
Un "destino" es un término de MSBuild que indica una operación con nombre que puede invocar MSBuild. Normalmente está
unido a una o varias tareas que ejecutan alguna lógica que se supone que debe hacer el destino. MSBuild admite michos
destinos predefinidos, como Copy o Execute ; también permite a los usuarios escribir sus propias tareas mediante código
administrado y definir destinos para ejecutar esas tareas. Para obtener más información, consulte Tareas de MSBuild.

Todos los conjuntos de herramientas consumen ahora el componente de SDK compartido y sus destinos, incluida
la CLI. Por ejemplo, la siguiente versión de Visual Studio no llamará al comando dotnet restore (vea la nota) para
restaurar las dependencias para proyectos de .NET Core, sino que usará directamente el destino "Restore". Como
son destinos de MSBuild, también puede usar MSBuild sin procesar para ejecutarlos mediante el comando dotnet
msbuild.
Comandos de la CLI
El componente de SDK compartido implica que la mayoría de los comandos de la CLI existentes se han vuelto a
implementar como tareas y destinos de MSBuild. ¿Qué significa esto para los comandos de la CLI y el uso del
conjunto de herramientas?
Desde una perspectiva del uso, no cambia la forma de usar la CLI. La CLI sigue teniendo los comandos principales
que existen en la versión Preview 2:
new
restore
run
build
publish
test
pack

Estos comandos todavía hacen lo que se espera que hagan (crear un nuevo proyecto, compilarlo, publicarlo,
empaquetarlo, etc.). La mayoría de las opciones no varían y siguen ahí. Puede consultar las pantallas de ayuda de
los comandos (mediante dotnet <command> --help ) o la documentación de este sitio para familiarizarse con los
cambios.
Desde una perspectiva de la ejecución, los comandos de la CLI tomarán sus parámetros y construirán una llamada
a MSBuild "sin procesar" que establecerá las propiedades necesarias y ejecutará el destino deseado. Para ilustrar
mejor esto, considere el siguiente comando:

dotnet publish -o pub -c Release

Este comando está publicando una aplicación en una carpeta pub mediante la configuración de "Release".
Internamente, este comando se traduce en la siguiente invocación de MSBuild:

dotnet msbuild -t:Publish -p:OutputPath=pub -p:Configuration=Release

La excepción importante a esta regla son los comandos new y run , dado que no se han implementado como
destinos de MSBuild.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Administración de dependencias con el SDK 1.0 de
.NET Core
12/01/2020 • 5 minutes to read • Edit Online

Con el paso de los proyectos .NET Core de project.json a csproj y MSBuild, también se ha producido una inversión
significativa que ha dado lugar a la unificación del archivo de proyecto y los recursos que permiten el seguimiento
de dependencias. Para los proyectos .NET Core, esto es similar a lo que hizo project.json. No hay ningún archivo
independiente JSON o XML que realice el seguimiento de las dependencias de NuGet. Con este cambio, también
hemos introducido otro tipo de referencia en la sintaxis de csproj llamada <PackageReference> .
Este documento describe el nuevo tipo de referencia. También muestra cómo agregar a su proyecto una
dependencia de paquete mediante este nuevo tipo de referencia.

El nuevo elemento <PackageReference>


El elemento <PackageReference> tiene la siguiente estructura básica:

<PackageReference Include="PACKAGE_ID" Version="PACKAGE_VERSION" />

Si ya conoce MSBuild, le resultarán familiares los otros tipos de referencia que ya existen. La clave es la instrucción
Include que especifica el identificador de paquete que desea agregar al proyecto. El elemento secundario
<Version> especifica la versión que se obtiene. Las versiones se especifican según las como por reglas de versión
de NuGet.

NOTE
Si no está familiarizado con la sintaxis general de csproj , puede usar la documentación de referencia de proyecto de
MSBuild para obtener más información.

La adición de una dependencia que solo está disponible en un destino específico se realiza mediante condiciones
similares a las del siguiente ejemplo:

<PackageReference Include="PACKAGE_ID" Version="PACKAGE_VERSION" Condition="'$(TargetFramework)' ==


'netcoreapp2.1'" />

Lo anterior significa que la dependencia solo será válida si la compilación sucede para ese destino dado. El
elemento $(TargetFramework) de la condición es una propiedad de MSBuild que se está configurando en el
proyecto. Con aplicaciones .NET Core más comunes, no será necesario hacer esto.

Adición de una dependencia al proyecto


Agregar una dependencia a su proyecto es muy sencillo. Este es un ejemplo de cómo agregar la versión 9.0.1 de
Json.NET a su proyecto. Por supuesto, es aplicable a cualquier otra dependencia de NuGet.
Al abrir el archivo de proyecto, verá dos o más nodos <ItemGroup> . Observe que uno de los nodos ya contiene
elementos <PackageReference> . Puede agregar la nueva dependencia a este nodo, o crear uno nuevo; es su
decisión, ya que el resultado será el mismo.
En este ejemplo utilizaremos la plantilla predeterminada que se ha descartado mediante dotnet new console . Se
trata de una aplicación de consola simple. Cuando se abre el proyecto, primero encontramos el elemento
<ItemGroup> que ya contiene <PackageReference> . A continuación, le agregamos lo siguiente:

<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />

Después de esto, guardamos el proyecto y ejecutamos el comando dotnet restore para instalar la dependencia.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

El proyecto completo tiene este aspecto:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
</Project>

Eliminación de una dependencia del proyecto


La eliminación de una dependencia del archivo de proyecto supone simplemente quitar el elemento
<PackageReference> del archivo de proyecto.
Adiciones al formato csproj para .NET Core
20/01/2020 • 32 minutes to read • Edit Online

En este documento se describen los cambios que se han agregado a los archivos de proyecto como parte del cambio
de project.json a csproj y MSBuild. Para obtener más información sobre la sintaxis y la referencia del archivo de
proyecto general, consulte la documentación del archivo de proyecto de MSBuild.

Referencias implícitas del paquete


Se hace una referencia implícita a los metapaquetes basándose en los marcos de trabajo de destino especificados en
la propiedad <TargetFramework> o <TargetFrameworks> del archivo del proyecto. <TargetFrameworks> se ignora si
<TargetFramework> se especifica, independientemente del orden. Para obtener más información, vea Paquetes,
metapaquetes y marcos de trabajo.

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net462</TargetFrameworks>
</PropertyGroup>

Recomendaciones
Como se hace referencia implícitamente a los metapaquetes Microsoft.NETCore.App o NETStandard.Library , estos son
los procedimientos recomendados:
Si el destino es .NET Core o .NET Standard, nunca incluya una referencia explícita a los metapaquetes
Microsoft.NETCore.App o NETStandard.Library mediante un elemento <PackageReference> en el archivo de
proyecto.
Si necesita una versión concreta del runtime cuando el destino es .NET Core, debe usar la propiedad
<RuntimeFrameworkVersion> del proyecto (por ejemplo, 1.0.4 ) en lugar de hacer referencia al metapaquete.
Esto puede ocurrir si está usando implementaciones autocontenidas y necesita una versión de revisión
específica del tiempo de ejecución de LTS 1.0.0, por ejemplo.
Si necesita una versión concreta del metapaquete NETStandard.Library cuando el destino es .NET Standard, puede
usar la propiedad <NetStandardImplicitPackageVersion> y establecer la versión necesaria.
No agregue referencias a los metapaquetes Microsoft.NETCore.App y NETStandard.Library ni las actualice
explícitamente en proyectos de .NET Framework. Si se necesita alguna versión de NETStandard.Library al usar un
paquete NuGet basado en .NET Standard, NuGet instala automáticamente esa versión.

Versión implícita para algunas referencias de paquete


La mayoría de los usos de <PackageReference> requieren establecer el atributo Version para especificar la versión del
paquete de NuGet que se va a usar. Sin embargo, el atributo es innecesario si se usa .NET Core 2.1 o 2.2 y se hace
referencia a Microsoft.AspNetCore.App o a Microsoft.AspNetCore.All. El SDK de .NET Core puede seleccionar
automáticamente la versión que se debe usar de estos paquetes.
Recomendación
Cuando haga referencia al paquete Microsoft.AspNetCore.App o al paquete Microsoft.AspNetCore.All , no especifique
la versión. Si se especifica una versión, el SDK podría generar la advertencia NETSDK1071. Para corregir esta
advertencia, quite la versión de paquete como en el ejemplo siguiente:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

Problema conocido: el SDK de .NET Core 2.1 solo admite esta sintaxis cuando el proyecto también usa
Microsoft.NET.Sdk.Web. Esto se resuelve en el SDK de .NET Core 2.2.

Estas referencias a los metapaquetes de ASP.NET Core tienen un comportamiento ligeramente distinto de los
paquetes más habituales de NuGet. Las implementaciones dependientes del marco de las aplicaciones que usan estos
metapaquetes aprovechan automáticamente el marco de uso compartido de ASP.NET Core. Al usar los
metapaquetes, no se implementa ningún recurso de los paquetes NuGet de ASP.NET Core a los que se hace
referencia con la aplicación, porque el marco de uso compartido de ASP.NET Core ya contiene estos recursos. Los
recursos del marco de uso compartido están optimizados para que la plataforma de destino mejore el tiempo de
inicio de la aplicación. Para más información sobre el marco de uso compartido, consulte Empaquetado de
distribución de .NET Core.
Si se especifica una versión, se trata como la versión mínima del marco de uso compartido de ASP.NET Core para las
implementaciones dependientes del marco y como una versión exacta de las implementaciones autocontenidas. Esto
puede deberse a las siguientes consecuencias:
Si la versión de ASP.NET Core instalada en el servidor es anterior a la versión especificada en PackageReference,
no se iniciará el proceso de .NET Core. Por lo general, las actualizaciones del metapaquete están disponibles en
NuGet.org antes de que se aparezcan en entornos de hospedaje como Azure. Actualizar la versión de
PackageReference a ASP.NET Core podría provocar un error en una aplicación implementada.
Si la aplicación se implementa como una implementación autocontenida, es posible que no contenga las
actualizaciones de seguridad más recientes a .NET Core. Cuando no se especifica una versión, el SDK puede incluir
automáticamente la versión más reciente de ASP.NET Core en la implementación autocontenida.

Inclusiones de compilación predeterminadas en proyectos .NET Core


Con el cambio al formato csproj en las últimas versiones del SDK, hemos trasladado las inclusiones y exclusiones
predeterminadas para los elementos de compilación y los recursos incrustados a los archivos de propiedades del
SDK. Esto implica que ya no tiene que especificar dichos elementos en el archivo del proyecto.
El principal motivo de este cambio consiste en reducir el desorden en el archivo del proyecto. Los valores
predeterminados presentes en el SDK deberían abarcar los casos de uso más habituales, por lo que no resulta
necesario repetirlos en todos los proyectos que cree. Esto da lugar a archivos de proyecto más pequeños que resultan
mucho más fáciles de entender, así como de editar manualmente si fuera necesario.
En la siguiente tabla se muestra qué elementos y qué globs se incluyen y excluyen en el SDK:

ELEMENTO GLOB PARA INCLUIR GLOB PARA EXCLUIR GLOB PARA QUITAR

Compile **/*.cs (u otras extensiones **/*.user; **/*.*proj; **/*.sln; N/D


de lenguaje) **/*.vssscc

EmbeddedResource **/*.resx **/*.user; **/*.*proj; **/*.sln; N/D


**/*.vssscc

None **/* **/*.user; **/*.*proj; **/*.sln; **/*.cs; **/*.resx


**/*.vssscc
NOTE
Glob para excluir siempre excluye las carpetas ./bin y ./obj , que se representan mediante las propiedades
$(BaseOutputPath) y $(BaseIntermediateOutputPath) de MSBuild, respectivamente. En su conjunto, todos los "exclude" se
representan mediante $(DefaultItemExcludes) .

Si tiene globs en el proyecto e intenta crearlo usando el SDK más reciente, le aparecerá el siguiente error:

Se han incluido elementos de compilación duplicados. El SDK de .NET incluye elementos de compilación del
directorio del proyecto de forma predeterminada. Puede quitar estos elementos del archivo de proyecto o
establecer la propiedad “EnableDefaultCompileItems” en “false” si quiere incluirlos explícitamente en el archivo
del proyecto.

Para evitar este error, puede quitar los elementos Compile explícitos que coinciden con los que aparecen en la tabla
anterior o establecer la propiedad <EnableDefaultCompileItems> en false de esta forma:

<PropertyGroup>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>

Al establecer esta propiedad en false , se deshabilita la inclusión implícita y se revierte el comportamiento de SDK
anteriores en los que había que especificar los globs predeterminados del proyecto.
Este cambio no modifica los mecanismos principales de otras inclusiones. En cambio, si quiere especificar, por
ejemplo, que algunos archivos se publiquen con la aplicación, puede seguir usando los mecanismos con los que está
familiarizado en csproj (por ejemplo, el elemento <Content> ).
<EnableDefaultCompileItems> solo deshabilita globs Compile , pero no afecta a otros globs, como el glob None
implícito, que también se aplica a elementos *.cs. Por eso, el Explorador de soluciones sigue mostrando elementos
*.cs como parte del proyecto, incluso como elementos None . Del mismo modo, puede establecer
<EnableDefaultNoneItems> en false para deshabilitar el glob None implícito, de esta forma:

<PropertyGroup>
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
</PropertyGroup>

Para deshabilitar todos los globs implícitos, puede establecer la propiedad <EnableDefaultItems> en false como
en el ejemplo siguiente:

<PropertyGroup>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>

Visualización del proyecto completo tal como MSBuild lo ve


Aunque dichos cambios de csproj simplifican considerablemente los archivos de proyecto, quizá desee visualizar el
proyecto totalmente expandido tal y como MSBuild lo ve después de haber incluido el SDK y sus destinos. Preprocese
el proyecto con el conmutador /pp del comando dotnet msbuild , que muestra qué archivos se han importado, sus
orígenes y sus contribuciones a la compilación sin tener que compilar el proyecto realmente:
dotnet msbuild -pp:fullproject.xml

Si el proyecto tiene varios marcos de destino, los resultados del comando deben centrarse solo en uno de ellos,
especificándolo como una propiedad de MSBuild:
dotnet msbuild -p:TargetFramework=netcoreapp2.0 -pp:fullproject.xml

Adiciones
Atributo Sdk
El elemento raíz <Project> del archivo .csproj tiene un nuevo atributo denominado Sdk . Sdk especifica qué SDK
usará el proyecto. El SDK, como se describe en el documento sobre capas, es un conjunto de tareas y destinos de
MSBuild que pueden generar código de .NET Core. Los siguientes SDK están disponibles para .NET Core:
1. El SDK de .NET Core con el id. de Microsoft.NET.Sdk
2. El SDK web de .NET Core con el id. de Microsoft.NET.Sdk.Web
3. El SDK de la biblioteca de clases de Razor de .NET Core con el id. Microsoft.NET.Sdk.Razor
4. El servicio de trabajo de .NET Core con el id. de Microsoft.NET.Sdk.Worker (a partir de .NET Core 3.0)
5. WinForms y WPF de .NET Core con el id. de Microsoft.NET.Sdk.WindowsDesktop (a partir de .NET Core 3.0)

Debe tener el conjunto de atributos Sdk establecido en uno de esos id. del elemento <Project> para poder usar las
herramientas de .NET Core y generar el código.
PackageReference
Elemento <PackageReference> que especifica una dependencia de NuGet en el proyecto. El atributo Include
especifica el identificador del paquete.

<PackageReference Include="<package-id>" Version="" PrivateAssets="" IncludeAssets="" ExcludeAssets="" />

Versión
El atributo Version necesario especifica la versión del paquete que se va a restaurar. El atributo respeta las reglas del
esquema de versiones de NuGet. El comportamiento predeterminado es una coincidencia de versión exacta. Por
ejemplo, si se especifica Version="1.2.3" , es equivalente a la notación de NuGet [1.2.3] para la versión exacta 1.2.3
del paquete.
IncludeAssets, ExcludeAssets y PrivateAssets
El atributo IncludeAssets especifica qué recursos que pertenecen al paquete especificado por <PackageReference> se
deben consumir. De forma predeterminada, se incluyen todos los recursos del paquete.
El atributo ExcludeAssets especifica qué recursos que pertenecen al paquete especificado por <PackageReference> no
se deben consumir.
El atributo PrivateAssets especifica qué recursos que pertenecen al paquete especificado por <PackageReference> se
deben consumir, pero no pasar al proyecto siguiente. Cuando este atributo no existe, los recursos Analyzers , Build y
ContentFiles son privados de forma predeterminada.

NOTE
PrivateAssets es equivalente al elemento project.json/xproj SuppressParent .

Estos atributos pueden contener uno o varios de los siguientes elementos, separados por punto y coma ; si aparece
más de uno:
Compile : el contenido de la carpeta lib está disponible para compilación.
Runtime : el contenido de la carpeta runtime está distribuido.
ContentFiles : se usa el contenido de la carpeta contentfiles.
Build : se usan los archivos props/targets de la carpeta build.
Native : el contenido de recursos nativos se copia en la carpeta output en runtime.
Analyzers : se usan los analizadores.
Como alternativa, el atributo puede contener:
None : no se usa ninguno de los recursos.
All : se usan todos los recursos.

DotnetCliToolReference
Un elemento <DotNetCliToolReference> especifica la herramienta de la CLI que el usuario quiere restaurar en el
contexto del proyecto. Es un sustituto del nodo tools de project.json.

<DotNetCliToolReference Include="<package-id>" Version="" />

Tenga en cuenta que DotNetCliToolReference está ahora en desuso en favor de las herramientas locales de .NET Core.
Versión
Version especifica la versión del paquete que se va a restaurar. El atributo respeta las reglas del esquema de
versiones de NuGet. El comportamiento predeterminado es una coincidencia de versión exacta. Por ejemplo, si se
especifica Version="1.2.3" , es equivalente a la notación de NuGet [1.2.3] para la versión exacta 1.2.3 del paquete.
RuntimeIdentifiers
El elemento de propiedad <RuntimeIdentifiers> permite especificar una lista delimitada por puntos y coma de
identificadores de tiempo ejecución (RID ) para el proyecto. Los RID permiten publicar implementaciones
autocontenidas.

<RuntimeIdentifiers>win10-x64;osx.10.11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>

RuntimeIdentifier
El elemento de propiedad <RuntimeIdentifier> permite especificar solo un identificador de tiempo ejecución (RID )
para el proyecto. El RID permite publicar una implementación autocontenida.

<RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>

Use <RuntimeIdentifiers> (en plural) en su lugar si tiene que publicar para varios entornos de ejecución.
<RuntimeIdentifier> puede proporcionar compilaciones más rápidas cuando solo se requiere un entorno de
ejecución.
PackageTargetFallback
El elemento de propiedad <PackageTargetFallback> permite especificar un conjunto de destinos compatibles que se
van a usar al restaurar paquetes. Está diseñado para permitir que los paquetes que usan la dotnet TxM (destino x
moniker) funcionen con paquetes que no declaran una dotnet TxM. Si el proyecto usa la dotnet TxM, todos los
paquetes de los que depende también deben tener una dotnet TxM, a menos que agregue el elemento
<PackageTargetFallback> a su proyecto a fin de permitir que las plataformas sin dotnet sean compatibles con dotnet.

En el ejemplo siguiente se proporcionan los elementos Fallback para todos los destinos del proyecto:

<PackageTargetFallback>
$(PackageTargetFallback);portable-net45+win8+wpa81+wp8
</PackageTargetFallback >

En el ejemplo siguiente se especifican los elementos Fallback solo para el destino netcoreapp2.1 :

<PackageTargetFallback Condition="'$(TargetFramework)'=='netcoreapp2.1'">
$(PackageTargetFallback);portable-net45+win8+wpa81+wp8
</PackageTargetFallback >
Eventos de compilación
La forma en que se especifican los eventos anteriores y posteriores a la compilación en el archivo de proyecto ha
cambiado. No se recomiendan las propiedades PreBuildEvent y PostBuildEvent en el formato de proyecto de estilo
SDK, ya que las macros como $(ProjectDir) no se resuelven. Por ejemplo, el código siguiente ya no se admite:

<PropertyGroup>
<PreBuildEvent>"$(ProjectDir)PreBuildEvent.bat" "$(ProjectDir)..\" "$(ProjectDir)" "$(TargetDir)" />
</PropertyGroup>

En los proyectos de estilo SDK, use un destino de MSBuild denominado PreBuild o PostBuild , y establezca la
propiedad BeforeTargets para PreBuild , o bien la propiedad AfterTargets para PostBuild . Para el ejemplo anterior,
use el código siguiente:

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">


<Exec Command="&quot;$(ProjectDir)PreBuildEvent.bat&quot; &quot;$(ProjectDir)..\&quot;
&quot;$(ProjectDir)&quot; &quot;$(TargetDir)&quot;" />
</Target>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">


<Exec Command="echo Output written to $(TargetDir)" />
</Target>

NOTE
Puede usar cualquier nombre para los destinos de MSBuild, pero el IDE de Visual Studio reconoce los destinos PreBuild y
PostBuild , por lo que se recomienda usar esos nombres para poder editar los comandos en el IDE de Visual Studio.

Propiedades de metadatos de NuGet


Con el paso a MSBuild, hemos trasladado los metadatos de entrada que se usan cuando se empaqueta un paquete
NuGet de archivos project.json a archivos .csproj. Las entradas son propiedades de MSBuild, por lo que deben ir
dentro de un grupo <PropertyGroup> . La siguiente es la lista de propiedades que se utilizan como entradas para el
proceso de empaquetado cuando se usa el comando dotnet pack o el destino de MSBuild Pack , que forma parte del
SDK:
IsPackable
Un valor booleano que especifica si se puede empaquetar el proyecto. El valor predeterminado es true .
PackageVersion
Especifica la versión que tendrá el paquete resultante. Acepta todos los formatos de la cadena de versión de NuGet. El
valor predeterminado es $(Version) , es decir, de la propiedad Version del proyecto.
PackageId
Especifica el nombre para el paquete resultante. Si no se especifica, la operación pack usará de forma
predeterminada el elemento AssemblyName o el nombre del directorio como el nombre del paquete.
Title
Un título fácil de usar del paquete, que se usa normalmente en las visualizaciones de la interfaz de usuario, como en
nuget.org, y el Administrador de paquetes de Visual Studio. Si no se especifica, se usa el identificador del paquete en
su lugar.
Authors
Una lista separada por punto y coma de los autores de los paquetes, que coinciden con los nombres de perfil de
nuget.org. Estos se muestran en la galería de NuGet, en nuget.org, y se usan para hacer referencias cruzadas a
paquetes de los mismos autores.
PackageDescription
Una descripción larga del paquete para su visualización en la interfaz de usuario.
Descripción
Una descripción larga del ensamblado. Si PackageDescription no se especifica, esta propiedad también se utiliza
como la descripción del paquete.
Copyright
Detalles de copyright del paquete.
PackageRequireLicenseAcceptance
Un valor booleano que especifica si el cliente debe pedir al consumidor que acepte la licencia del paquete antes de
instalarlo. De manera predeterminada, es false .
PackageLicenseExpression
Identificador de licencia SPDX o expresión. Por ejemplo: Apache-2.0 .
Esta es la lista completa de identificadores de licencia SPDX. NuGet.org acepta solo licencias aprobadas de OSI o FSF
cuando se usa la expresión de tipo de licencia.
La sintaxis exacta de las expresiones de licencia se describe a continuación en ABNF.

license-id = <short form license identifier from https://spdx.org/spdx-specification-21-web-


version#h.luq9dgcle9mo>

license-exception-id = <short form license exception identifier from https://spdx.org/spdx-specification-21-web-


version#h.ruv3yl8g6czd>

simple-expression = license-id / license-id”+”

compound-expression = 1*1(simple-expression /
simple-expression "WITH" license-exception-id /
compound-expression "AND" compound-expression /
compound-expression "OR" compound-expression ) /
"(" compound-expression ")" )

license-expression = 1*1(simple-expression / compound-expression / UNLICENSED)

NOTE
Solo se puede especificar una de estos elementos cada vez: PackageLicenseExpression , PackageLicenseFile o
PackageLicenseUrl .

PackageLicenseFile
Ruta de acceso a un archivo de licencia dentro del paquete si usa una licencia que no tiene asignado un identificador
SPDX, o se trata de una licencia personalizada (en caso contrario, se prefiere PackageLicenseExpression )
Reemplaza a PackageLicenseUrl , no se puede combinar con PackageLicenseExpression y requiere Visual Studio 15.9.4,
SDK de .NET 2.1.502 o 2.2.101, o una versión posterior.
Deberá asegurarse de que el archivo de licencia está empaquetado; para ello, agréguelo explícitamente al proyecto.
Ejemplo de uso:

<PropertyGroup>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<None Include="licenses\LICENSE.txt" Pack="true" PackagePath="$(PackageLicenseFile)"/>
</ItemGroup>
PackageLicenseUrl
Una dirección URL a la licencia que se aplica al paquete. (en desuso desde Visual Studio 15.9.4, SDK de .NET 2.1.502 y
2.2.101)
PackageIconUrl
Una dirección URL para una imagen de 64 x 64 con fondo transparente para usarla como icono para el paquete en la
visualización de la interfaz de usuario.
PackageReleaseNotes
Notas de la versión para el paquete.
PackageTags
Una lista de etiquetas delimitada por punto y coma que designa el paquete.
PackageOutputPath
Determina la ruta de acceso de salida en la que se va a quitar el paquete empaquetado. El valor predeterminado es
$(OutputPath) .

IncludeSymbols
Este valor booleano indica si el paquete debe crear un paquete de símbolos adicionales cuando se empaqueta el
proyecto. El formato del paquete de símbolos se controla mediante la propiedad SymbolPackageFormat .
SymbolPackageFormat
Especifica el formato del paquete de símbolos. Si es "symbols.nupkg", se crea un paquete de símbolos heredado con
una extensión .symbols.nupkg que contiene archivos PDB, DLL y otros archivos de salida. Si es "snupkg", se crea un
paquete de símbolos snupkg que contiene los archivos PDB portátiles. El valor predeterminado es "symbols.nupkg".
IncludeSource
Este valor booleano indica si el proceso de empaquetado debe crear un paquete de origen. El paquete de origen
contiene el código fuente de la biblioteca, así como archivos PDB. Los archivos de origen se colocan en el directorio
src/ProjectName , en el archivo de paquete resultante.

IsTool
Especifica si se copian todos los archivos de salida en la carpeta tools en lugar de la carpeta lib. Tenga en cuenta que
esto es diferente de un elemento DotNetCliTool , que se especifica estableciendo el elemento PackageType en el
archivo .csproj.
RepositoryUrl
Especifica la dirección URL del repositorio donde reside el código fuente del paquete o desde el que se está creando.
RepositoryType
Especifica el tipo del repositorio. El valor predeterminado es “git”.
RepositoryBranch
Especifica el nombre de la rama de origen en el repositorio. Cuando el proyecto se empaqueta en un paquete NuGet,
se agrega a los metadatos del paquete.
RepositoryCommit
Confirmación o conjunto de cambios opcionales de repositorio para indicar en qué origen se ha compilado el paquete.
RepositoryUrl también se debe especificar para que esta propiedad se incluya. Cuando el proyecto se empaqueta en
un paquete NuGet, esta confirmación o conjunto de cambios se agrega a los metadatos del paquete.
NoPackageAnalysis
Especifica que el paquete no debe ejecutar el análisis de paquetes después de crear el paquete.
MinClientVersion
Especifica la versión mínima del cliente de NuGet que puede instalar este paquete, aplicada por nuget.exe y el
Administrador de paquetes de Visual Studio.
IncludeBuildOutput
Este valor booleano especifica si se deben empaquetar los ensamblados de salida de la compilación en el archivo
.nupkg o no.
IncludeContentInPack
Este valor booleano especifica si los elementos del tipo Content se incluirán automáticamente en el paquete
resultante. De manera predeterminada, es true .
BuildOutputTargetFolder
Especifica la carpeta en la que se colocarán los ensamblados de salida. Los ensamblados de salida (y otros archivos de
salida) se copian en sus respectivas carpetas de marco.
ContentTargetFolders
Esta propiedad especifica la ubicación predeterminada a la que deben ir todos los archivos de contenido si no se
especifica PackagePath para ellos. El valor predeterminado es “content;contentFiles”.
NuspecFile
Ruta de acceso relativa o absoluta al archivo .nuspec que se usa para el empaquetado.

NOTE
Si se especifica el archivo .nuspec, se usa exclusivamente para la información de empaquetado y no se usa ninguna de la
información de los proyectos.

NuspecBasePath
Ruta de acceso base para el archivo .nuspec.
NuspecProperties
Lista separada por punto y coma de pares clave=valor.

Propiedades de AssemblyInfo
Los atributos de ensamblado que solían estar presentes en un archivo AssemblyInfo ahora se generan
automáticamente a partir de las propiedades.
Propiedades por atributo
Cada atributo tiene una propiedad que controla su contenido y otra para deshabilitar la generación, tal como se
muestra en la tabla siguiente:

ATRIBUTO PROPIEDAD. PROPIEDAD QUE SE VA A DESHABILITAR

AssemblyCompanyAttribute Company GenerateAssemblyCompanyAttribute

AssemblyConfigurationAttribute Configuration GenerateAssemblyConfigurationAttribute

AssemblyCopyrightAttribute Copyright GenerateAssemblyCopyrightAttribute

AssemblyDescriptionAttribute Description GenerateAssemblyDescriptionAttribute

AssemblyFileVersionAttribute FileVersion GenerateAssemblyFileVersionAttribute

AssemblyInformationalVersionAttribute InformationalVersion GenerateAssemblyInformationalVersionAttribute


ATRIBUTO PROPIEDAD. PROPIEDAD QUE SE VA A DESHABILITAR

AssemblyProductAttribute Product GenerateAssemblyProductAttribute

AssemblyTitleAttribute AssemblyTitle GenerateAssemblyTitleAttribute

AssemblyVersionAttribute AssemblyVersion GenerateAssemblyVersionAttribute

NeutralResourcesLanguageAttribute NeutralLanguage GenerateNeutralResourcesLanguageAttribute

Notas:
El comportamiento predeterminado de AssemblyVersion y FileVersion consiste en adoptar el valor de
$(Version) sin sufijo. Por ejemplo, si $(Version) es 1.2.3-beta.4 , entonces el valor sería 1.2.3 .
El valor predeterminado de InformationalVersion es el de $(Version) .
InformationalVersion tiene $(SourceRevisionId) anexado si la propiedad está presente. Puede deshabilitarse
mediante IncludeSourceRevisionInInformationalVersion .
Las propiedades Copyright y Description también se utilizan para metadatos de NuGet.
Configuration se comparte con todos los procesos de compilación y se establece mediante el parámetro
--configuration de los comandos dotnet .

GenerateAssemblyInfo
Un valor booleano que habilita o deshabilita toda la generación de AssemblyInfo. El valor predeterminado es true .
GeneratedAssemblyInfoFile
La ruta de acceso del archivo de información del ensamblado generado. De forma predeterminada, se trata de un
archivo del directorio $(IntermediateOutputPath) (obj).
Migración de .NET Core 2.0 a 2.1
12/01/2020 • 2 minutes to read • Edit Online

En este artículo se muestran los pasos básicos para migrar la aplicación de .NET Core 2.0 a 2.1. Si está pensando
en migrar la aplicación de ASP.NET Core a 2.1, vea Migración de ASP.NET Core 2.0 a 2.1.
Para obtener información general de las nuevas características de .NET Core 2.1, vea Novedades de .NET Core 2.1.

Actualización del archivo de proyecto para que use las versiones 2.1
Abra el archivo de proyecto (el archivo *.csproj, *.vbproj o *.fsproj).
Cambie el valor de la plataforma de destino de netcoreapp2.0 a netcoreapp2.1 . La plataforma de destino
está definida por el elemento <TargetFramework> o <TargetFrameworks> .
Por ejemplo, cambie <TargetFramework>netcoreapp2.0</TargetFramework> a
<TargetFramework>netcoreapp2.1</TargetFramework> .
Quite las referencias <DotNetCliToolReference> para las herramientas que están incluidas en el SDK de .NET
Core 2.1 (v 2.1.300 o posterior). Estas referencias incluyen:
dotnet-watch (Microsoft.DotNet.Watcher.Tools)
dotnet-user-secrets (Microsoft.Extensions.SecretManager.Tools)
dotnet-sql-cache (Microsoft.Extensions.Caching.SqlConfig.Tools)
dotnet-ef (Microsoft.EntityFrameworkCore.Tools.DotNet)
En versiones anteriores del SDK de .NET Core, la referencia a una de estas herramientas en el archivo de
proyecto tiene un aspecto similar al ejemplo siguiente:

<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />

Puesto que el SDK de .NET Core ya no utiliza esta entrada, verá una advertencia similar a la siguiente si
todavía tiene referencias a una de estas herramientas agrupadas en el proyecto:
The tool 'Microsoft.EntityFrameworkCore.Tools.DotNet' is now included in the .NET Core SDK. Here is
information on resolving this warning.

Este problema se soluciona quitando las referencias a <DotNetCliToolReference> para estas herramientas
desde el archivo del proyecto.

Vea también
Migración de ASP.NET Core 2.0 a 2.1
Novedades de .NET Core 2.1
Migración de proyectos de .NET Core desde
project.json
10/01/2020 • 10 minutes to read • Edit Online

En este documento se tratan los tres escenarios de migración siguientes para los proyectos de .NET Core:
1. Migración desde un esquema válido más reciente de project.json a csproj
2. Migración desde DNX a csproj
3. Migración desde proyectos de csproj de .NET Core RC3 y anteriores al formato final
Este documento solo es aplicable a proyectos antiguos de .NET Core que usan project.json. No se aplica a la
migración de .NET Framework a .NET Core.

Migración desde project.json a csproj


La migración desde project.json a .csproj puede realizarse mediante uno de los métodos siguientes:
Visual Studio
Herramienta de línea de comandos dotnet migrate
Ambos métodos usan el mismo motor subyacente para migrar los proyectos, por lo que los resultados serán los
mismos para ambos. En la mayoría de los casos, tan solo será necesario usar una de estas dos formas de migrar
project.json a csproj, y no se requerirá ninguna otra edición manual del archivo del proyecto. El archivo .csproj
resultante tendrá el mismo nombre que el directorio que lo contiene.
Programa para la mejora
Al abrir un archivo .xproj o un archivo de solución que hace referencia a archivos .xproj en Visual Studio 2017 o
Visual Studio 2019, versión 16.2 y versiones anteriores, se abre el cuadro de diálogo Actualización
unidireccional. El cuadro de diálogo muestra los proyectos que se van a migrar. Si se abre un archivo de solución,
se enumeran todos los proyectos especificados en el archivo de solución. Revise la lista de proyectos que se van a
migrar y haga clic en Aceptar.

Visual Studio migra automáticamente los proyectos seleccionados. Al migrar una solución, si no elige todos los
proyectos, aparece el mismo cuadro de diálogo preguntando si quiere actualizar los proyectos restantes de esa
solución. Después de migrar el proyecto, puede ver y modificar su contenido. Para ello, haga clic con el botón
derecho en el proyecto en la ventana del Explorador de soluciones y seleccione Editar <nombre del
proyecto>.csproj.
Los archivos que se migraron (project.json, global.json, .xproj y el archivo de solución) se mueven a una carpeta
Copia de seguridad. El archivo de solución migrado se actualiza a Visual Studio 2017 o Visual Studio 2019 y no
podrá abrir ese archivo de solución en Visual Studio 2015 ni en versiones anteriores. También se guarda y se abre
automáticamente un archivo denominado UpgradeLog.htm que contiene un informe de migración.

IMPORTANT
En la versión 16.3 de Visual Studio 2019 y versiones posteriores, no se puede cargar ni migrar un archivo .xproj . Además,
Visual Studio 2015 no permite migrar un archivo .xproj. Si utiliza una de estas versiones de Visual Studio, instale una versión
adecuada de Visual Studio o use la herramienta de migración de la línea de comandos que se indica a continuación.

dotnet migrate
En el escenario de la línea de comandos, puede usar el comando dotnet migrate . Se migra un proyecto, una
solución o un conjunto de carpetas, en ese orden, dependiendo de lo que se encuentre. Cuando se migra un
proyecto, se migra el proyecto y todas sus dependencias.
Los archivos que se migraron (project.json, global.json y .xproj) se mueven a una carpeta Copia de seguridad.

NOTE
Si se usa Visual Studio Code, el comando dotnet migrate no modifica archivos específicos de Visual Studio Code, como
tasks.json. Estos archivos deben modificarse de forma manual. Esto también sucede si se usa cualquier editor o entorno de
desarrollo integrado (IDE) que no sea Visual Studio.

Consulte Una asignación entre propiedades project.json y csproj para una comparación de los formatos
project.json y .csproj.
Si se produce un error que indica que

no se encuentra ningún archivo que coincida con el comando dotnet-migrate,

Ejecute dotnet --version para ver qué versión está usando. dotnet migrate se presentó en la versión 1.0.0 del
SDK de .NET Core y se quitó en la versión 3.0.100. Obtendrá este error si tiene un archivo global.json en el
directorio actual o principal y la versión de sdk que especifica está fuera de este rango.

Migración desde DNX a csproj


Si aún usa DNX para el desarrollo de .NET Core, el proceso de migración debe realizarse en dos fases:
1. Use la guía de migración de DNX existente para migrar desde DNX a la CLI compatible con project.json.
2. Siga los pasos de la sección anterior para migrar desde project.json a .csproj.

NOTE
DNX quedó oficialmente en desuso durante la versión Preview 1 de la CLI de .NET Core.

Migración desde formatos anteriores de csproj de .NET Core a csproj


RTM
El formato de csproj de .NET Core ha cambiado y evolucionado con cada nueva versión preliminar de las
herramientas. No hay ninguna herramienta que migre el archivo del proyecto de versiones anteriores de csproj a la
versión más reciente, por lo que tendrá que editar manualmente el archivo del proyecto. Los pasos reales
dependen de la versión del archivo del proyecto que se va a migrar. Tenga en cuenta los siguientes consejos
basados en los cambios que se produjeron entre las versiones:
Quite la propiedad de versión de las herramientas del elemento <Project> , si existe.
Quite el espacio de nombres XML ( xmlns ) del elemento <Project> .
Si no existe, agregue el atributo Sdk al elemento <Project> y establézcalo en Microsoft.NET.Sdk o
Microsoft.NET.Sdk.Web . Este atributo especifica que el proyecto usa el SDK que se va a usar.
Microsoft.NET.Sdk.Web se usa para las aplicaciones web.
Quite las instrucciones
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> e
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> de la parte superior e inferior del proyecto.
Estas instrucciones de importación están implícitas en el SDK, por lo que no es necesario que estén en el
proyecto.
Si tiene elementos Microsoft.NETCore.App o NETStandard.Library <PackageReference> en el proyecto, debe
quitarlos. Estas referencias de paquete son implícitas para el SDK .
Quite el elemento Microsoft.NET.Sdk <PackageReference> , si existe. La referencia del SDK procede del atributo
Sdk del elemento <Project> .
Quite los globs que están implícitos en el SDK. Dejar estos patrones globales en el proyecto producirá un error
de compilación porque se duplicarán los elementos de compilación.
Tras seguir estos pasos, el proyecto debe ser totalmente compatible con el formato csproj RTM de .NET Core.
Para obtener ejemplos de antes y después de la migración desde el formato csproj antiguo al nuevo, vea el artículo
Updating Visual Studio 2017 RC – .NET Core Tooling improvements (Actualización de Visual Studio 2017 RC:
Mejoras de las herramientas de .NET Core) en el blog de .NET.

Vea también
Portar, migrar y actualizar proyectos de Visual Studio
Una asignación entre propiedades project.json y
csproj
12/01/2020 • 10 minutes to read • Edit Online

Por Nate McMaster


Durante el desarrollo de las herramientas de .NET Core, se realizó un cambio de diseño importante para dejar de
admitir los archivos project.json y trasladar en su lugar los proyectos .NET Core al formato MSBuild/csproj.
En este artículo se muestra cómo se representa la configuración de project.json en el formato MSBuild/csproj para
que pueda aprender a usar el nuevo formato y comprender los cambios realizados por las herramientas de
migración cuando actualice el proyecto a la versión más reciente de la herramienta.

El formato csproj
El nuevo formato, *.csproj, está basado en XML. En el ejemplo siguiente se muestra el nodo raíz de un proyecto
.NET Core con el SDK Microsoft.NET.Sdk . Para proyectos web, el SDK que se usa es Microsoft.NET.Sdk.Web .

<Project Sdk="Microsoft.NET.Sdk">
...
</Project>

Propiedades comunes de nivel superior


name

{
"name": "MyProjectName"
}

Ya no se admite. En csproj, viene determinado por el nombre de archivo del proyecto, que normalmente coincide
con el nombre del directorio. Por ejemplo: MyProjectName.csproj .
De forma predeterminada, el nombre de archivo del proyecto también especifica el valor de las propiedades
<AssemblyName> y <PackageId> .

<PropertyGroup>
<AssemblyName>MyProjectName</AssemblyName>
<PackageId>MyProjectName</PackageId>
</PropertyGroup>

La propiedad <AssemblyName> tendrá un valor diferente a <PackageId> si se ha definido la propiedad


buildOptions\outputName en project.json. Para obtener más información, consulte Otras opciones de compilación
comunes.
version
{
"version": "1.0.0-alpha-*"
}

Use las propiedades VersionPrefix y VersionSuffix :

<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha</VersionSuffix>
</PropertyGroup>

También puede usar la propiedad Version , pero esto puede invalidar la configuración de la versión durante el
empaquetado:

<PropertyGroup>
<Version>1.0.0-alpha</Version>
</PropertyGroup>

Otras opciones comunes de nivel de raíz

{
"authors": [ "Anne", "Bob" ],
"company": "Contoso",
"language": "en-US",
"title": "My library",
"description": "This is my library.\r\nAnd it's really great!",
"copyright": "Nugetizer 3000",
"userSecretsId": "xyz123"
}

<PropertyGroup>
<Authors>Anne;Bob</Authors>
<Company>Contoso</Company>
<NeutralLanguage>en-US</NeutralLanguage>
<AssemblyTitle>My library</AssemblyTitle>
<Description>This is my library.
And it's really great!</Description>
<Copyright>Nugetizer 3000</Copyright>
<UserSecretsId>xyz123</UserSecretsId>
</PropertyGroup>

frameworks
Un marco de trabajo de destino

{
"frameworks": {
"netcoreapp1.0": {}
}
}

<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>
Varios marcos de trabajo de destino

{
"frameworks": {
"netcoreapp1.0": {},
"net451": {}
}
}

Use la propiedad TargetFrameworks para definir la lista de los marcos de trabajo de destino. Use el punto y coma
para separar varios valores de marco de trabajo.

<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
</PropertyGroup>

dependencias
IMPORTANT
Si la dependencia es un proyecto y no un paquete, el formato es diferente. Para obtener más información, consulte la
sección tipo de dependencia.

Metapaquete NETStandard.Library

{
"dependencies": {
"NETStandard.Library": "1.6.0"
}
}

<PropertyGroup>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
</PropertyGroup>

Metapaquete Microsoft.NETCore.App

{
"dependencies": {
"Microsoft.NETCore.App": "1.0.0"
}
}

<PropertyGroup>
<RuntimeFrameworkVersion>1.0.3</RuntimeFrameworkVersion>
</PropertyGroup>

Tenga en cuenta que el valor <RuntimeFrameworkVersion> del proyecto migrado viene determinado por la versión
del SDK que ha instalado.
Dependencias de nivel superior
{
"dependencies": {
"Microsoft.AspNetCore": "1.1.0"
}
}

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" />
</ItemGroup>

Dependencias por marco de trabajo

{
"framework": {
"net451": {
"dependencies": {
"System.Collections.Immutable": "1.3.1"
}
},
"netstandard1.5": {
"dependencies": {
"Newtonsoft.Json": "9.0.1"
}
}
}
}

<ItemGroup Condition="'$(TargetFramework)'=='net451'">
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>

imports

{
"dependencies": {
"YamlDotNet": "4.0.1-pre309"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"dotnet"
]
}
}
}

<PropertyGroup>
<PackageTargetFallback>dnxcore50;dotnet</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="4.0.1-pre309" />
</ItemGroup>
dependency type
type: project

{
"dependencies": {
"MyOtherProject": "1.0.0-*",
"AnotherProject": {
"type": "project"
}
}
}

<ItemGroup>
<ProjectReference Include="..\MyOtherProject\MyOtherProject.csproj" />
<ProjectReference Include="..\AnotherProject\AnotherProject.csproj" />
</ItemGroup>

NOTE
Esto interrumpirá la forma en que dotnet pack --version-suffix $suffix determina la versión de dependencia de una
referencia de proyecto.

type: build

{
"dependencies": {
"Microsoft.EntityFrameworkCore.Design": {
"version": "1.1.0",
"type": "build"
}
}
}

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.0" PrivateAssets="All" />
</ItemGroup>

type: platform

{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.1.0",
"type": "platform"
}
}
}

No existe ningún equivalente en csproj.

runtimes
{
"runtimes": {
"win7-x64": {},
"osx.10.11-x64": {},
"ubuntu.16.04-x64": {}
}
}

<PropertyGroup>
<RuntimeIdentifiers>win7-x64;osx.10.11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
</PropertyGroup>

Aplicaciones independientes (implementación autocontenida)


En project.json, definir una sección runtimes implica que la aplicación se ha mantenido independiente durante la
compilación y la publicación. En MSBuild, todos los proyectos son portátiles durante la compilación, pero se
pueden publicar como independientes.
dotnet publish --framework netcoreapp1.0 --runtime osx.10.11-x64

Para obtener más información, consulte Implementaciones autocontenidas (SCD ).

tools
{
"tools": {
"Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-*"
}
}

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>

NOTE
En csproj no se admite imports en herramientas. Las herramientas que necesitan importaciones no funcionarán con el
nuevo SDK Microsoft.NET.Sdk .

buildOptions
Consulte también Archivos.
emitEntryPoint

{
"buildOptions": {
"emitEntryPoint": true
}
}
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

Si emitEntryPoint era false , el valor de OutputType se convierte en Library , que es el valor predeterminado:

{
"buildOptions": {
"emitEntryPoint": false
}
}

<PropertyGroup>
<OutputType>Library</OutputType>
<!-- or, omit altogether. It defaults to 'Library' -->
</PropertyGroup>

keyFile

{
"buildOptions": {
"keyFile": "MyKey.snk"
}
}

El elemento keyFile se expande a tres propiedades en MSBuild:

<PropertyGroup>
<AssemblyOriginatorKeyFile>MyKey.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>

Otras opciones de compilación comunes

{
"buildOptions": {
"warningsAsErrors": true,
"nowarn": ["CS0168", "CS0219"],
"xmlDoc": true,
"preserveCompilationContext": true,
"outputName": "Different.AssemblyName",
"debugType": "portable",
"allowUnsafe": true,
"define": ["TEST", "OTHERCONDITION"]
}
}
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);CS0168;CS0219</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Different.AssemblyName</AssemblyName>
<DebugType>portable</DebugType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);TEST;OTHERCONDITION</DefineConstants>
</PropertyGroup>

packOptions
Consulte también Archivos.
Opciones comunes de empaquetado

{
"packOptions": {
"summary": "numl is a machine learning library intended to ease the use of using standard modeling
techniques for both prediction and clustering.",
"tags": ["machine learning", "framework"],
"releaseNotes": "Version 0.9.12-beta",
"iconUrl": "http://numl.net/images/ico.png",
"projectUrl": "http://numl.net",
"licenseUrl": "https://raw.githubusercontent.com/sethjuarez/numl/master/LICENSE.md",
"requireLicenseAcceptance": false,
"repository": {
"type": "git",
"url": "https://raw.githubusercontent.com/sethjuarez/numl"
},
"owners": ["Seth Juarez"]
}
}

<PropertyGroup>
<!-- summary is not migrated from project.json, but you can use the <Description> property for that if
needed. -->
<PackageTags>machine learning;framework</PackageTags>
<PackageReleaseNotes>Version 0.9.12-beta</PackageReleaseNotes>
<PackageIconUrl>http://numl.net/images/ico.png</PackageIconUrl>
<PackageProjectUrl>http://numl.net</PackageProjectUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/sethjuarez/numl/master/LICENSE.md</PackageLicenseUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://raw.githubusercontent.com/sethjuarez/numl</RepositoryUrl>
<!-- owners is not supported in MSBuild -->
</PropertyGroup>

No hay ningún equivalente del elemento owners en MSBuild. Para summary , puede usar la propiedad
<Description> de MSBuild, aunque el valor de summary no se migra automáticamente a esa propiedad, ya que
esta se asigna al elemento description .

scripts
{
"scripts": {
"precompile": "generateCode.cmd",
"postpublish": [ "obfuscate.cmd", "removeTempFiles.cmd" ]
}
}

Su equivalente en MSBuild es target:

<Target Name="MyPreCompileTarget" BeforeTargets="Build">


<Exec Command="generateCode.cmd" />
</Target>

<Target Name="MyPostCompileTarget" AfterTargets="Publish">


<Exec Command="obfuscate.cmd" />
<Exec Command="removeTempFiles.cmd" />
</Target>

runtimeOptions
{
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true,
"System.GC.Concurrent": true,
"System.GC.RetainVM": true,
"System.Threading.ThreadPool.MinThreads": 4,
"System.Threading.ThreadPool.MaxThreads": 25
}
}
}

Todos los valores de configuración de este grupo, excepto la propiedad “System.GC.Server”, se colocan en un
archivo denominado runtimeconfig.template.json en la carpeta del proyecto, con opciones elevadas al objeto raíz
durante el proceso de migración:

{
"configProperties": {
"System.GC.Concurrent": true,
"System.GC.RetainVM": true,
"System.Threading.ThreadPool.MinThreads": 4,
"System.Threading.ThreadPool.MaxThreads": 25
}
}

Se migra la propiedad “System.GC.Server” al archivo csproj:

<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

En cambio, puede establecer todos esos valores en csproj, así como en propiedades de MSBuild:
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<RetainVMGarbageCollection>true</RetainVMGarbageCollection>
<ThreadPoolMinThreads>4</ThreadPoolMinThreads>
<ThreadPoolMaxThreads>25</ThreadPoolMaxThreads>
</PropertyGroup>

shared
{
"shared": "shared/**/*.cs"
}

No se admite en csproj. En su lugar, debe incluir archivos de contenido en el archivo .nuspec. Para obtener más
información, consulte Including content files (Incluir archivos de contenido).

archivos
En project.json, la compilación y el empaquetado podrían ampliarse para compilar e insertar desde diferentes
carpetas. En MSBuild, esto se hace mediante elementos. En el siguiente ejemplo se muestra una conversión
común:

{
"buildOptions": {
"compile": {
"copyToOutput": "notes.txt",
"include": "../Shared/*.cs",
"exclude": "../Shared/Not/*.cs"
},
"embed": {
"include": "../Shared/*.resx"
}
},
"packOptions": {
"include": "Views/",
"mappings": {
"some/path/in/project.txt": "in/package.txt"
}
},
"publishOptions": {
"include": [
"files/",
"publishnotes.txt"
]
}
}
<ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="..\Shared\Not\*.cs" />
<EmbeddedResource Include="..\Shared\*.resx" />
<Content Include="Views\**\*" PackagePath="%(Identity)" />
<None Include="some/path/in/project.txt" Pack="true" PackagePath="in/package.txt" />

<None Include="notes.txt" CopyToOutputDirectory="Always" />


<!-- CopyToOutputDirectory = { Always, PreserveNewest, Never } -->

<Content Include="files\**\*" CopyToPublishDirectory="PreserveNewest" />


<None Include="publishnotes.txt" CopyToPublishDirectory="Always" />
<!-- CopyToPublishDirectory = { Always, PreserveNewest, Never } -->
</ItemGroup>

NOTE
El SDK de .NET Core agrega automáticamente muchos de los patrones globales predeterminados. Para obtener más
información, consulte Default Compile Item Values (Valores de elementos de compilación predeterminados).

Todos los elementos ItemGroup de MSBuild admiten Include , Exclude y Remove .


Se puede modificar el diseño del paquete dentro de .nupkg con PackagePath="path" .
A excepción de Content , la mayoría de los grupos de elementos requiere que se agregue explícitamente
Pack="true" para incluirlos en el paquete. Content se colocará en la carpeta content de un paquete, puesto que la
propiedad <IncludeContentInPack> de MSBuild está establecida como true de forma predeterminada. Para
obtener más información, consulte Including content in a package (Incluir contenido en un paquete).
PackagePath="%(Identity)" es una forma rápida de establecer la ruta del paquete como la ruta del archivo relativa
al proyecto.

testRunner
xUnit

{
"testRunner": "xunit",
"dependencies": {
"dotnet-test-xunit": "<any>"
}
}

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
<PackageReference Include="xunit" Version="2.2.0-*" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-*" />
</ItemGroup>

MSTest

{
"testRunner": "mstest",
"dependencies": {
"dotnet-test-mstest": "<any>"
}
}
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.12-*" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.11-*" />
</ItemGroup>

Vea también
Introducción de alto nivel de cambios en la CLI
Migración de DNX a CLI de .NET Core (project.json)
12/01/2020 • 18 minutes to read • Edit Online

Información general
Con la versión RC1 de .NET Core y ASP.NET Core 1.0, presentamos las herramientas DNX. Con la versión RC2
de .NET Core y ASP.NET Core 1.0, hicimos la transición de DNX a .NET Core CLI.
Resumamos un poco de qué se trata DNX como un breve recordatorio. DNX era un entorno de ejecución y un
conjunto de herramientas para compilar aplicaciones de .NET Core y, más específicamente, de ASP.NET Core 1.0.
Constaba de 3 componentes principales:
1. DNVM: un script de instalación para obtener DNX.
2. DNX (entorno de ejecución Dotnet): el entorno de ejecución que ejecuta el código.
3. DNU (utilidad para desarrolladores de Dotnet): herramientas para administrar dependencias y compilar y
publicar las aplicaciones.
Con la presentación de la CLI, todos los componentes anteriores ahora forman parte de un conjunto de
herramientas único. Sin embargo, como DNX estaba disponible en el período de tiempo de RC1, es posible que
tenga proyectos que se compilaron así que desearía mover a las nuevas herramientas de CLI.
En esta guía de migración se analizarán los aspectos fundamentales sobre cómo migrar proyectos de DNX a la
CLI de .NET Core. Si recién está comenzando un proyecto en .NET Core desde cero, puede omitir sin problemas
este documento.

Principales cambios en las herramientas


En primer lugar, es necesario describir algunos cambios generales en las herramientas.
No más DNVM
DNVM, abreviatura para el inglés de Administrador de versiones DotNet era un script de PowerShell/búsqueda
intensiva que se usaba para instalar un DNX en la máquina. Ayudó a los usuarios a obtener el DNX que
necesitaban a partir de la fuente que especificaban (o la fuente predeterminada), además de marcar cierto DNX
como "activo", lo que lo ubicaría en la $PATH de la sesión especificada. Esto le permitiría usar las diversas
herramientas.
DNVM se interrumpió porque su conjunto de características se volvió redundante debido a los cambios
introducidos con las herramientas de la CLI de .NET Core.
Las herramientas de la CLI vienen empaquetadas de dos maneras principales:
1. Instaladores nativos en una plataforma determinada.
2. Script de instalación para otras situaciones (como los servidores de CI).
Por lo tanto, no se necesitan las características de instalación de DNVM. ¿Qué sucede, entonces, con las
características de selección del entorno de ejecución?
Si agrega un paquete de cierta versión a las dependencias, hace referencia a un entorno de ejecución en su
project.json . Con este cambio, la aplicación podrá usar los nuevos bits de entorno de ejecución. Incorporar estos
bits a la máquina es similar a lo que sucede con la CLI: instala el entorno de ejecución a través de los instaladores
nativos que admite o a través del script de instalación.
Otros comandos
Si usó DNX, usaba algunos comandos provenientes de uno de sus tres componentes (DNX, DNU o DNVM ). Con
la CLI, algunos de estos comandos cambian, algunos no están disponibles y otros son iguales, pero con pequeñas
diferencias semánticas.
La tabla siguiente muestra la asignación entre los comandos de DNX/DNU y sus contrapartes de la CLI.

COMANDO DE DNX COMANDO DE LA CLI DESCRIPCIÓN

dnx run dotnet run Ejecute el código desde el origen.

dnu build dotnet build Compile un archivo binario de IL del


código.

dnu pack dotnet pack Cree un paquete NuGet del código.

dnx [comando] (por ejemplo, "dnx web") no disponible* Si se usa DNX, ejecute un comando
según lo definido en project.json.

dnu install no disponible* Si se usa DNX, instale un paquete como


dependencia.

dnu restore dotnet restore Restaure las dependencias especificadas


en project.json. (vea la nota)

dnu publish dotnet publish Publique la aplicación para su


implementación en una de tres formas
(portátil, portátil con nativo e
independiente).

dnu wrap no disponible* Si se usa DNX, encapsule un archivo


project.json en csproj.

dnu commands no disponible* Si se usa DNX, administre los comandos


instalados globalmente.

(*): por diseño, la CLI no admite estas características.

Características de DNX no admitidas


Tal como muestra la tabla anterior, hay características de DNX que decidimos no admitir en la CLI, al menos por el
momento. En esta sección se analizarán las más importantes y se describe el razonamiento detrás de la decisión
de no admitirlas, además de las soluciones que puede implementar si las necesita.
Comandos globales
DNU incluía un concepto llamado "comandos globales". En esencia, se trataba de aplicaciones de consola
empaquetadas como paquetes NuGet con un script de shell que podría invocar el DNX especificado para ejecutar
la aplicación.
La CLI no admite este concepto. Sin embargo, sí admite el concepto de agregar comandos por proyecto que se
pueden invocar con la conocida sintaxis dotnet <command> .
Instalación de dependencias
A partir de la versión v1, las herramientas de la CLI de .NET Core no tienen un comando install para instalar
dependencias. Para instalar un paquete desde NuGet, necesita agregarlo como una dependencia al archivo
project.json y, luego, ejecutar dotnet restore (vea la nota).
Ejecución del código
Existen dos formas principales de ejecutar el código. Una es desde el origen, con dotnet run . A diferencia de
dnx run , no hará ninguna compilación en memoria. En realidad, invocará a dotnet build para compilar el código
y, luego, ejecutar el archivo binario compilado.
La otra forma es usar el dotnet mismo para ejecutar el código. Para ello, proporcione una ruta de acceso al
ensamblado: dotnet path/to/an/assembly.dll .

Migración del proyecto DNX a la CLI de .NET Core


Además de usar los comandos nuevos cuando se trabaja con el código, hay 3 aspectos importantes que se
dejaron en la migración desde DNX:
1. Si lo tiene, migre el archivo global.json para usar la CLI.
2. Migración del archivo del proyecto ( project.json ) mismo a las herramientas de la CLI.
3. Migración de cualquier API de DNX a sus contrapartes de BCL.
Cambio del archivo global.json
El archivo global.json actúa como un archivo de solución tanto para los proyectos de RC1 como para los de RC2
(o posteriores). A fin de que las herramientas de la CLI (como también Visual Studio) diferencien entre RC1 y las
versiones posteriores, usan la propiedad "sdk": { "version" } para hacer la distinción entre qué proyecto es RC1
o posterior. Si global.json no tiene este nodo, se supone que es la versión más reciente.
Con el fin de actualizar el archivo global.json , quite la propiedad o establézcala en la versión exacta de las
herramientas que desea usar; en este caso, 1.0.0-preview2-003121:

{
"sdk": {
"version": "1.0.0-preview2-003121"
}
}

Migración del archivo del proyecto


Tanto la CLI como DNX usan el mismo sistema de proyectos básico basado en el archivo project.json . La
sintaxis y la semántica del archivo del proyecto son prácticamente iguales, con pequeñas diferencias en función de
los escenarios. También hay algunos cambios en el esquema que puede ver en el archivo del esquema.
Si compila una aplicación de consola, debe agregar el siguiente fragmento de código al archivo del proyecto:

"buildOptions": {
"emitEntryPoint": true
}

Esto indica a dotnet build que emita un punto de entrada para la aplicación, lo que permitirá que el código se
pueda ejecutar. Si compila una biblioteca de clases, simplemente debe omitir la sección anterior. Por supuesto, una
vez que agregue el fragmento de código anterior al archivo project.json , deberá agregar un punto de entrada
estático. Con la migración de DNX, los servicios de DI que proporcionaba ya no están disponibles y, por lo tanto,
debe tratarse de un punto de entrada .NET básico: static void Main() .
Si tiene una sección de "comandos" en su project.json , puede quitarla. Algunos de los comandos que existían
como comandos de DNU, como los comandos de la CLI de Entity Framework, se trasladan para convertirse en
extensiones por proyecto en la CLI. Si compila sus propios comandos que usa en los proyectos, debe
reemplazarlos con extensiones de la CLI. En este caso, el nodo commands de project.json debe reemplazarse por
el nodo tools y se deben enumerar las dependencias de herramientas.
Una vez hecho esto, deberá decidir qué tipo de portabilidad desea para la aplicación. Con .NET Core, invertimos
en proporcionar un espectro de opciones de portabilidad entre las que puede elegir. Por ejemplo, podría tener una
aplicación completamente portátil, o bien podría querer tener una aplicación autocontenida. La opción de la
aplicación portátil es más similar a cómo funcionan las aplicaciones de .NET Framework: necesita un componente
compartido para ejecutarlo en la máquina de destino (.NET Core). La aplicación autocontenida no requiere que
.NET Core esté instalado en el destino, pero es necesario generar una aplicación para cada SO que desea admitir.
Estos tipos de portabilidad, y otros más, se analizan en el documento sobre los tipos de portabilidad de
aplicaciones.
Una vez que decide el tipo de portabilidad que desea, deberá cambiar las plataformas de destino. Si escribiera
aplicaciones para .NET Core, es probable que use dnxcore50 como la plataforma de destino. Con la CLI y los
cambios que trajo la nueva especificación .NET Standard, la plataforma debe ser una de las siguientes:
1. netcoreapp1.0 , si escribe aplicaciones en .NET Core (incluidas las aplicaciones de ASP.NET Core).
2. netstandard1.6 , si escribe las bibliotecas de clases para .NET Core.

Si usa otros destinos dnx , como dnx451 , también deberá cambiarlos. dnx451 se debe cambiar a net451 .
Consulte el tema Estándar .NET para obtener más información.
El archivo project.json está casi listo. Debe revisar la lista de dependencias y actualizarlas a sus versiones más
recientes, especialmente si usa las dependencias de ASP.NET Core. Si usará los paquetes independientes para las
API de BCL, puede usar el paquete del entorno de ejecución tal como se explica en el documento sobre los tipos
de portabilidad de aplicaciones.
Cuando esté listo, puede intentar la restauración con dotnet restore (vea la nota). En función de la versión de las
dependencias, puede encontrar errores si NuGet no puede resolver las dependencias de una de las plataformas de
destino anteriormente mencionadas. Este es un problema "en un momento específico"; a medida que pase el
tiempo, cada vez más paquetes incluirán compatibilidad con estos marcos de trabajo. Por ahora, si se enfrenta con
este problema, puede usar la instrucción imports dentro del nodo framework para especificar a NuGet que puede
restaurar los paquetes que tienen como destino el marco de trabajo que se encuentra dentro de la instrucción de
"importaciones". Los errores de restauración que recibe en este caso deben proporcionar información suficiente
que le permita distinguir los marcos de trabajo que debe importar. Si está un poco confundido o es nuevo en esto,
en palabras generales, bastaría con especificar dnxcore50 y portable-net45+win8 en la instrucción imports . El
fragmento de código JSON siguiente muestra cómo se verá:

"frameworks": {
"netcoreapp1.0": {
"imports": ["dnxcore50", "portable-net45+win8"]
}
}

La ejecución de dotnet build mostrará cualquier posible error de compilación, aunque no debería haber muchos.
Una vez que el código se compile y ejecute correctamente, puede probarlo con el ejecutor. Ejecute
dotnet <path-to-your-assembly> y vea si se ejecuta correctamente.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Implementación de aplicaciones .NET Core
08/01/2020 • 12 minutes to read • Edit Online

Puede crear tres tipos de implementaciones para aplicaciones .NET Core:


Implementación dependiente de Framework. Como su nombre indica, la implementación dependiente
de marco de trabajo (FDD ) se basa en la presencia de una versión compartida de .NET Core en todo el
sistema en el sistema de destino. Como .NET Core ya está presente, la aplicación también es portátil
entre instalaciones de .NET Core. La aplicación solo contiene su propio código y dependencias de
terceros que están fuera de las bibliotecas .NET Core. FDD contiene archivos .dll que se pueden iniciar
utilizando la utilidad dotnet desde la línea de comandos. Por ejemplo, dotnet app.dll ejecuta una
aplicación denominada app .
Implementación autocontenida. A diferencia de FDD, una implementación autocontenida (SCD ) no
depende de la presencia de los componentes compartidos en el sistema de destino. Todos los
componentes, incluidas las bibliotecas y el entorno de ejecución de .NET Core, se incluyen con la
aplicación y están aislados de otras aplicaciones .NET Core. Las SCD incluyen un archivo ejecutable
(como app.exe en plataformas de Windows para una aplicación denominada app ), que es una versión
con otro nombre del host de .NET Core específico de la plataforma y un archivo .dll (como app.dll), que
es la aplicación real.
Archivos ejecutables dependiente de la plataforma. Genera un archivo ejecutable que se ejecuta en una
plataforma de destino. De manera parecida a las FDD, los archivos ejecutables dependientes de la
plataforma (FDE ) son específicos de la plataforma y no son independientes. Estas implementaciones
aún dependen de la presencia de una versión compartida de .NET Core en todo el sistema para
ejecutarse. A diferencia de una SCD, la aplicación solo contiene su código y las dependencias de
terceros que están fuera de las bibliotecas .NET Core. Las FDE generan un archivo ejecutable que se
ejecuta en la plataforma de destino.

Implementaciones dependientes de Framework (FDD)


En una implementación dependiente del marco de trabajo, solo se implementa la aplicación y las
dependencias de terceros. La aplicación usará la versión de .NET Core que exista en el sistema de destino. Este
es el modelo de implementación predeterminado para las aplicaciones .NET Core y ASP.NET Core que tienen
como destino .NET Core.
¿Por qué crear una implementación dependiente del marco?
La implementación de FDD tienen varias ventajas:
No es necesario definir por adelantado los sistemas operativos de destino en los que se ejecutará la
aplicación .NET Core. Como .NET Core usa un formato de archivo PE común para archivos ejecutables
y bibliotecas independientemente del sistema operativo, .NET Core puede ejecutar la aplicación con
independencia del sistema operativo subyacente. Para más información sobre el formato de archivo PE,
consulte .NET Assembly File Format (Formato de archivo de ensamblado .NET).
El tamaño de su paquete de implementación es pequeño. Solo tendrá que implementar la aplicación y
sus dependencias, .NET Core propiamente dicho.
A menos que se reemplace, las FDD usarán el entorno de ejecución atendido más reciente instalado en
el sistema de destino. De esta forma, la aplicación puede usar la versión revisada más reciente del
entorno de ejecución de .NET Core.
Varias aplicaciones usan la misma instalación de .NET Core, lo que reduce tanto el espacio en disco y el
uso de memoria en sistemas host.
Hay también algunas desventajas:
Su aplicación solo se puede ejecutar si la versión de .NET Core de destino de la aplicación, o una
versión posterior, ya está instalada en el sistema host.
Es posible que el entorno de tiempo de ejecución y las bibliotecas .NET Core cambien en futuras
versiones sin su conocimiento. En raras ocasiones, esto puede cambiar el comportamiento de la
aplicación.

Implementaciones autocontenidas (SCD)


En una implementación autocontenida, implementa su aplicación y cualquier dependencia de terceros junto
con la versión de .NET Core que ha usado para compilar la aplicación. La creación de una SCD no incluye las
dependencias nativas de .NET Core en diversas plataformas, así que es necesario que estén presentes antes
de ejecutar la aplicación. Para obtener más información sobre el enlace de versiones en un entorno de
ejecución, vea el artículo sobre enlace de versiones de .NET Core.
A partir del SDK de .NET Core 2.1 (versión 2.1.300), .NET Core es compatible con la puesta al día de la
revisión de versiones. Cuando se crea una implementación autocontenida, las herramientas de .NET Core
incluyen automáticamente el último tiempo de ejecución con mantenimiento de la versión de .NET Core a la
que se dirige su aplicación. (El último tiempo de ejecución con mantenimiento incluye revisiones de seguridad
y otras correcciones de errores). El tiempo de ejecución con mantenimiento no tiene que estar presente en el
sistema de compilación; se descarga automáticamente de NuGet.org. Para más información, incluidas las
instrucciones sobre cómo dejar de recibir la puesta al día de la revisión de versiones, vea Puesta al día del
tiempo de ejecución de implementación autocontenida.
Las implementaciones de FDD y SCD usan ejecutables de host independientes, por lo que puede firmar un
host ejecutable de un SCD con su firma de publicador.
¿Por qué realizar una implementación autocontenida?
La implementación de una implementación autocontenida tiene dos ventajas principales:
Tiene el control exclusivo de la versión de .NET Core que se implementa con la aplicación. El
mantenimiento de .NET Core solo puede realizarlo usted.
Puede tener la seguridad de que el sistema de destino puede ejecutar su aplicación de .NET Core, dado
que usted proporciona la versión de .NET Core en la que se ejecuta.
También tiene algunos inconvenientes:
Como .NET Core se incluye en el paquete de implementación, debe seleccionar por adelantado las
plataformas de destino en las que se compilan los paquetes de implementación.
El tamaño de su paquete de implementación es relativamente grande, ya que tendrá que incluir .NET
Core, así como la aplicación y sus dependencias de terceros.
A partir de .NET Core 2.0, puede reducir el tamaño de la implementación en sistemas Linux en 28 MB
aproximadamente con el modo invariable global de .NET Core. Normalmente, .NET Core en Linux se
basa en las bibliotecas ICU para la compatibilidad global. En modo invariable, las bibliotecas no se
incluyen con la implementación y todas las referencias culturales se comportan como la referencia
cultural invariable.
La implementación de numerosas aplicaciones .NET Core autocontenidas en un sistema puede
consumir importantes cantidades de espacio en disco, puesto que cada aplicación duplica archivos de
.NET Core.

Archivos ejecutables dependiente de la plataforma (FDE)


A partir de .NET Core 2.2, puede implementar la aplicación como una FDE, junto con cualquier dependencia
de terceros necesaria. La aplicación usará la versión de .NET Core que está instalada en el sistema de destino.
¿Por qué implementar un archivo ejecutable dependiente de la plataforma?
La implementación de un FDE tiene una serie de ventajas:
El tamaño de su paquete de implementación es pequeño. Solo tendrá que implementar la aplicación y
sus dependencias, .NET Core propiamente dicho.
Varias aplicaciones usan la misma instalación de .NET Core, lo que reduce tanto el espacio en disco y el
uso de memoria en sistemas host.
Para ejecutar la aplicación se puede llamar al archivo ejecutable publicado sin invocar la utilidad
dotnet directamente.

Hay también algunas desventajas:


Su aplicación solo se puede ejecutar si la versión de .NET Core de destino de la aplicación, o una
versión posterior, ya está instalada en el sistema host.
Es posible que el entorno de tiempo de ejecución y las bibliotecas .NET Core cambien en futuras
versiones sin su conocimiento. En raras ocasiones, esto puede cambiar el comportamiento de la
aplicación.
Se debe publicar la aplicación para cada plataforma de destino.

Ejemplos paso a paso


Para ver ejemplos paso a paso de la implementación de aplicaciones .NET Core con herramientas de la CLI,
consulte Deploying .NET Core Apps with CLI Tools (Implementación de aplicaciones de .NET Core con
herramientas de la CLI). Para ver ejemplos paso a paso de la implementación de aplicaciones .NET Core con
herramientas de la CLI, consulte Deploying .NET Core Apps with Visual Studio (Implementación de
aplicaciones de .NET Core con Visual Studio).

Vea también
Implementación de aplicaciones .NET Core con herramientas de la CLI
Implementación de aplicaciones de .NET Core con Visual Studio
Paquetes, metapaquetes y marcos de trabajo
Catálogo de identificadores de entorno de ejecución (RID ) de .NET Core
Publicación de aplicaciones .NET Core con la CLI
20/01/2020 • 16 minutes to read • Edit Online

En este artículo se muestra cómo se puede publicar la aplicación .NET Core desde la línea de comandos. .NET
core proporciona tres maneras de publicar las aplicaciones. La implementación dependiente del marco de trabajo
genera un archivo .dll multiplataforma que usa el runtime de .NET Core instalado localmente. La implementación
dependiente del marco de trabajo genera un archivo ejecutable específico de la plataforma que usa el runtime de
.NET Core instalado localmente. El archivo ejecutable independiente genera un archivo ejecutable específico de la
plataforma e incluye una copia local del runtime de .NET Core.
Para obtener información general sobre estos modos de publicación, vea Implementación de aplicaciones .NET
Core.
¿Busca ayuda rápida sobre el uso de la CLI? En la tabla siguiente se muestran algunos ejemplos de cómo publicar
la aplicación. La plataforma de destino se puede especificar con el parámetro -f <TFM> o si edita el archivo de
proyecto. Para más información, vea Conceptos básicos de publicación.

MODO DE PUBLICACIÓN VERSIÓN DEL SDK COMANDO

Implementación dependiente de marco 2.x dotnet publish -c Release


de trabajo

Archivo ejecutable dependiente de la 2.2 dotnet publish -c Release -r


plataforma <RID> --self-contained false

3.0 dotnet publish -c Release -r


<RID> --self-contained false

3.0* dotnet publish -c Release

Implementación autocontenida 2.1 dotnet publish -c Release -r


<RID> --self-contained true

2.2 dotnet publish -c Release -r


<RID> --self-contained true

3.0 dotnet publish -c Release -r


<RID> --self-contained true

* Si se usa el archivo ejecutable dependiente del marco de la versión 3.0 del SDK, se trata del modo de publicación
predeterminado cuando se ejecuta el comando dotnet publish básico. Esto solo se aplica cuando el proyecto
tiene como destino .NET Core 2.1 o .NET Core 3.0.

Conceptos básicos de publicación


El valor <TargetFramework> del archivo de proyecto especifica la plataforma de destino predeterminada al publicar
la aplicación. Se puede cambiar la plataforma de destino a cualquier moniker de la plataforma de destino (TFM ).
Por ejemplo, si en el proyecto se usa <TargetFramework>netcoreapp2.2</TargetFramework> , se crea un archivo binario
que tiene como destino .NET Core 2.2. El TFM especificado en esta configuración es el destino predeterminado
que usa el comando dotnet publish .
Si quiere tener como destino más de una plataforma, puede establecer el valor <TargetFrameworks> en más de un
valor de TFM separados por punto y coma. Puede publicar una de las plataformas con el comando
dotnet publish -f <TFM> . Por ejemplo, si tiene <TargetFrameworks>netcoreapp2.1;netcoreapp2.2</TargetFrameworks>
y ejecuta dotnet publish -f netcoreapp2.1 , se crea un archivo binario que tiene como destino .NET Core 2.1.
A menos que se establezca otro, el directorio de salida del comando dotnet publish es
./bin/<BUILD-CONFIGURATION>/<TFM>/publish/ . El modo BUILD -CONFIGURATION predeterminado es Depurar a
menos que se cambie con el parámetro -c . Por ejemplo, dotnet publish -c Release -f netcoreapp2.1 publica en
myfolder/bin/Release/netcoreapp2.1/publish/ .

Si usa el SDK 3.0 de .NET Core o versiones posteriores, el modo de publicación predeterminado para las
aplicaciones destinadas a las versiones 2.1, 2.2, 3.0 o una versión posterior de .NET Core es el ejecutable
dependiente del marco.
Si usa el SDK 2.1 de .NET Core, el modo de publicación predeterminado para las aplicaciones destinadas a las
versiones 2.1 y 2.2 de .NET Core es la implementación dependiente del marco.
Dependencias nativas
Si la aplicación tiene dependencias nativas, es posible que no funcione en otro sistema operativo. Por ejemplo, si
en la aplicación se usa la API Windows nativa, no se ejecutará en macOS o Linux. Tendrá que proporcionar código
específico de la plataforma y compilar un archivo ejecutable para cada plataforma.
Tenga en cuenta también que, si una biblioteca a la que se hace referencia tiene una dependencia nativa, es posible
que la aplicación no se ejecute en todas las plataformas. Pero es posible que un paquete NuGet al que se hace
referencia incluya versiones específicas de la plataforma para controlar de forma automática las dependencias
nativas necesarias.
Al distribuir una aplicación con dependencias nativas, es posible que tenga que usar el modificador
dotnet publish -r <RID> para especificar la plataforma de destino para la que se quiere publicar. Para obtener una
lista de identificadores de tiempo de ejecución, vea Catálogo de identificadores de entorno de ejecución (RID ) de
.NET Core.
En las secciones Archivo ejecutable dependiente de la plataforma e Implementación autocontenida se ofrece más
información sobre los archivos binarios específicos de la plataforma.

Aplicación de ejemplo
Puede usar la siguiente aplicación para explorar los comandos de publicación. La aplicación se crea mediante la
ejecución de los comandos siguientes en el terminal:

mkdir apptest1
cd apptest1
dotnet new console
dotnet add package Figgle

Es necesario cambiar el archivo Program.cs o Program.vb que genera la plantilla de consola por lo siguiente:
using System;

namespace apptest1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"));
}
}
}

Module Program
Sub Main(args As String())
Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))
End Sub
End Module

Al ejecutar la aplicación ( dotnet run ), se muestra el resultado siguiente:

_ _ _ _ __ __ _ _ _
| | | | ___| | | ___ \ \ / /__ _ __| | __| | |
| |_| |/ _ \ | |/ _ \ \ \ /\ / / _ \| '__| |/ _` | |
| _ | __/ | | (_) | \ V V / (_) | | | | (_| |_|
|_| |_|\___|_|_|\___( ) \_/\_/ \___/|_| |_|\__,_(_)
|/

Implementación dependiente de marco de trabajo


Para la CLI del SDK de .NET Core 2.x, la implementación dependiente de la plataforma (FDD ) es el modo
predeterminado para el comando dotnet publish básico.
Cuando la aplicación se publica como una FDD, se crea un archivo <PROJECT-NAME>.dll en la carpeta
./bin/<BUILD-CONFIGURATION>/<TFM>/publish/ . Para ejecutar la aplicación, vaya a la carpeta de salida y use el
comando dotnet <PROJECT-NAME>.dll .
La aplicación está configurada para tener como destino una versión específica de .NET Core. Es obligatorio que
ese runtime de .NET Core de destino esté en cualquier equipo donde se ejecute la aplicación. Por ejemplo, si la
aplicación tiene como destino .NET Core 2.2, todos los equipos en los que se ejecute la aplicación deben tener
instalado el runtime de .NET Core 2.2. Como se indica en la sección Conceptos básicos de publicación, se puede
editar el archivo de proyecto para cambiar la plataforma de destino predeterminada o seleccionar más de una
como destino.
Al publicar una FDD se crea una aplicación que realiza la puesta al día automática a la revisión de seguridad de
.NET Core más reciente disponible en el sistema en el que se ejecuta la aplicación. Para más información sobre el
enlace de versión en tiempo de compilación, vea Selección de la versión de .NET Core que se va a usar.

Archivo ejecutable dependiente de la plataforma


Para la CLI del SDK de .NET Core 3.x, el archivo ejecutable dependiente de la plataforma (FDE ) es el modo
predeterminado para el comando dotnet publish básico. No es necesario especificar ningún otro parámetro,
siempre que se quiera establecer como destino el sistema operativo actual.
En este modo, se crea un host ejecutable específico de la plataforma para hospedar la aplicación multiplataforma.
Este modo es similar a FDD, ya que requiere un host en forma del comando dotnet . El nombre de archivo
ejecutable de host varía según la plataforma y es similar a <PROJECT-FILE>.exe . Este archivo ejecutable se puede
ejecutar directamente en lugar de llamar a dotnet <PROJECT-FILE>.dll , que sigue siendo una forma aceptable de
ejecutar la aplicación.
La aplicación está configurada para tener como destino una versión específica de .NET Core. Es obligatorio que
ese runtime de .NET Core de destino esté en cualquier equipo donde se ejecute la aplicación. Por ejemplo, si la
aplicación tiene como destino .NET Core 2.2, todos los equipos en los que se ejecute la aplicación deben tener
instalado el runtime de .NET Core 2.2. Como se indica en la sección Conceptos básicos de publicación, se puede
editar el archivo de proyecto para cambiar la plataforma de destino predeterminada o seleccionar más de una
como destino.
Al publicar un FDE se crea una aplicación que realiza la puesta al día automática a la revisión de seguridad de
.NET Core más reciente disponible en el sistema en el que se ejecuta la aplicación. Para más información sobre el
enlace de versión en tiempo de compilación, vea Selección de la versión de .NET Core que se va a usar.
En el caso de .NET Core 2.2 y versiones anteriores, debe usar los modificadores siguientes con el comando
dotnet publish para publicar un FDE:

-r <RID> Este modificador usa un identificador (RID ) para especificar la plataforma de destino. Para
obtener una lista de identificadores de tiempo de ejecución, vea Catálogo de identificadores de entorno de
ejecución (RID ) de .NET Core.
--self-contained false Este modificador indica al SDK de .NET Core que cree un archivo ejecutable como
un FDE.
Siempre que se usa el modificador -r , la ruta de acceso de la carpeta de salida cambia a:
./bin/<BUILD-CONFIGURATION>/<TFM>/<RID>/publish/

Si usa la aplicación de ejemplo, ejecute dotnet publish -f netcoreapp2.2 -r win10-x64 --self-contained false . Este
comando crea el archivo ejecutable siguiente: ./bin/Debug/netcoreapp2.2/win10-x64/publish/apptest1.exe

NOTE
Puede reducir el tamaño total de la implementación si habilita el modo de globalización invariable. Este modo es útil
para las aplicaciones que no son globales y que pueden usar las convenciones de formato, las de mayúsculas y minúsculas, y
el criterio de ordenación y la comparación de cadenas de la referencia cultural invariable. Para más información sobre el
modo de globalización invariable y cómo habilitarlo, vea Modo de globalización invariable de .NET Core.

Implementación autocontenida
Cuando se publica una implementación autocontenida (SCD ), el SDK de .NET Core crea un archivo ejecutable
específico de la plataforma. La publicación de una SCD incluye todos los archivos de .NET Core necesarios para
ejecutar la aplicación, pero no incluye las dependencias nativas de .NET Core. Estas dependencias deben estar
presentes en el sistema antes de ejecutar la aplicación.
Al publicar una SCD, se crea una aplicación que no se pone al día a la revisión de seguridad de .NET Core más
reciente disponible. Para más información sobre el enlace de versión en tiempo de compilación, vea Selección de
la versión de .NET Core que se va a usar.
Debe usar los modificadores siguientes con el comando dotnet publish para publicar una SCD:
-r <RID> Este modificador usa un identificador (RID ) para especificar la plataforma de destino. Para
obtener una lista de identificadores de tiempo de ejecución, vea Catálogo de identificadores de entorno de
ejecución (RID ) de .NET Core.
--self-contained true Este modificador indica al SDK de .NET Core que cree un archivo ejecutable como
una SCD.

NOTE
Puede reducir el tamaño total de la implementación si habilita el modo de globalización invariable. Este modo es útil
para las aplicaciones que no son globales y que pueden usar las convenciones de formato, las de mayúsculas y minúsculas, y
el criterio de ordenación y la comparación de cadenas de la referencia cultural invariable. Para más información sobre el
modo de globalización invariable y cómo habilitarlo, vea Modo de globalización invariable de .NET Core.

Vea también
Información general sobre la implementación de aplicaciones .NET Core
Catálogo de identificadores de entorno de ejecución (RID ) de .NET Core
Implementación de aplicaciones de .NET Core con
Visual Studio
20/01/2020 • 29 minutes to read • Edit Online

Puede implementar una aplicación de .NET Core como una implementación dependiente de la plataforma, que
incluye los archivos binarios de la aplicación pero depende de la presencia de .NET Core en el sistema de destino,
o como una implementación independiente, que incluye la aplicación y los archivos binarios de .NET Core. Para
obtener información general sobre la implementación de aplicaciones de NET Core, vea Implementación de
aplicaciones .NET Core.
En las secciones siguientes se muestra cómo usar Microsoft Visual Studio para crear los siguientes tipos de
implementaciones:
Implementación dependiente de marco de trabajo
Implementación dependiente de marco de trabajo con dependencias de terceros
Implementación autocontenida
Implementación autocontenida con dependencias de terceros
Para obtener información sobre el uso de Visual Studio para desarrollar aplicaciones de .NET Core, vea
Dependencias y requisitos de .NET Core .

Implementación dependiente de marco de trabajo


La implementación de una implementación dependiente del marco sin dependencias de terceros implica
simplemente la compilación, la prueba y la publicación de la aplicación. Un sencillo ejemplo escrito en C# ilustra el
proceso.
1. Crear el proyecto.
Seleccione Archivo > Nuevo > Proyecto. En el cuadro de diálogo Nuevo proyecto, expanda las
categorías de proyecto del lenguaje (C# o Visual Basic) en el panel de tipos de proyecto instalados, elija
.NET Core y luego seleccione la plantilla Aplicación de consola (.NET Core) en el panel central. Escriba
un nombre de proyecto, como "FDD", en el cuadro de texto Nombre. Seleccione el botón Aceptar.
2. Agregar el código fuente de la aplicación.
Abra el archivo Program.cs o Program.vb en el editor y reemplace el código generado automáticamente
por el siguiente. Pide al usuario que escriba texto y muestra las palabras individuales escritas por el usuario.
Se usa la expresión regular \w+ para separar las palabras en el texto de entrada.
using System;
using System.Text.RegularExpressions;

namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}

private static void ShowWords(String s)


{
String pattern = @"\w+";
var matches = Regex.Matches(s, pattern);
if (matches.Count == 0)
{
Console.WriteLine("\nNo words were identified in your input.");
}
else
{
Console.WriteLine($"\nThere are {matches.Count} words in your string:");
for (int ctr = 0; ctr < matches.Count; ctr++)
{
Console.WriteLine($" #{ctr,2}: '{matches[ctr].Value}' at position
{matches[ctr].Index}");
}
}
}
}
}
Imports System.Text.RegularExpressions

Namespace Applications.ConsoleApps
Public Module ConsoleParser
Public Sub Main()
Console.WriteLine("Enter any text, followed by <Enter>:")
Console.WriteLine()
Dim s = Console.ReadLine()
ShowWords(s)
Console.Write($"{vbCrLf}Press any key to continue... ")
Console.ReadKey()
End Sub

Private Sub ShowWords(s As String)


Dim pattern = "\w+"
Dim matches = Regex.Matches(s, pattern)
Console.WriteLine()
If matches.Count = 0 Then
Console.WriteLine("No words were identified in your input.")
Else
Console.WriteLine($"There are {matches.Count} words in your string:")
For ctr = 0 To matches.Count - 1
Console.WriteLine($" #{ctr,2}: '{matches(ctr).Value}' at position
{matches(ctr).Index}")
Next
End If
Console.WriteLine()
End Sub
End Module
End Namespace

3. Crear una versión de depuración de la aplicación.


Seleccione Compilar > Compilar solución. También puede compilar y ejecutar la versión de depuración
de la aplicación seleccionando Depurar > Iniciar depuración.
4. Implementar la aplicación.
Después de depurar y probar el programa, cree los archivos que se implementarán con la aplicación. Para
publicar desde Visual Studio, siga estos pasos:
a. Cambie la configuración de la solución de Depurar a Versión en la barra de herramientas para
compilar una compilación de versión (en lugar de depuración) de la aplicación.
b. Haga clic con el botón derecho en el proyecto (no en la solución) en el Explorador de soluciones y
seleccione Publicar.
c. En la pestaña Publicar, seleccione Publicar. Visual Studio escribe los archivos que componen la
aplicación en el sistema de archivos local.
d. La pestaña Publicar muestra ahora un solo perfil, FolderProfile. Los valores de configuración del
perfil se muestran en la sección Resumen de la pestaña.
Los archivos resultantes se colocan en un directorio denominado Publish en Windows y publish en
sistemas Unix que está en un subdirectorio del subdirectorio .\bin\release\netcoreapp2.1 del proyecto.
Junto con los archivos de la aplicación, el proceso de publicación emite un archivo de base de datos de programa
(.pdb) que contiene información de depuración sobre la aplicación. El archivo es útil principalmente para depurar
excepciones. Puede decidir no empaquetarlo con los archivos de la aplicación. Pero se debe guardar en caso de
que se quiera depurar la compilación de versión de la aplicación.
Implemente el conjunto completo de archivos de la aplicación del modo que quiera. Por ejemplo, puede
empaquetarlos en un archivo ZIP, usar un simple comando copy o implementarlos con el paquete de instalación
que prefiera. Una vez instalados, los usuarios pueden ejecutar la aplicación mediante el comando dotnet y
proporcionando el nombre de archivo, como dotnet fdd.dll .
Además de los archivos binarios de la aplicación, el instalador también debe empaquetar el instalador de marco
compartido o buscarlo como requisito previo como parte de la instalación de la aplicación. La instalación del
marco compartido requiere acceso raíz o de administrador dado que implica a toda la máquina.

Implementación dependiente de marco de trabajo con dependencias


de terceros
La implementación de una implementación dependiente de la plataforma con una o más dependencias de
terceros requiere que todas las dependencias estén disponibles para el proyecto. Se requieren los pasos
adicionales siguientes antes de poder compilar la aplicación:
1. Use el Administrador de paquetes NuGet para agregar una referencia a un paquete de NuGet para el
proyecto y, si el paquete todavía no está disponible en el sistema, instálelo. Para abrir el administrador de
paquetes, seleccione Herramientas > Administrador de paquetes NuGet > Administrar paquetes
NuGet para la solución.
2. Confirme que las dependencias de terceros (por ejemplo, Newtonsoft.Json ) están instaladas en el sistema y,
si no es así, instálelas. La pestaña Instalado enumera los paquetes de NuGet instalados en el sistema. Si
Newtonsoft.Json no aparece ahí, seleccione la pestaña Examinar y escriba "Newtonsoft.Json" en el cuadro
de búsqueda. Seleccione Newtonsoft.Json y, en el panel derecho, seleccione el proyecto antes de hacer clic
en Instalar.
3. Si Newtonsoft.Json ya está instalado en el sistema, agréguelo al proyecto seleccionando el proyecto en el
panel derecho de la pestaña Administrar paquetes para la solución.
Una implementación dependiente del marco con dependencias de terceros solo es tan portátil como sus
dependencias de terceros. Por ejemplo, si una biblioteca de terceros solo admite macOS, la aplicación no se puede
portar a sistemas Windows. Esto ocurre si la dependencia de terceros propiamente dicha depende del código
nativo. Un buen ejemplo de esto es el servidor Kestrel, que requiere una dependencia nativa de libuv. Cuando se
crea una FDD para una aplicación con esta clase de dependencia de terceros, el resultado publicado contiene una
carpeta para cada identificador en tiempo de ejecución (RID ) que admita la dependencia nativa (y que exista en su
paquete de NuGet).

Implementación independiente sin dependencias de terceros


La implementación de una implementación independiente sin dependencias de terceros implica crear el proyecto,
modificar el archivo csproj y compilar, probar y publicar la aplicación. Un sencillo ejemplo escrito en C# ilustra el
proceso. Empiece por crear, codificar y probar el proyecto, como haría en el caso de una implementación
dependiente del marco de trabajo:
1. Crear el proyecto.
Seleccione Archivo > Nuevo > Proyecto. En el cuadro de diálogo Nuevo proyecto, expanda las
categorías de proyecto del lenguaje (C# o Visual Basic) en el panel de tipos de proyecto instalados, elija
.NET Core y luego seleccione la plantilla Aplicación de consola (.NET Core) en el panel central. Escriba
un nombre de proyecto, como "SCD", en el cuadro de texto Nombre y pulse el botón Aceptar.
2. Agregar el código fuente de la aplicación.
Abra el archivo Program.cs o Program.vb en el editor y reemplace el código generado automáticamente
por el siguiente. Pide al usuario que escriba texto y muestra las palabras individuales escritas por el usuario.
Se usa la expresión regular \w+ para separar las palabras en el texto de entrada.

using System;
using System.Text.RegularExpressions;

namespace Applications.ConsoleApps
{
public class ConsoleParser
{
public static void Main()
{
Console.WriteLine("Enter any text, followed by <Enter>:\n");
String s = Console.ReadLine();
ShowWords(s);
Console.Write("\nPress any key to continue... ");
Console.ReadKey();
}

private static void ShowWords(String s)


{
String pattern = @"\w+";
var matches = Regex.Matches(s, pattern);
if (matches.Count == 0)
{
Console.WriteLine("\nNo words were identified in your input.");
}
else
{
Console.WriteLine($"\nThere are {matches.Count} words in your string:");
for (int ctr = 0; ctr < matches.Count; ctr++)
{
Console.WriteLine($" #{ctr,2}: '{matches[ctr].Value}' at position
{matches[ctr].Index}");
}
}
}
}
}
Imports System.Text.RegularExpressions

Namespace Applications.ConsoleApps
Public Module ConsoleParser
Public Sub Main()
Console.WriteLine("Enter any text, followed by <Enter>:")
Console.WriteLine()
Dim s = Console.ReadLine()
ShowWords(s)
Console.Write($"{vbCrLf}Press any key to continue... ")
Console.ReadKey()
End Sub

Private Sub ShowWords(s As String)


Dim pattern = "\w+"
Dim matches = Regex.Matches(s, pattern)
Console.WriteLine()
If matches.Count = 0 Then
Console.WriteLine("No words were identified in your input.")
Else
Console.WriteLine($"There are {matches.Count} words in your string:")
For ctr = 0 To matches.Count - 1
Console.WriteLine($" #{ctr,2}: '{matches(ctr).Value}' at position
{matches(ctr).Index}")
Next
End If
Console.WriteLine()
End Sub
End Module
End Namespace

3. Determine si quiere usar el modo de globalización invariable.


Especialmente si la aplicación es para Linux, puede reducir el tamaño total de la implementación si
aprovecha las ventajas del modo de globalización invariable. El modo de globalización invariable es útil
para aquellas aplicaciones que no son globales y que pueden usar las convenciones de formato, las
convenciones de mayúsculas y minúsculas y el criterio de ordenación y la comparación de cadenas de la
referencia cultural invariable.
Para habilitar el modo invariable, haga clic con el botón derecho en el proyecto (no en la solución) en el
Explorador de soluciones y seleccione Editar SCD.csproj o Editar SCD.vbproj. Luego agregue las
siguientes líneas resaltadas al archivo:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true" />
</ItemGroup>
</Project>

4. Cree una compilación de depuración de la aplicación.


Seleccione Compilar > Compilar solución. También puede compilar y ejecutar la versión de depuración
de la aplicación seleccionando Depurar > Iniciar depuración. Este paso de depuración permite identificar
problemas con la aplicación cuando se ejecuta en la plataforma de host. Pero, aun así, tiene que probarla en
cada una de las plataformas de destino.
Si ha habilitado el modo de globalización invariable, asegúrese especialmente de probar si la ausencia de
datos dependientes de la referencia cultural es adecuada para la aplicación.
Una vez que haya terminado de depurar, puede publicar la implementación independiente:
Visual Studio 15.6 y anterior
Visual Studio 15.7 y posterior
Después de depurar y probar el programa, cree los archivos que se implementarán con la aplicación para cada
una de las plataformas de destino.
Para publicar la aplicación desde Visual Studio, siga estos pasos:
1. Definir las plataformas de destino de la aplicación.
a. Haga clic con el botón derecho en el proyecto (no en la solución) en el Explorador de soluciones y
seleccione Editar SCD.csproj.
b. Cree una etiqueta <RuntimeIdentifiers> en la sección <PropertyGroup> del archivo csproj que defina
las plataformas a las que se destina la aplicación y especifique el identificador en tiempo de
ejecución (RID ) de cada una. También debe agregar un punto y coma para separar los RID. Para ver
una lista de identificadores de tiempo de ejecución, consulte el catálogo de identificadores de tiempo
de ejecución.
Por ejemplo, el ejemplo siguiente indica que la aplicación se ejecuta en sistemas operativos Windows 10 de
64 bits y OS X versión 10.11 de 64 bits.

<PropertyGroup>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>

El elemento <RuntimeIdentifiers> puede ir en cualquier <PropertyGroup> que tenga en el archivo csproj.


Más adelante en esta sección aparece un ejemplo completo del archivo csproj.
2. Publique la aplicación.
Después de depurar y probar el programa, cree los archivos que se implementarán con la aplicación para
cada una de las plataformas de destino.
Para publicar la aplicación desde Visual Studio, siga estos pasos:
a. Cambie la configuración de la solución de Depurar a Versión en la barra de herramientas para
compilar una compilación de versión (en lugar de depuración) de la aplicación.
b. Haga clic con el botón derecho en el proyecto (no en la solución) en el Explorador de soluciones y
seleccione Publicar.
c. En la pestaña Publicar, seleccione Publicar. Visual Studio escribe los archivos que componen la
aplicación en el sistema de archivos local.
d. La pestaña Publicar muestra ahora un solo perfil, FolderProfile. Los valores de configuración del
perfil se muestran en la sección Resumen de la pestaña. Tiempo de ejecución de destino
identifica qué tiempo de ejecución se ha publicado, y Ubicación de destino identifica dónde se
escriben los archivos de la implementación independiente.
e. De forma predeterminada, Visual Studio escribe todos los archivos publicados en un único
directorio. Para mayor comodidad, es mejor crear perfiles distintos para cada tiempo de ejecución de
destino y colocar los archivos publicados en un directorio específico de la plataforma. Esto implica la
creación de un perfil de publicación independiente para cada plataforma de destino. Por tanto,
vuelva a compilar la aplicación para cada plataforma siguiendo estos pasos:
a. Seleccione Crear nuevo perfil en el cuadro de diálogo Publicar.
b. En el cuadro de diálogo Elegir un destino de publicación, cambie la ubicación Elegir una
carpeta a bin\Release\PublishOutput\win10 -x64. Seleccione Aceptar.
c. Seleccione el nuevo perfil (FolderProfile1) en la lista de perfiles y asegúrese de que el
Tiempo de ejecución de destino es win10-x64 . Si no lo es, seleccione Configuración. En
el cuadro de diálogo Configuración de perfil, cambie Tiempo de ejecución de destino
por win10-x64 y haga clic en Guardar. En caso contrario, haga clic en Cancelar.
d. Seleccione Publicar para publicar la aplicación para las plataformas de 64 bits de Windows
10.
e. Siga los pasos anteriores de nuevo para crear un perfil para la plataforma osx.10.11-x64 . La
Ubicación de destino es bin\Release\PublishOutput\osx.10.11 -x64 y el Tiempo de
ejecución de destino es osx.10.11-x64 . El nombre que Visual Studio asigna a este perfil es
FolderProfile2.
Cada ubicación de destino contiene el conjunto completo de archivos (los archivos de aplicación y todos los
archivos de .NET Core) necesarios para iniciar la aplicación.
Junto con los archivos de la aplicación, el proceso de publicación emite un archivo de base de datos de programa
(.pdb) que contiene información de depuración sobre la aplicación. El archivo es útil principalmente para depurar
excepciones. Puede decidir no empaquetarlo con los archivos de la aplicación. Pero se debe guardar en caso de
que se quiera depurar la compilación de versión de la aplicación.
Implemente los archivos publicados de la forma que quiera. Por ejemplo, puede empaquetarlos en un archivo ZIP,
usar un simple comando copy o implementarlos con el paquete de instalación que prefiera.
A continuación se muestra el archivo csproj completo para este proyecto.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>

Implementación autocontenida con dependencias de terceros


Implementar una implementación independiente con una o varias dependencias de terceros implica agregar las
dependencias. Se requieren los pasos adicionales siguientes antes de poder compilar la aplicación:
1. Use el Administrador de paquetes NuGet para agregar una referencia a un paquete de NuGet para el
proyecto y, si el paquete todavía no está disponible en el sistema, instálelo. Para abrir el administrador de
paquetes, seleccione Herramientas > Administrador de paquetes NuGet > Administrar paquetes
NuGet para la solución.
2. Confirme que las dependencias de terceros (por ejemplo, Newtonsoft.Json ) están instaladas en el sistema y,
si no es así, instálelas. La pestaña Instalado enumera los paquetes de NuGet instalados en el sistema. Si
Newtonsoft.Json no aparece ahí, seleccione la pestaña Examinar y escriba "Newtonsoft.Json" en el cuadro
de búsqueda. Seleccione Newtonsoft.Json y, en el panel derecho, seleccione el proyecto antes de hacer clic
en Instalar.
3. Si Newtonsoft.Json ya está instalado en el sistema, agréguelo al proyecto seleccionando el proyecto en el
panel derecho de la pestaña Administrar paquetes para la solución.
A continuación se muestra el archivo csproj completo de este proyecto:
Visual Studio 15.6 y anterior
Visual Studio 15.7 y posterior

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
</Project>

Al implementar la aplicación, los archivos de aplicación también contienen las dependencias de terceros usadas en
la aplicación. No se requieren las bibliotecas de terceros en el sistema en el que se ejecuta la aplicación.
Solo puede implementar una implementación autocontenida con una biblioteca de terceros en plataformas
compatibles con esa biblioteca. Esto es similar a tener dependencias de terceros con dependencias nativas en la
implementación dependiente de la plataforma, donde las dependencias nativas no existirán en la plataforma de
destino a menos que se hayan instalado allí previamente.

Vea también
Implementación de aplicaciones .NET Core
Catálogo de identificadores de entorno de ejecución (RID ) de .NET Core
Cómo crear un paquete NuGet con herramientas de
la interfaz de la línea de comandos (CLI) de .NET
Core
20/01/2020 • 4 minutes to read • Edit Online

NOTE
A continuación se muestran ejemplos de línea de comandos mediante Unix. El comando dotnet pack , tal como se muestra
aquí, funciona del mismo modo en Windows.

Está previsto que las bibliotecas .NET Standard y .NET Core se distribuyan como paquetes NuGet. De hecho, es así
como se distribuyen y consumen todas las bibliotecas estándar .NET. Esto se hace más fácil con el comando
dotnet pack .

Imagine que acaba de escribir una nueva biblioteca sorprendente que quiere distribuir a través de NuGet. Puede
crear un paquete NuGet con herramientas multiplataforma para hacer exactamente eso. En el ejemplo siguiente,
hay una biblioteca denominada SuperAwesomeLibrary con destino a netstandard1.0 .
Si tiene dependencias transitivas; es decir, un proyecto que depende de otro paquete, asegúrese de restaurar los
paquetes para toda la solución con el comando dotnet restore antes de crear un paquete NuGet. Si no lo hace, el
comando dotnet pack no funcionará correctamente.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

Después de asegurarse de que se restauran los paquetes, puede ir hasta el directorio donde reside una biblioteca:

cd src/SuperAwesomeLibrary

Luego, es solo cuestión de un comando desde la línea de comandos:

dotnet pack

La carpeta /bin/Debug tendrá un aspecto similar al siguiente:

$ ls bin/Debug
netstandard1.0/
SuperAwesomeLibrary.1.0.0.nupkg
SuperAwesomeLibrary.1.0.0.symbols.nupkg

Esto genera un paquete que se puede depurar. Si quiere compilar un paquete NuGet con archivos binarios de
versión comercial, todo lo que tiene que hacer es agregar el modificador --configuration (o -c ) y usar release
como argumento.

dotnet pack --configuration release

La carpeta /bin tendrá ahora una carpeta versión que contiene el paquete NuGet con archivos binarios de versión:

$ ls bin/release
netstandard1.0/
SuperAwesomeLibrary.1.0.0.nupkg
SuperAwesomeLibrary.1.0.0.symbols.nupkg

Y ahora tiene los archivos necesarios para publicar un paquete de NuGet.

dotnet pack No confunda dotnet publish con


Es importante tener en cuenta que en ningún momento participa el comando dotnet publish . El comando
dotnet publish se destina a la implementación de aplicaciones con todas sus dependencias en el mismo conjunto,
no a la generación de un paquete NuGet que se distribuya y consuma a través de NuGet.

Vea también
Inicio rápido: Creación y publicación de un paquete
Puesta al día del runtime de implementación
autocontenida
20/01/2020 • 5 minutes to read • Edit Online

Las implementaciones de aplicaciones autocontenidas de .NET Core incluyen las bibliotecas de .NET Core y el
runtime de .NET Core. A partir del SDK de .NET Core 2.1 (versión 2.1.300), una implementación de aplicación
autocontenida publica el runtime con la revisión superior en el equipo. De forma predeterminada, el comando
dotnet publish para una implementación autocontenida selecciona la versión más reciente instalada como parte
del SDK en el equipo de publicación. Esto permite que la aplicación implementada se ejecute con las revisiones de
seguridad (y otras correcciones) disponibles en el momento de usar el comando publish . La aplicación debe
volver a publicarse para obtener una nueva revisión. Para crear una aplicación autocontenida, se especifica
-r <RID> en el comando dotnet publish o se especifica el identificador de runtime ( RID ) en el archivo de
proyecto (csproj o vbproj) o en la línea de comandos.

Información general sobre la puesta al día de una versión de revisión


restore , build y publish son comandos de dotnet que se pueden ejecutar por separado. La opción de
runtime forma parte de la operación restore , no de publish ni de build . Si se llama a publish , se elegirá la
versión de revisión más reciente. Si se llama a publish con el argumento --no-restore , podría no obtenerse la
versión de revisión deseada porque es posible que un restore anterior no se haya ejecutado con la directiva de
publicación de la nueva aplicación autocontenida. En este caso, se genera un error de compilación con un texto
similar al siguiente:
"El proyecto se restauró usando Microsoft.NETCore.App versión 2.0.0, pero con la configuración actual, la versión
2.0.6 se usará en su lugar. Para resolver este problema, asegúrese de que se usa la misma configuración para la
restauración y para operaciones posteriores tales como compilar o publicar. Normalmente este problema puede
producirse si la propiedad RuntimeIdentifier se establece durante la compilación o publicación, pero no durante la
restauración".

NOTE
restore y build pueden ejecutarse implícitamente como parte de otro comando, como publish . Cuando se ejecutan
implícitamente como parte de otro comando, se les proporciona contexto adicional para que se produzcan los artefactos
correctos. Cuando se usa el comando publish con un runtime (por ejemplo, dotnet publish -r linux-x64 ), la parte
implícita restore restaura los paquetes para el runtime de linux-x64. Si se llama a restore explícitamente, no se
restauran los paquetes de runtime de forma predeterminada, dado que carece del contexto.

Cómo evitar la restauración durante la publicación


Ejecutar restore como parte de la operación publish puede no ser adecuado para su escenario. Para evitar
restore durante publish al crear aplicaciones autocontenidas, haga lo siguiente:
Establezca la propiedad RuntimeIdentifiers en una lista separada por punto y coma de todos los RID que se
van a publicar.
Establezca la propiedad TargetLatestRuntimePatch en true .

Argumento no-restore con opciones de dotnet publish


Si quiere crear aplicaciones autocontenidas y aplicaciones dependientes del marco de trabajo con el mismo
archivo de proyecto, y además quiere utilizar el argumento --no-restore con dotnet publish , elija una de las
opciones siguientes:
1. Preferir el comportamiento dependiente del marco de trabajo. Si la aplicación depende del marco de
trabajo, este es el comportamiento predeterminado. Si la aplicación es autocontenida y puede usar un
runtime local 2.1.0 sin revisiones, establezca TargetLatestRuntimePatch en false en el archivo de proyecto.
2. Preferir el comportamiento autocontenido. Si la aplicación es autocontenida, este es el comportamiento
predeterminado. Si la aplicación depende del marco de trabajo y requiere que esté instalada la revisión
más reciente, establezca TargetLatestRuntimePatch en true en el archivo de proyecto.
3. Para tomar el control explícito del marco de trabajo del runtime, establezca RuntimeFrameworkVersion en la
versión de revisión específica en el archivo de proyecto.
Almacenamiento de paquetes en tiempo de
ejecución
12/01/2020 • 11 minutes to read • Edit Online

A partir de .NET Core 2.0, es posible empaquetar e implementar aplicaciones en un conjunto conocido de
paquetes que existen en el entorno de destino. Las ventajas son implementaciones más rápidas, menor uso de
espacio en disco y un rendimiento de inicio mejorado en algunos casos.
Esta característica se implementa como un almacenamiento de paquetes en tiempo de ejecución, que es un
directorio en disco donde se almacenan los paquetes (normalmente en /usr/local/share/dotnet/store en
macOS/Linux y C:/Program Files/dotnet/store en Windows). En este directorio, existen subdirectorios para las
arquitecturas y las plataformas de destino. El diseño del archivo es similar a la manera en que los activos de
NuGet se colocan en el disco:

\dotnet
\store
\x64
\netcoreapp2.0
\microsoft.applicationinsights
\microsoft.aspnetcore
...
\x86
\netcoreapp2.0
\microsoft.applicationinsights
\microsoft.aspnetcore
...

Un archivo de manifiesto de destino muestra los paquetes en el almacenamiento de paquetes en tiempo de


ejecución. Los desarrolladores pueden dirigirse a este manifiesto cuando publican su aplicación. Normalmente, el
propietario del entorno de producción de destino proporciona el manifiesto de destino.

Preparación de un entorno en tiempo de ejecución


El administrador de un entorno en tiempo de ejecución puede optimizar aplicaciones para obtener
implementaciones más rápidas y un menor uso de espacio en disco creando un almacenamiento de paquetes en
tiempo de ejecución y el manifiesto de destino correspondiente.
El primer paso consiste en crear un manifiesto de almacenamiento de paquetes que muestra los paquetes que
forman el almacenamiento de paquetes en tiempo de ejecución. El formato de archivo es compatible con el
formato de archivo del proyecto (csproj).

<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="<NUGET_PACKAGE>" Version="<VERSION>" />
<!-- Include additional packages here -->
</ItemGroup>
</Project>

Ejemplo
El siguiente manifiesto de almacenamiento de paquetes de ejemplo (packages.csproj) se usa para agregar
Newtonsoft.Json y Moq a un almacenamiento de paquetes en tiempo de ejecución:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Moq" Version="4.7.63" />
</ItemGroup>
</Project>

Aprovisione el almacenamiento de paquetes en tiempo de ejecución ejecutando dotnet store con el manifiesto
de almacenamiento de paquetes, el runtime y el marco:

dotnet store --manifest <PATH_TO_MANIFEST_FILE> --runtime <RUNTIME_IDENTIFIER> --framework <FRAMEWORK>

Ejemplo

dotnet store --manifest packages.csproj --runtime win10-x64 --framework netcoreapp2.0 --framework-version


2.0.0

Puede pasar varias rutas de manifiesto de almacenamiento de paquetes de destino a un único comando
dotnet store repitiendo la opción y la ruta en el comando.

De manera predeterminada, el resultado del comando es un almacenamiento de paquetes en el subdirectorio


.dotnet/store del perfil de usuario. Puede especificar una ubicación diferente con la opción
--output <OUTPUT_DIRECTORY> . El directorio raíz del almacenamiento contiene un archivo artifact.xml de
manifiesto de destino. Este archivo puede estar disponible para su descarga y usarse por los autores de
aplicaciones que quieran dirigirse a este almacenamiento al realizar la publicación.
Ejemplo
El siguiente archivo artifact.xml se genera después de ejecutar el ejemplo anterior. Tenga en cuenta que
Castle.Core es una dependencia de Moq , de manera que se incluye automáticamente y aparece en el archivo de
manifiesto artifacts.xml.

<StoreArtifacts>
<Package Id="Newtonsoft.Json" Version="10.0.3" />
<Package Id="Castle.Core" Version="4.1.0" />
<Package Id="Moq" Version="4.7.63" />
</StoreArtifacts>

Publicación de una aplicación en un manifiesto de destino


Si tiene un archivo de manifiesto de destino en disco, especifique la ruta al archivo al publicar su aplicación con el
comando dotnet publish :

dotnet publish --manifest <PATH_TO_MANIFEST_FILE>

Ejemplo

dotnet publish --manifest manifest.xml

Implemente la aplicación publicada resultante en un entorno que tenga los paquetes descritos en el manifiesto de
destino. Realizar esto incorrectamente produce errores en el inicio de la aplicación.
Especifique varios manifiestos de destino al publicar una aplicación repitiendo la opción y la ruta (por ejemplo,
--manifest manifest1.xml --manifest manifest2.xml ). Cuando realice esto, la aplicación se reduce para la unión de
los paquetes especificados en los archivos de manifiesto de destino que se proporcionan para el comando.

Especificar los manifiestos de destino en el archivo del proyecto


Una alternativa de especificar manifiestos de destino con el comando dotnet publish es especificarlos en el
archivo de proyecto como una lista de rutas separadas por punto y coma en una etiqueta
<TargetManifestFiles> .

<PropertyGroup>
<TargetManifestFiles>manifest1.xml;manifest2.xml</TargetManifestFiles>
</PropertyGroup>

Especifique los manifiestos de destino en el archivo de proyecto solo cuando el entorno de destino de la
aplicación sea muy conocido, como para los proyectos de .NET Core. Este no es el caso de los proyectos de
código abierto. Los usuarios de un proyecto de código abierto normalmente lo implementan en diferentes
entornos de producción. Estos entornos de producción generalmente tienen diferentes conjuntos de paquetes
preinstalados. No puede realizar presuposiciones sobre el manifiesto de destino en dichos entornos, por lo que
debe usar la opción --manifest de dotnet publish .

Almacenamiento implícito de ASP.NET Core


El almacenamiento implícito de ASP.NET Core solo se aplica a ASP.NET Core 2.0. Se recomienda
encarecidamente que las aplicaciones usen ASP.NET Core 2.1 y versiones posteriores, que no usan
almacenamiento implícito. ASP.NET Core 2.1 y versiones posteriores usan el marco de trabajo compartido.
La característica de almacenamiento de paquetes en tiempo de ejecución se usa implícitamente por una
aplicación de ASP.NET Core cuando la aplicación se implementa como una aplicación de implementación
dependiente del marco (FDD ). Los destinos en Microsoft.NET.Sdk.Web incluyen manifiestos que hacen referencia
al almacenamiento de paquetes implícito en el sistema de destino. Además, cualquier aplicación de FDD que
depende del paquete Microsoft.AspNetCore.All tiene como resultado una aplicación publicada que contiene solo
la aplicación y sus activos y no los paquetes que se muestran en el metapaquete Microsoft.AspNetCore.All . Se
presupone que esos paquetes están presentes en el sistema de destino.
El almacenamiento de paquetes en tiempo de ejecución está instalado en el host cuando el SDK de .NET Core
está instalado. Otros instaladores pueden proporcionar el almacenamiento de paquetes en tiempo de ejecución,
incluidas las instalaciones Zip/tarball del SDK de .NET Core, apt-get , Red Hat Yum, la agrupación de hospedaje
de Windows Server para .NET Core y las instalaciones manuales de almacenamiento de paquetes en tiempo de
ejecución.
Al implementar una aplicación de implementación dependiente del marco (FDD ), asegúrese de que el entorno de
destino tiene el SDK de .NET Core instalado. Si la aplicación se implementa en un entorno que no incluye
ASP.NET Core, puede rechazar el almacenamiento implícito especificando
<PublishWithAspNetCoreTargetManifest> en false en el archivo de proyecto como se muestra en el
ejemplo siguiente:

<PropertyGroup>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
NOTE
Para las aplicaciones de implementación independiente (SCD), se presupone que el sistema de destino no contiene
necesariamente los paquetes de manifiesto necesarios. Por lo tanto, <PublishWithAspNetCoreTargetManifest> no
puede establecerse en true para una aplicación de SCD.

Si implementa una aplicación con una dependencia de manifiesto que está presente en la implementación (el
ensamblado está presente en la carpeta bin), el almacenamiento de paquetes en tiempo de ejecución no se usa en
el host de ese ensamblado. El ensamblado de la carpeta bin se usa independientemente de su presencia en el
almacenamiento de paquetes en tiempo de ejecución en el host.
La versión de la dependencia indicada en el manifiesto debe coincidir con la versión de la dependencia en el
almacenamiento de paquetes en tiempo de ejecución. Si no coinciden las versiones entre la dependencia del
manifiesto de destino y la versión que existe en el almacenamiento de paquetes en tiempo de ejecución, y la
aplicación no incluye la versión necesaria del paquete en su implementación, se produce un error en el inicio de
la aplicación. La excepción incluye el nombre del manifiesto de destino que se ha llamado para el ensamblado del
almacenamiento de paquetes en tiempo de ejecución, que le ayuda a solucionar los errores de coincidencia.
Cuando la implementación se reduce en su publicación, solo las versiones específicas de los paquetes de
manifiesto que indique se retienen del resultado publicado. Los paquetes de las versiones indicadas deben estar
presentes en el host para que se inicie la aplicación.

Vea también
dotnet-publish
dotnet-store
Introducción a .NET y Docker
12/01/2020 • 7 minutes to read • Edit Online

.NET Core puede ejecutarse con facilidad en un contenedor de Docker. Los contenedores proporcionan una
manera ligera de aislar la aplicación del resto del sistema host, con tan solo compartir el kernel y usar los
recursos proporcionados a la aplicación. Si no está familiarizado con Docker, se recomienda encarecidamente que
lea la documentación de introducción a Docker.
Para más información sobre cómo instalar Docker, vea la página de descarga de Docker Desktop: Community
Edition.

Conceptos básicos de Docker


Hay algunos conceptos con los que debe estar familiarizado. El cliente Docker tiene un programa de interfaz de la
línea de comandos que se usa para administrar imágenes y contenedores. Como se mencionó anteriormente,
debe dedicar tiempo a leer la documentación de introducción a Docker.
Imágenes
Una imagen es una colección ordenada de los cambios del sistema de archivos que forman la base de un
contenedor. La imagen no tiene ningún estado y es de solo lectura. La mayor parte del tiempo, una imagen se
basa en otra imagen, pero con alguna personalización. Por ejemplo, al crear una imagen para una aplicación, esta
se basaría en una imagen existente que ya contiene .NET Core Runtime.
Dado que los contenedores se crean a partir de imágenes, estas tienen un conjunto de parámetros de ejecución
(por ejemplo, un archivo ejecutable de inicio) que se ejecutan cuando se inicia el contenedor.
Contenedores
Un contenedor es una instancia ejecutable de una imagen. Al crear la imagen, implementa la aplicación y sus
dependencias. Después, se pueden crear instancias de varios contenedores, cada una de ellas aisladas entre sí.
Cada instancia de contenedor tiene su sistema de archivos, memoria e interfaz de red propios.
Registros
Los registros de contenedor son una colección de repositorios de imágenes. Puede basar sus imágenes en una
imagen del registro. Puede crear contenedores directamente a partir de una imagen en un registro. La relación
entre los contenedores, las imágenes y los registros de Docker es un concepto importante a la hora de diseñar y
compilar aplicaciones o microservicios en contenedores. Este enfoque reduce en gran medida el tiempo que
transcurre entre el desarrollo y la implementación.
Docker tiene un registro público hospedado en Docker Hub que puede usar. Las imágenes relacionadas con .NET
Core aparecen en Docker Hub.
El registro de contenedor de Microsoft (MCR ) es el origen oficial de las imágenes de contenedor proporcionadas
por Microsoft. El MCR se basa en Azure CDN para proporcionar imágenes replicadas globalmente. Sin embargo,
el MCR no tiene un sitio web público, y la manera principal de obtener información sobre las imágenes de
contenedor proporcionadas por Microsoft es en las páginas de Microsoft Docker Hub.
Dockerfile
Un archivo Dockerfile es aquel que define un conjunto de instrucciones que crea una imagen. Cada instrucción
de Dockerfile crea una capa en la imagen. Por lo general, cuando se recompila la imagen, solo se recompilan las
capas que han cambiado. El Dockerfile se puede distribuir a otros usuarios, para que puedan recrear una imagen
de la misma manera que usted. Aunque esto le permite distribuir las instrucciones sobre cómo crear la imagen, el
método principal para distribuir la imagen consiste en publicarla en un registro.

Imágenes de .NET Core


Las imágenes oficiales de Docker en .NET Core se publican en el registro de contenedor de Microsoft (MCR ) y se
pueden encontrar en el repositorio de Docker Hub para Microsoft .NET Core. Cada repositorio contiene
imágenes para diferentes combinaciones de .NET (SDK o Runtime) y del sistema operativo que puede usar.
Microsoft ofrece imágenes que se adaptan a escenarios específicos. Por ejemplo, el repositorio de ASP.NET Core
proporciona imágenes que se compilan para ejecutar aplicaciones de ASP.NET Core en producción.

Servicios de Azure
Varios servicios de Azure admiten contenedores. Cree una imagen de Docker para la aplicación e impleméntela
en alguno de los siguientes servicios:
Azure Kubernetes Service (AKS )
Escale y organice contenedores de Linux mediante Kubernetes.
Azure App Service
Implemente aplicaciones web o API con contenedores de Linux en un entorno PaaS.
Azure Container Instances
Hospede el contenedor en la nube sin ningún servicio de administración de nivel superior.
Azure Batch
Ejecute trabajos de proceso repetitivos mediante contenedores.
Azure Service Fabric
Migre las aplicaciones de .NET mediante lift-and-shift y modernícelas a microservicios mediante
contenedores de Windows Server.
Azure Container Registry
Almacene y administre imágenes de contenedor en todos los tipos de implementaciones de Azure.

Pasos siguientes
Obtenga información sobre cómo incluir una aplicación de .NET Core en contenedores.
Obtenga información sobre cómo incluir una aplicación ASP.NET Core en contenedores.
Consulte el tutorial de ASP.NET Core para los microservicios.
Obtenga información sobre las herramientas de contenedor en Visual Studio
Tutorial: Incluir una aplicación de .NET Core en un
contenedor
20/01/2020 • 20 minutes to read • Edit Online

En este tutorial se ofrece información sobre cómo compilar una imagen de Docker que contiene una aplicación
de .NET Core. La imagen puede usarse para crear contenedores para un entorno de desarrollo local, una nube
privada o una nube pública.
Aprenderá a hacer lo siguiente:
Crear y publicar una aplicación .NET Core sencilla
Crear y configurar un archivo Dockerfile para .NET Core
Creación de una imagen de Docker
Crear y ejecutar un contenedor de Docker
Aprenderá sobre las tareas de compilación e implementación de un contenedor de Docker para una aplicación
.NET Core. La plataforma Docker usa el motor de Docker para compilar y empaquetar rápidamente aplicaciones
como imágenes de Docker. Estas imágenes se escriben en el formato Dockerfile para implementarse y ejecutarse
en un contenedor superpuesto.

TIP
Si está trabajando con una aplicación de ASP.NET Core, consulte el tutorial Obtenga información sobre cómo incluir una
aplicación ASP.NET Core en contenedores.

Requisitos previos
Instale estos requisitos previos:
SDK de .NET Core 3.1
Si tiene instalado .NET Core, use el comando dotnet --info para determinar el SDK que está usando.
Docker Community Edition
Una carpeta de trabajo temporal para Dockerfile y una aplicación .NET Core de ejemplo. En este tutorial,
el nombre docker-working se usa como la carpeta de trabajo.

Creación de una aplicación .NET Core


Necesita una aplicación .NET Core que el contenedor de Docker ejecutará. Abra el terminal, cree una carpeta de
trabajo si todavía no lo ha hecho y entre en ella. En la carpeta de trabajo, ejecute el comando siguiente para crear
un proyecto en un subdirectorio llamado app:

dotnet new console -o app -n myapp

El árbol de carpetas tendrá un aspecto similar al siguiente:


docker-working

└───app
│ myapp.csproj
│ Program.cs

└───obj
myapp.csproj.nuget.cache
myapp.csproj.nuget.dgspec.json
myapp.csproj.nuget.g.props
myapp.csproj.nuget.g.targets
project.assets.json

Con el comando dotnet new se crea una carpeta denominada app y se genera una aplicación "Hola mundo".
Entre en la carpeta app y ejecute el comando dotnet run . Verá la salida siguiente:

> dotnet run


Hello World!

La plantilla predeterminada crea una aplicación que imprime en el terminal y luego se cierra. En este tutorial, se
usará una aplicación que se repite en bucle de manera indefinida. Abra el archivo Program.cs en un editor de
texto. Actualmente debe ser similar al código siguiente:

using System;

namespace myapp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Reemplace el archivo por el código siguiente que cuenta números cada segundo:

using System;

namespace myapp
{
class Program
{
static void Main(string[] args)
{
var counter = 0;
var max = args.Length != 0 ? Convert.ToInt32(args[0]) : -1;
while (max == -1 || counter < max)
{
counter++;
Console.WriteLine($"Counter: {counter}");
System.Threading.Tasks.Task.Delay(1000).Wait();
}
}
}
}

Guarde el archivo y vuelva a probar el programa con dotnet run . Recuerde que esta aplicación se ejecuta de
manera indefinida. Use el comando de cancelación CTRL+C para detenerla. Verá la salida siguiente:
> dotnet run
Counter: 1
Counter: 2
Counter: 3
Counter: 4
^C

Si pasa un número en la línea de comandos a la aplicación, solo se contará hasta esa cantidad y se cerrará.
Inténtelo con dotnet run -- 5 para contar hasta cinco.

NOTE
Cualquier parámetro posterior a -- no se pasa al comando dotnet run y, en su lugar, se pasa a su aplicación.

Publicación de una aplicación .NET Core


Antes de agregar la aplicación .NET Core a la imagen de Docker, publíquela. Quiere asegurarse de que el
contenedor ejecuta la versión publicada de la aplicación al iniciarse.
Desde la carpeta de trabajo, entre en la carpeta app con el código fuente de ejemplo y ejecute el comando
siguiente:

dotnet publish -c Release

Con este comando se compila la aplicación en la carpeta publish. La ruta de acceso a la carpeta publish desde la
carpeta de trabajo debería ser .\app\bin\Release\netcoreapp3.1\publish\ .
En la carpeta app, obtenga un listado de los directorios de la carpeta publish para comprobar que se creó el
archivo myapp.dll.

> dir bin\Release\netcoreapp3.1\publish

Directory: C:\docker-working\app\bin\Release\netcoreapp3.1\publish

01/09/2020 11:41 AM <DIR> .


01/09/2020 11:41 AM <DIR> ..
01/09/2020 11:41 AM 407 myapp.deps.json
01/09/2020 12:15 PM 4,608 myapp.dll
01/09/2020 12:15 PM 169,984 myapp.exe
01/09/2020 12:15 PM 736 myapp.pdb
01/09/2020 11:41 AM 154 myapp.runtimeconfig.json

Si usa Linux o macOS, use el comando ls para obtener una lista de directorios y comprobar que se ha creado
el archivo dmyapp.dll.

me@DESKTOP:/docker-working/app$ ls bin/Release/netcoreapp3.1/publish
myapp.deps.json myapp.dll myapp.pdb myapp.runtimeconfig.json

Creación del archivo Dockerfile


El archivo Dockerfile lo usa el comando docker build para crear una imagen de contenedor. Este archivo es un
archivo de texto denominado Dockerfile que no tiene ninguna extensión.
En el terminal, suba un directorio a la carpeta de trabajo creada al principio. Cree un archivo denominado
Dockerfile en la carpeta de trabajo y ábralo en un editor de texto. En función del tipo de aplicación que vaya a
incluir en un contenedor, elija el runtime de ASP.NET Core o el de .NET Core. En duda, elija el runtime de
ASP.NET Core, que incluye el de .NET Core. En este tutorial se usará la imagen del runtime de ASP.NET Core,
pero la aplicación creada en las secciones anteriores es una aplicación de .NET Core.
Runtime de ASP.NET Core

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1

Tiempo de ejecución de .NET Core

FROM mcr.microsoft.com/dotnet/core/runtime:3.1

El comando FROM indica a Docker que extraiga la imagen etiquetada 3.1 del repositorio especificado. Asegúrese
de extraer el runtime que coincida con el que el SDK tiene como destino. Por ejemplo, la aplicación creada en la
sección anterior usaba el SDK de .NET Core 3.1, y la imagen base a la que se hace referencia en el documento
Dockerfile se etiqueta con 3.1.
Guarde el archivo Dockerfile. La estructura de directorios de la carpeta de trabajo debería tener el siguiente
aspecto. Algunos de los archivos de carpetas y archivos inferiores se han cortado para ahorrar espacio en este
artículo:

docker-working
│ Dockerfile

└───app
│ myapp.csproj
│ Program.cs

├───bin
│ └───Release
│ └───netcoreapp3.1
│ └───publish
│ myapp.deps.json
│ myapp.exe
│ myapp.dll
│ myapp.pdb
│ myapp.runtimeconfig.json

└───obj

Desde un terminal, ejecute el comando siguiente:

docker build -t myimage -f Dockerfile .

Docker procesará cada línea en el archivo Dockerfile. . del comando docker build indica a Docker que use la
carpeta actual para encontrar un archivo Dockerfile. Este comando crea la imagen y un repositorio local
denominado myimage que apunta a esa imagen. Una vez que finalice este comando, ejecute docker images
para ver una lista de las imágenes instaladas:

> docker images


REPOSITORY TAG IMAGE ID CREATED SIZE
myimage latest 38db0eb8f648 4 weeks ago 346MB
mcr.microsoft.com/dotnet/core/aspnet 3.1 38db0eb8f648 4 weeks ago 346MB
Observe que ambas imágenes comparten el mismo valor IMAGE ID. El valor es el mismo entre ambas
imágenes porque el único comando en Dockerfile era basar la imagen nueva en una imagen existente.
Agreguemos dos comandos a Dockerfile. Cada comando crear una capa de imagen con el comando final que
representa la imagen a la que apuntará el repositorio myimage.

COPY app/bin/Release/netcoreapp3.1/publish/ app/

ENTRYPOINT ["dotnet", "app/myapp.dll"]

El comando COPY indica a Docker que copie la carpeta especificada en el equipo a una carpeta del contenedor.
En este ejemplo, la carpeta publish se copia a una carpeta denominada app del contenedor.
El comando siguiente, ENTRYPOINT , indica a Docker que configure el contenedor para que se ejecute como
ejecutable. Cuando el contenedor se inicia, se ejecuta el comando ENTRYPOINT . Cuando este comando finaliza, el
contenedor se detiene automáticamente.
Desde el terminal, ejecute docker build -t myimage -f Dockerfile . y, cuando el comando finalice, ejecute
docker images .

> docker build -t myimage -f Dockerfile .


Sending build context to Docker daemon 1.624MB
Step 1/3 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
---> 38db0eb8f648
Step 2/3 : COPY app/bin/Release/netcoreapp3.1/publish/ app/
---> 37873673e468
Step 3/3 : ENTRYPOINT ["dotnet", "app/myapp.dll"]
---> Running in d8deb7b3aa9e
Removing intermediate container d8deb7b3aa9e
---> 0d602ca35c1d
Successfully built 0d602ca35c1d
Successfully tagged myimage:latest

> docker images


REPOSITORY TAG IMAGE ID CREATED SIZE
myimage latest 0d602ca35c1d 4 seconds ago 346MB
mcr.microsoft.com/dotnet/core/aspnet 3.1 38db0eb8f648 4 weeks ago 346MB

Cada comando de Dockerfile generó una capa y creó un valor IMAGE ID. El valor IMAGE ID final (el suyo será
distinto) es ddcc6646461b y, a continuación, usted creará un contenedor basado en esta imagen.

Crear un contenedor
Ahora que tiene una imagen que contiene la aplicación, puede crear un contenedor. Hay dos formas de crear un
contenedor. En primer lugar, cree un contenedor que esté detenido.

> docker create myimage


ceda87b219a4e55e9ad5d833ee1a7ea4da21b5ea7ce5a7d08f3051152e784944

El comando docker create anterior creará un contenedor basado en la imagen myimage. La salida de ese
comando muestra el valor CONTAINER ID (el suyo será distinto) del contenedor creado. Para ver una lista de
todos los contenedores, use el comando docker ps -a :
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
ceda87b219a4 myimage "dotnet app/myapp.dll" 4 seconds ago Created
gallant_lehmann

Administración del contenedor


Cada contenedor tiene asignado un nombre aleatorio que puede usar para hacer referencia a la instancia de
contenedor. Por ejemplo, el contenedor que se creó automáticamente eligió el nombre gallant_lehmann (el
suyo será distinto) y ese nombre se puede usar para iniciar el contenedor. Puede reemplazar el nombre
automático por uno específico si usa el parámetro docker create --name .
En el ejemplo siguiente se usa el comando docker start para iniciar el contenedor y luego se usa el comando
docker ps para mostrar solo los contenedores que están en ejecución:

> docker start gallant_lehmann


gallant_lehmann

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
ceda87b219a4 myimage "dotnet app/myapp.dll" 7 minutes ago Up 8 seconds
gallant_lehmann

De manera similar, el comando docker stop detendrá el contenedor. En el ejemplo siguiente se usa el comando
docker stop para detener el contenedor y luego se usa el comando docker ps para mostrar que no hay ningún
contenedor en ejecución:

> docker stop gallant_lehmann


gallant_lehmann

> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Conectarse a un contenedor
Una vez que se ejecuta un contenedor, puede conectarse a él para ver la salida. Use los comandos docker start
y docker attach para iniciar el contenedor y echar un vistazo al flujo de salida. En este ejemplo, el comando
Ctrl+C se usa para desasociarse del contenedor en ejecución. Esta pulsación de teclas podría realmente finalizar
el proceso en el contenedor, lo que detendrá el contenedor. El parámetro --sig-proxy=false garantiza que CTRL
+ C no detendrá el proceso en el contenedor.

Después de desasociarse del contenedor, reasócielo para comprobar que sigue en ejecución.
> docker start gallant_lehmann
gallant_lehmann

> docker attach --sig-proxy=false gallant_lehmann


Counter: 7
Counter: 8
Counter: 9
^C

> docker attach --sig-proxy=false gallant_lehmann


Counter: 17
Counter: 18
Counter: 19
^C

Eliminación de un contenedor
Para el propósito de este artículo, no queremos contenedores que solo existan y no hagan nada. Elimine el
contenedor que creó anteriormente. Si el contenedor está en ejecución, deténgalo.

> docker stop gallant_lehmann

En el ejemplo siguiente se muestran todos los contenedores. Luego, usa el comando docker rm para eliminar el
contenedor y después vuelve a comprobar si hay algún contenedor en ejecución.

> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ceda87b219a4 myimage "dotnet app/myapp.dll" 19 minutes ago Exited
gallant_lehmann

> docker rm gallant_lehmann


gallant_lehmann

> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Ejecución única
Docker proporciona el comando docker run para crear y ejecutar el contenedor como comando único. Este
comando elimina la necesidad de ejecutar docker create y luego docker start . También puede establecer este
comando en que elimine automáticamente el contenedor cuando este se detenga. Por ejemplo, use
docker run -it --rm para hacer dos cosas: primero, use automáticamente el terminal actual para conectarse al
contenedor y cuando el contenedor finalice, quítelo:

> docker run -it --rm myimage


Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
^C

Con docker run -it , el comando CTRL + C detendrá el proceso que está en ejecución en el contenedor, lo que,
a su vez, detendrá el contenedor. Como se proporcionó el parámetro --rm , el contenedor se elimina
automáticamente cuando se detiene el proceso. Compruebe que no existe:
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Cambio de ENTRYPOINT
El comando docker run también permite modificar el comando ENTRYPOINT desde el archivo Dockerfile y
ejecute algún otro elemento, pero solo para ese contenedor. Por ejemplo, use el comando siguiente para ejecutar
bash o cmd.exe . Edite el comando según sea necesario.

Windows
En este ejemplo, ENTRYPOINT cambia a cmd.exe . Se presiona CTRL+C para finalizar el proceso y detener el
contenedor.

> docker run -it --rm --entrypoint "cmd.exe" myimage

Microsoft Windows [Version 10.0.17763.379]


(c) 2018 Microsoft Corporation. All rights reserved.

C:\>dir
Volume in drive C has no label.
Volume Serial Number is 3005-1E84

Directory of C:\

04/09/2019 08:46 AM <DIR> app


03/07/2019 10:25 AM 5,510 License.txt
04/02/2019 01:35 PM <DIR> Program Files
04/09/2019 01:06 PM <DIR> Users
04/02/2019 01:35 PM <DIR> Windows
1 File(s) 5,510 bytes
4 Dir(s) 21,246,517,248 bytes free

C:\>^C

Linux
En este ejemplo, ENTRYPOINT cambia a bash . Se ejecuta el comando quit , lo que finaliza el proceso y detiene el
contenedor.

root@user:~# docker run -it --rm --entrypoint "bash" myimage


root@8515e897c893:/# ls app
myapp.deps.json myapp.dll myapp.pdb myapp.runtimeconfig.json
root@8515e897c893:/# exit
exit

Comandos esenciales
Docker tiene muchos comandos distintos que abarcan las acciones que quiere hacer con el contenedor y las
imágenes. Estos comandos de Docker son esenciales para la administración de los contenedores:
docker build
docker run
docker ps
docker stop
docker rm
docker rmi
docker image
Limpiar los recursos
Durante este tutorial, creó contenedores e imágenes. Elimine estos recursos si quiere hacerlo. Use los comandos
siguientes para
1. Mostrar todos los contenedores

> docker ps -a

2. Detener los contenedores que están en ejecución CONTAINER_NAME representa el nombre que se asignó
automáticamente al contenedor.

> docker stop CONTAINER_NAME

3. Eliminar el contenedor

> docker rm CONTAINER_NAME

A continuación, elimine las imágenes que ya no quiere tener en la máquina. Elimine la imagen que creó el
archivo Dockerfile y luego elimine la imagen de .NET Core en que se basó el archivo Dockerfile. Puede usar el
valor IMAGE ID o la cadena con formato REPOSITORY:TAG.

docker rmi myimage:latest


docker rmi mcr.microsoft.com/dotnet/core/aspnet:3.1

Use el comando docker images para ver una lista de las imágenes instaladas.

NOTE
Los archivos de imagen pueden ser grandes. Por lo general, quitaría los contenedores temporales que creó al probar y
desarrollar la aplicación. Habitualmente, estas imágenes base se conservan con el runtime instalado si se planea crear otras
imágenes basadas en ese runtime.

Pasos siguientes
Obtenga información sobre cómo incluir una aplicación ASP.NET Core en contenedores.
Consulte el tutorial de ASP.NET Core para los microservicios.
Revise los servicios de Azure que admiten contenedores.
Lea sobre los comandos de Dockerfile.
Explorar las herramientas de contenedor para Visual Studio
¿Qué herramientas de diagnóstico están disponibles
en .NET Core?
08/01/2020 • 3 minutes to read • Edit Online

El comportamiento del software no siempre es el esperado, pero .NET Core tiene herramientas y API que lo
ayudarán a diagnosticar estos problemas de manera rápida y eficaz.
Este artículo lo ayuda a encontrar las distintas herramientas que necesita.

Depuradores administrados
Los depuradores administrados le permiten interactuar con el programa. Pausar, ejecutar de manera incremental,
examinar y reanudar le proporcionan información sobre el comportamiento del código. Un depurador es la
primera opción para diagnosticar problemas funcionales que se pueden reproducir de manera fácil.

Registro y seguimiento
El registro y seguimiento son técnicas relacionadas. Hacen referencia a la instrumentación del código para crear
archivos de registro. Los archivos registran los detalles de lo que hace un programa. Estos detalles se pueden usar
para diagnosticar los problemas más complejos. Cuando se combinan con marcas de tiempo, estas técnicas
también son valiosas para investigaciones de rendimiento.

Pruebas unitarias
Las pruebas unitarias son un componente clave de la integración continua y la implementación de software de alta
calidad. Las pruebas unitarias están diseñadas para brindarle una advertencia temprana cuando se daña algo.

Herramientas globales de diagnóstico de dotnet de .NET Core


dotnet-counters
dotnet-counters es una herramienta diseñada para la investigación del rendimiento y la supervisión del estado de
primer nivel. Permite observar los valores del contador de rendimiento que se publican a través de la API
EventCounter. Por ejemplo, puede supervisar rápidamente elementos como el uso de la CPU o la tasa de
excepciones que se generan en su aplicación .NET Core.
dotnet-dump
La herramienta dotnet-dump permite recopilar y analizar los volcados de Windows y Linux sin necesidad de un
depurador nativo.
dotnet-trace
.NET Core incluye lo que se denomina EventPipe , a través del cual se exponen los datos de diagnóstico. La
herramienta dotnet-trace permite consumir datos interesantes sobre la generación de perfiles a partir de su
aplicación, lo cual puede resultar útil para analizar la causa principal de que una aplicación se ejecute con lentitud.

Tutoriales de diagnóstico de .NET Core


Depuración de una fuga de memoria
Tutorial: Depuración de una fuga de memoria le guía a través de la búsqueda de una fuga de memoria. La
herramienta dotnet-counters se usa para confirmar la fuga, y la herramienta dotnet-dump, para diagnosticarla.
Depuradores administrados de .Net Core
12/01/2020 • 2 minutes to read • Edit Online

Los depuradores permiten a los programas pausarse o ejecutarse paso a paso. Cuando se pausa, se puede ver el
estado actual del proceso. Al recorrer las secciones clave, se entiende mejor el código y el motivo por el que
genera determinado resultado.
Microsoft proporciona depuradores para código administrado en Visual Studio y Visual Studio Code.

Depurador administrado de Visual Studio


Visual Studio es un entorno de desarrollo integrado con el depurador más completo disponible. Visual Studio es
una opción excelente para los desarrolladores que trabajan en Windows.
Tutorial: Depuración de una aplicación .NET Core en Windows con Visual Studio
Aunque Visual Studio es una aplicación de Windows, se puede usar para depurar aplicaciones de Linux y macOS
de forma remota.
Depuración de una aplicación .NET Core en Linux/OSX con Visual Studio
La depuración de aplicaciones ASP.NET Core requiere instrucciones ligeramente distintas.
Depuración de aplicaciones ASP.NET Core en Visual Studio

Depurador administrado de Visual Studio Code


Visual Studio Code es un editor de código ligero y multiplataforma. Usa la misma implementación de depurador
de .NET Core que Visual Studio, pero con una interfaz de usuario simplificada.
Tutorial: Depuración de una aplicación .NET Core con Visual Studio
Debugging in Visual Studio Code (Depuración en Visual Studio Code)
Registro y seguimiento de .NET Core
20/01/2020 • 7 minutes to read • Edit Online

El registro y el seguimiento son en realidad dos nombres para la misma técnica. Esta sencilla técnica se ha usado
desde el inicio de la era de la informática. Simplemente implica instrumentar una aplicación para escribir la salida
que se va a consumir más adelante.

Motivos para usar el registro y seguimiento


Esta técnica sencilla es sorprendentemente eficaz. Se puede usar en situaciones en las que se produzca un error en
un depurador:
Las incidencias que se producen durante largos períodos de tiempo pueden ser difíciles de depurar con un
depurador tradicional. Los registros permiten una revisión detallada de evaluación que abarca períodos largos
de tiempo. En cambio, los depuradores están restringidos a análisis en tiempo real.
Las aplicaciones multiproceso y las aplicaciones distribuidas a menudo son difíciles de depurar. Adjuntar un
depurador tiende a modificar los comportamientos. Los registros detallados se pueden analizar, según sea
necesario, para comprender sistemas complejos.
Las incidencias en las aplicaciones distribuidas pueden surgir de una interacción compleja entre muchos
componentes y puede que no sea razonable conectar un depurador en todas las partes del sistema.
Muchos servicios no deben estar detenidos. Al adjuntar un depurador a menudo se producen errores de
tiempo de expiración.
Las incidencias no siempre están previstas. El registro y seguimiento están diseñados para una baja sobrecarga,
de modo que los programas siempre pueden grabarse en caso de que se produzca una incidencia.

API de .NET Core


API de estilo de impresión
Cada una de las clases System.Console, System.Diagnostics.Trace y System.Diagnostics.Debug proporcionan API
de estilo de impresión parecidas para el registro.
La elección de la API de estilo de impresión que se va a usar depende de usted. Las diferencias clave son:
System.Console
Siempre está habilitada y siempre escribe en la consola.
Resulta útil para la información que es posible que el cliente necesite ver en la versión.
Dado que es el enfoque más sencillo, a menudo se usa para la depuración temporal ad hoc. Este código
de depuración a veces no se registra nunca en el control de código fuente.
System.Diagnostics.Trace
Solo se habilita cuando se define TRACE .
Escribe en el elemento Listeners adjuntado, de forma predeterminada, DefaultTraceListener.
Use esta API cuando cree registros que se vayan a habilitar en la mayoría de compilaciones.
System.Diagnostics.Debug
Solo se habilita cuando se define DEBUG .
Escribe en un depurador adjuntado.
En *nix , escribe en stderr si se establece COMPlus_DebugWriteToStdErr .
Use esta API cuando cree registros que se vayan a habilitar solo en las compilaciones de depuración.
Eventos de registro
Las siguientes API están más orientadas a eventos. En lugar de registrar cadenas sencillas, registran objetos de
evento.
System.Diagnostics.Tracing.EventSource
EventSource es la API de seguimiento de .NET Core de raíz principal.
Disponible en todas las versiones .NET Standard.
Solo permite el seguimiento de objetos serializables.
Escribe en los clientes de escucha de evento adjuntados.
.NET Core proporciona clientes de escucha para:
EventPipe de .NET Core en todas las plataformas
Seguimiento de eventos para Windows (ETW )
Marco de seguimiento de LTTng para Linux
System.Diagnostics.DiagnosticSource
Se incluye en .NET Core y como un paquete NuGet para .NET Framework.
Permite el seguimiento en curso de objetos no serializables.
Incluye un puente para permitir que los campos seleccionados de objetos registrados se escriban en un
elemento EventSource.
System.Diagnostics.Activity
Proporciona una manera definitiva de identificar los mensajes de registro resultantes de una actividad o
transacción específica. Este objeto se puede utilizar para correlacionar los registros entre distintos
servicios.
System.Diagnostics.EventLog
Solo Windows.
Escribe mensajes en el registro de eventos de Windows.
Los administradores del sistema esperan que aparezcan mensajes de error grave de aplicación en el
registro de eventos de Windows.

Plataformas de registro y de ILogger


Es posible que las API de bajo nivel no sean la opción adecuada para sus necesidades de registro. Puede que
quiera considerar la posibilidad de usar una plataforma de registro.
La interfaz de ILogger se ha utilizado para crear una interfaz de registro común en la que se pueden insertar los
registradores mediante la inserción de dependencias.
Por ejemplo, para que pueda elegir la mejor opción para la aplicación, ASP.NET ofrece compatibilidad con una
selección de marcos integrados y de terceros:
Proveedores de registro integrados de ASP.NET
Proveedores de registro de terceros de ASP.NET

Referencias relacionadas de registro


Cómo: Compilación condicional con Trace y Debug
Cómo: agregar instrucciones de seguimiento al código de aplicación
El registro de ASP.NET proporciona información general sobre las técnicas de registro que admite.
La interpolación de cadenas de C# puede simplificar la escritura de código de registro.
La propiedad Exception.Message es útil para las excepciones de registro.
La clase System.Diagnostics.StackTrace puede ser útil para proporcionar información de pila en los
registros.

Consideraciones sobre el rendimiento


El formato de cadena puede tomar un tiempo de procesamiento de la CPU considerable.
En las aplicaciones críticas de rendimiento, se recomienda lo siguiente:
Evitar muchos registros cuando no haya nadie escuchando. Evitar la construcción de mensajes de registro
costosos comprobando en primer lugar si el registro está habilitado.
Registrar únicamente lo que sea útil.
Aplazar el formato sofisticado a la fase de análisis.
dotnet-counters
20/01/2020 • 3 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 3.0 y versiones posteriores

Instalación de dotnet-counters
Para instalar la versión de lanzamiento más reciente del paquete NuGet de dotnet-counters , use el comando
dotnet tool install:

dotnet tool install --global dotnet-counters

Sinopsis
dotnet-counters [-h|--help] [--version] <command>

Descripción
dotnet-counters es una herramienta de supervisión de rendimiento diseñada para la investigación del
rendimiento y la supervisión del estado de primer nivel ad hoc. Puede observar los valores del contador de
rendimiento que se publican a través de la API EventCounter. Por ejemplo, se pueden supervisar rápidamente
cosas como el uso de la CPU o la velocidad de las excepciones que se producen en la aplicación .NET Core para
ver si hay algo sospechoso antes de profundizar en una investigación de rendimiento más seria mediante
PerfView o dotnet-trace .

Opciones
--version

Muestra la versión de la utilidad dotnet-counters.


-h|--help

Muestra la ayuda de la línea de comandos.

Comandos
COMANDO

dotnet-counters list

dotnet-counters monitor

dotnet-counters list
Muestra una lista de nombres y descripciones de contador, agrupada por proveedor.
Sinopsis
dotnet-counters list [-h|--help]

Ejemplo

> dotnet-counters list

Showing well-known counters only. Specific processes may support additional counters.
System.Runtime
cpu-usage Amount of time the process has utilized the CPU (ms)
working-set Amount of working set used by the process (MB)
gc-heap-size Total heap size reported by the GC (MB)
gen-0-gc-count Number of Gen 0 GCs / sec
gen-1-gc-count Number of Gen 1 GCs / sec
gen-2-gc-count Number of Gen 2 GCs / sec
exception-count Number of Exceptions / sec

dotnet-counters monitor
Muestra la actualización periódica de los valores de los contadores seleccionados.
Sinopsis

dotnet-counters monitor [-h|--help] [-p|--process-id] [--refreshInterval] [counter_list]

Opciones
-p|--process-id <PID>

Id. del proceso que se va a supervisar.


--refresh-interval <SECONDS>

Número de segundos de retraso entre la actualización de los contadores mostrados.


counter_list <COUNTERS>

Una lista de contadores separados por espacios. Los contadores pueden ser
provider_name[:counter_name] especificados. Si provider_name se usa sin un elemento counter_name
calificado, se mostrarán todos los contadores. Para descubrir los nombres del proveedor y del contador,
use el comando dotnet-counters list.
Ejemplos
Supervisión de todos los contadores de System.Runtime con un intervalo de actualización de 3 segundos:

> dotnet-counters monitor --process-id 1902 --refresh-interval 3 System.Runtime

Press p to pause, r to resume, q to quit.


System.Runtime:
CPU Usage (%) 24
Working Set (MB) 1982
GC Heap Size (MB) 811
Gen 0 GC / second 20
Gen 1 GC / second 4
Gen 2 GC / second 1
Number of Exceptions / sec 4

Supervisión de únicamente el uso de la CPU y el tamaño del montón de GC de System.Runtime :


> dotnet-counters monitor --process-id 1902 System.Runtime[cpu-usage,gc-heap-size]

Press p to pause, r to resume, q to quit.


System.Runtime:
CPU Usage (%) 24
GC Heap Size (MB) 811

Supervisión de los valores EventCounter del elemento EventSource definido por el usuario. Para obtener
más información, consulte Tutorial: Cómo medir el rendimiento de eventos muy frecuentes con
EventCounters.

> dotnet-counters monitor --process-id 1902 Samples-EventCounterDemos-Minimal

Press p to pause, r to resume, q to quit.


request 100
Utilidad de recopilación y análisis de volcado (
dotnet-dump )
20/01/2020 • 9 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 3.0.x y versiones posteriores

NOTE
dotnet-dump no se admite en macOS.

Instalación de dotnet-dump
Para instalar la versión de lanzamiento más reciente del paquete NuGet de dotnet-dump , use el comando dotnet
tool install:

dotnet tool install -g dotnet-dump

Sinopsis
dotnet-dump [-h|--help] [--version] <command>

Descripción
La herramienta global dotnet-dump es una forma de recopilar y analizar los volcados de Windows y Linux sin
necesidad de un depurador nativo implicado, como lldb en Linux. Esta herramienta es importante en
plataformas como Alpine Linux, donde no está disponible una versión de lldb totalmente operativa. La
herramienta dotnet-dump permite ejecutar comandos SOS para analizar bloqueos y el recolector de elementos
no utilizados (GC ), pero no es un depurador nativo, por lo que no se admiten elementos como la visualización de
marcos de pila nativos.

Opciones
--version

Muestra la versión de la utilidad dotnet-counters.


-h|--help

Muestra la ayuda de la línea de comandos.

Comandos
COMANDO

dotnet-dump collect
COMANDO

dotnet-dump analyze

dotnet-dump collect
Captura un volcado de un proceso.
Sinopsis

dotnet-dump collect [-h|--help] [-p|--process-id] [--type] [-o|--output] [--diag]

Opciones
-h|--help

Muestra la ayuda de la línea de comandos.


-p|--process-id <PID>

Especifica el número de id. de proceso del que se va a recopilar un volcado de memoria.


--type <Heap|Mini>

Especifica el tipo de volcado, que determina los tipos de información que se recopilan del proceso. Hay
dos tipos:
Heap : un volcado grande y relativamente completo que contiene listas de módulos, listas de
subprocesos, todas las pilas, información de excepción, información de control y toda la memoria
excepto las imágenes asignadas.
Mini : un volcado pequeño que contiene listas de módulos, listas de subprocesos, información de
excepción y todas las pilas.
Si no se especifica, el valor predeterminado es Heap .
-o|--output <output_dump_path>

La ruta de acceso completa y el nombre de archivo donde se debe escribir el volcado recopilado.
Si no se especifica:
El valor predeterminado es .\dump_AAAAMMDD_HHMMSS.dmp en Windows.
El valor predeterminado es ./core_AAAAMMDD_HHMMSS en Linux.
AAAAMMDD es año/mes/día y HHMMSS es hora/minuto/segundo.
--diag

Habilita el registro de diagnóstico de la recopilación de volcado.

dotnet-dump analyze
Inicia un shell interactivo para explorar un volcado. El shell acepta varios comandos SOS.
Sinopsis

dotnet-dump analyze <dump_path> [-h|--help] [-c|--command]

Argumentos
<dump_path>

Especifica la ruta de acceso al archivo de volcado que se va a analizar.


Opciones
-c|--command <debug_command>

Especifica el comando que se va a ejecutar en el shell al inicio.


Análisis de comandos SOS
COMANDO FUNCIÓN

soshelp Muestra todos los comandos disponibles.

soshelp|help <command> Muestra el comando especificado.

exit|quit Sale del modo interactivo.

clrstack <arguments> Proporciona un seguimiento de pila del código administrado


únicamente.

clrthreads <arguments> Enumera los subprocesos administrados que se ejecutan.

dumpasync <arguments> Muestra información sobre las máquinas de estado


asincrónicas en el montón de recolección de elementos no
utilizados.

dumpassembly <arguments> Muestra detalles sobre un ensamblado.

dumpclass <arguments> Muestra información sobre una estructura de clase EE en la


dirección especificada.

dumpdelegate <arguments> Muestra información sobre un delegado.

dumpdomain <arguments> Muestra información sobre todos los dominios de aplicación


y sobre todos los ensamblados en los dominios.

dumpheap <arguments> Muestra información sobre el montón de recolección de


elementos no utilizados y estadísticas de recolección de los
objetos.

dumpil <arguments> Muestra el Lenguaje intermedio de Microsoft (MSIL) que está


asociado a un método administrado.

dumplog <arguments> Escribe el contenido de un registro de esfuerzo existente en


memoria en el archivo especificado.

dumpmd <arguments> Muestra información sobre una estructura MethodDesc en la


dirección especificada.

dumpmodule <arguments> Muestra información sobre una estructura de módulo EE en


la dirección especificada.

dumpmt <arguments> Muestra información sobre una tabla de métodos en la


dirección especificada.
COMANDO FUNCIÓN

dumpobj <arguments> Muestra información sobre un objeto en la dirección


especificada.

dso|dumpstackobjects <arguments> Muestra todos los objetos administrados que se han


encontrado dentro de los límites de la pila actual.

eeheap <arguments> Muestra información sobre la memoria de proceso que usan


las estructuras de datos internas del runtime.

finalizequeue <arguments> Muestra todos los objetos registrados para su finalización.

gcroot <arguments> Muestra información acerca de las referencias (o raíces) a un


objeto en la dirección especificada.

gcwhere <arguments> Muestra la ubicación en el montón de recolección de


elementos no utilizados del argumento que se ha pasado.

ip2md <arguments> Muestra la estructura MethodDesc en la dirección


especificada en código JIT.

histclear <arguments> Libera los recursos usados por la familia de comandos


hist* .

histinit <arguments> Inicializa las estructuras SOS del registro de esfuerzo


guardado en el código que se está depurando.

histobj <arguments> Muestra las reubicaciones de registro de esfuerzo de la


recolección de elementos no utilizados relacionadas con
<arguments> .

histobjfind <arguments> Muestra todas las entradas de registro que hacen referencia
a un objeto en la dirección especificada.

histroot <arguments> Muestra información relacionada con las promociones y las


reubicaciones de la raíz especificada.

lm|modules Muestra los módulos nativos del proceso.

name2ee <arguments> Muestra la estructura MethodTable y la estructura EEClass


para <argument> .

pe|printexception <arguments> Muestra cualquier objeto que se deriva de la clase Exception


en la dirección <argument> .

setsymbolserver <arguments> Habilita la compatibilidad con el servidor de símbolos.

syncblk <arguments> Muestra la información del contenedor de SyncBlock.

threads|setthread <threadid> Establece o muestra el identificador del subproceso actual


para los comandos SOS.

Uso de dotnet-dump
El primer paso es recopilar un volcado. Este paso se puede omitir si ya se ha generado un volcado principal. El
sistema operativo o la característica de generación de volcado integrada del runtime de .NET Core pueden crear
volcados principales.

$ dotnet-dump collect --process-id 1902


Writing minidump to file ./core_20190226_135837
Written 98983936 bytes (24166 pages) to core file
Complete

Ahora analice el volcado principal con el comando analyze :

$ dotnet-dump analyze ./core_20190226_135850


Loading core dump: ./core_20190226_135850
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get
detailed help on a command.
Type 'quit' or 'exit' to exit the session.
>

Esta acción abre una sesión interactiva que acepta comandos como los siguientes:

> clrstack
OS Thread Id: 0x573d (0)
Child SP IP Call Site
00007FFD28B42C58 00007fb22c1a8ed9 [HelperMethodFrame_PROTECTOBJ: 00007ffd28b42c58]
System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67 System.Reflection.RuntimeMethodInfo.Invoke(System.Object,
System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
[/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.Program.Foo4(System.String)
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.Program.Foo2(Int32, System.String)
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.Program.Foo1(Int32, System.String)
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.Program.Main(System.String[])
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]
00007FFD28B43210 00007fb22aa9cedf [GCFrame: 00007ffd28b43210]
00007FFD28B43610 00007fb22aa9cedf [GCFrame: 00007ffd28b43610]

Para ver una excepción no controlada que ha terminado la aplicación:


> pe -lines
Exception object: 00007fb18c038590
Exception type: System.Reflection.TargetInvocationException
Message: Exception has been thrown by the target of an invocation.
InnerException: System.Exception, Use !PrintException 00007FB18C038368 to see more.
StackTrace (generated):
SP IP Function
00007FFD28B42DD0 0000000000000000
System.Private.CoreLib.dll!System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[],
System.Signature, Boolean, Boolean)
00007FFD28B42DD0 00007FB1B1334F67
System.Private.CoreLib.dll!System.Reflection.RuntimeMethodInfo.Invoke(System.Object,
System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[],
System.Globalization.CultureInfo)+0xa7 [/root/coreclr/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs
@ 472]
00007FFD28B42E20 00007FB1B18D33ED SymbolTestApp.dll!SymbolTestApp.Program.Foo4(System.String)+0x15d
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 54]
00007FFD28B42ED0 00007FB1B18D2FC4 SymbolTestApp.dll!SymbolTestApp.Program.Foo2(Int32, System.String)+0x34
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 29]
00007FFD28B42F00 00007FB1B18D2F5A SymbolTestApp.dll!SymbolTestApp.Program.Foo1(Int32, System.String)+0x3a
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 24]
00007FFD28B42F30 00007FB1B18D168E SymbolTestApp.dll!SymbolTestApp.Program.Main(System.String[])+0x6e
[/home/mikem/builds/SymbolTestApp/SymbolTestApp/SymbolTestApp.cs @ 19]

StackTraceString: <none>
HResult: 80131604

Instrucciones especiales para Docker


Si ejecuta en Docker, la recopilación de volcados requiere capacidades de SYS_PTRACE ( --cap-add=SYS_PTRACE o
--privileged ).

En Microsoft SDK de .NET Core imágenes de Docker de SDK de Linux, algunos comandos dotnet-dump pueden
producir la siguiente excepción:

Excepción no controlada: System.DllNotFoundException: No se puede cargar la biblioteca compartida


"libdl.so" o una de su excepción de dependencias.

Para solucionar este problema, instale el paquete "libc6-dev".


Utilidad de análisis de rendimiento dotnet-trace
20/01/2020 • 7 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 3.0.x y versiones posteriores

Instalación de dotnet-trace
Instale el paquete NuGet dotnet-trace con el comando dotnet tool install:

dotnet tool install --global dotnet-trace

Sinopsis
dotnet-trace [-h, --help] [--version] <command>

Descripción
La herramienta dotnet-trace :
Es una herramienta de .NET Core para varias plataformas.
Habilita la recolección de seguimientos de .NET Core de un proceso en ejecución sin un generador de perfiles
nativo.
Se basa en la tecnología EventPipe multiplataforma del entorno de ejecución de .NET Core.
Ofrece la misma experiencia en Windows, Linux o macOS.

Opciones
--version

Muestra la versión de la utilidad dotnet-counters.


-h|--help

Muestra la ayuda de la línea de comandos.

Comandos
COMANDO

dotnet-trace collect

dotnet-trace convert

dotnet-trace ps

dotnet-trace list-profiles
dotnet-trace collect
Recopila un seguimiento de diagnóstico de un proceso en ejecución.
Sinopsis

dotnet-trace collect [-h|--help] [-p|--process-id] [--buffersize <size>] [-o|--output]


[--providers] [--profile <profile-name>] [--format]

Opciones
-p|--process-id <PID>

Proceso del que se va a recopilar el seguimiento.


--buffersize <size>

Establece el tamaño del búfer circular en memoria, en megabytes. Valor predeterminado de 256 MB.
-o|--output <trace-file-path>

Ruta de acceso de salida para los datos de seguimiento recopilados. Si no se especifica, el valor
predeterminado es trace.nettrace .
--providers <list-of-comma-separated-providers>

Lista separada por comas de proveedores de EventPipe que se van a habilitar. Estos proveedores
complementan a los proveedores implícitos en --profile <profile-name> . Si hay alguna incoherencia para
un proveedor determinado, esta configuración tiene prioridad sobre la configuración implícita del perfil.
Esta lista de proveedores tiene el siguiente formato:
Provider[,Provider]
Provider tiene el formato: KnownProviderName[:Flags[:Level][:KeyValueArgs]] .
KeyValueArgs tiene el formato: [key1=value1][;key2=value2] .

--profile <profile-name>

Un conjunto con nombre predefinido de configuraciones de proveedor que permite especificar


sucintamente los escenarios de seguimiento comunes.
--format {NetTrace|Speedscope}

Establece el formato de salida para la conversión del archivo de seguimiento. De manera predeterminada,
es NetTrace .

dotnet-trace convert
Convierte los seguimientos de nettrace en formatos alternativos para usarlos con herramientas de análisis de
seguimiento alternativas.
Sinopsis

dotnet-trace convert [<input-filename>] [-h|--help] [--format] [-o|--output]

Argumentos
<input-filename>

Archivo de seguimiento de entrada que se va a convertir. El valor predeterminado es trace.nettrace.


Opciones
--format <NetTrace|Speedscope>

Establece el formato de salida para la conversión del archivo de seguimiento.


-o|--output <output-filename>

Nombre de archivo de salida. Se agregará la extensión del formato de destino.

dotnet-trace ps
Muestra los procesos de dotnet a los cuales se puede adjuntar.
Sinopsis

dotnet-trace ps [-h|--help]

dotnet-trace list-profiles
Muestra los perfiles de seguimiento pregenerados con una descripción de los proveedores y filtros que hay en
cada perfil.
Sinopsis

dotnet-trace list-profiles [-h|--help]

Recopilación de un seguimiento con dotnet-trace


Para recopilar seguimientos mediante dotnet-trace :
Averigüe el identificador de proceso (PID ) de la aplicación .NET Core del que se van a recopilar
seguimientos.
En Windows, puede usar el administrador de tareas o el comando tasklist , por ejemplo.
En Linux, por ejemplo, el comando ps .
dotnet-trace ps
Ejecute el siguiente comando:

dotnet-trace collect --process-id <PID>

El comando anterior genera una salida similar a la siguiente:

Press <Enter> to exit...


Connecting to process: <Full-Path-To-Process-Being-Profiled>/dotnet.exe
Collecting to file: <Full-Path-To-Trace>/trace.nettrace
Session Id: <SessionId>
Recording trace 721.025 (KB)

Detenga la recolección presionando la tecla <Enter> . dotnet-trace finalizará el registro de eventos en el


archivo trace.nettrace.

Vista del seguimiento capturado de dotnet-trace


En Windows, los archivos .nettrace se pueden ver en PerfView para el análisis: En el caso de los seguimientos
recopilados en otras plataformas, el archivo de seguimiento se puede trasladar a una máquina Windows para
verlo en PerfView.
En Linux, el seguimiento se puede ver cambiando el formato de salida de dotnet-trace a speedscope . Puede
cambiar el formato de archivo de salida mediante la opción -f|--format : -f speedscope hará que dotnet-trace
genere un archivo speedscope . Puede elegir entre nettrace (opción predeterminada) y speedscope . Loa archivos
Speedscope se pueden abrir en https://www.speedscope.app.

NOTE
El tiempo de ejecución de .NET Core genera seguimientos en el formato nettrace . Los seguimientos se convierten a
formato speedscope (si se especifica) una vez completado el seguimiento. Dado que algunas conversiones pueden provocar
la pérdida de datos, el archivo nettrace original se conserva junto al archivo convertido.

Uso de dotnet-trace para recopilar valores de contador a lo largo del


tiempo
dotnet-trace puede:
Use EventCounter para la supervisión de estado básica en entornos con distinción de rendimiento. Por
ejemplo, en producción.
Recopile seguimientos para que no sea necesario visualizarlos en tiempo real.
Por ejemplo, para recopilar valores de contador de rendimiento en tiempo de ejecución, puede usar el comando
siguiente:

dotnet-trace collect --process-id <PID> --providers System.Runtime:0:1:EventCounterIntervalSec=1

El comando anterior indica a los contadores en tiempo de ejecución que se deben notificar una vez por segundo
para la supervisión ligera del estado. Reemplazar EventCounterIntervalSec=1 por un valor mayor (por ejemplo,
60) permite recopilar un seguimiento más pequeño con menos granularidad en los datos de contador.
El comando siguiente reduce la sobrecarga y el tamaño de seguimiento más que el anterior:

dotnet-trace collect --process-id <PID> --providers System.Runtime:0:1:EventCounterIntervalSec=1,Microsoft-


Windows-DotNETRuntime:0:1,Microsoft-DotNETCore-SampleProfiler:0:1

El comando anterior deshabilita los eventos en tiempo de ejecución y el generador de perfiles de pila
administrado.

Proveedores .NET
El runtime de .NET Core admite los siguientes proveedores .NET. .NET Core usa las mismas palabras clave para
habilitar los seguimientos de Event Tracing for Windows (ETW) y EventPipe .

NOMBRE DEL PROVEEDOR INFORMACIÓN

Microsoft-Windows-DotNETRuntime El proveedor de runtime


Palabras clave de runtime de CLR

Microsoft-Windows-DotNETRuntimeRundown El proveedor de informe detallado


Palabras clave de informe detallado de CLR
NOMBRE DEL PROVEEDOR INFORMACIÓN

Microsoft-DotNETCore-SampleProfiler Habilita el generador de perfiles de ejemplo.


Tutorial: Depuración de una fuga de memoria en
.NET Core
20/01/2020 • 9 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 3.0.x y versiones posteriores


En este tutorial se muestran las herramientas para analizar una fuga de memoria de .NET Core.
En este tutorial se usa una aplicación de ejemplo, diseñada para perder memoria de manera intencionada. El
ejemplo se proporciona como ejercicio. Asimismo, puede analizar una aplicación que pierda memoria
involuntariamente.
En este tutorial va a:
Examinar el uso de memoria administrada con dotnet-counters.
Generar un archivo de volcado de memoria.
Analizar el uso de memoria mediante el archivo de volcado de memoria.

Requisitos previos
En el tutorial se usa:
SDK de .NET Core 3.0 o una versión posterior.
dotnet-trace para mostrar procesos.
dotnet-counters para comprobar el uso de memoria administrada.
dotnet-dump para recopilar y analizar un archivo de volcado de memoria.
Una aplicación de destino de depuración de ejemplo que se va a diagnosticar.
En el tutorial se da por supuesto que el ejemplo y las herramientas están instalados y listos para usarse.

Análisis del uso de memoria administrada


Antes de empezar a recopilar datos de diagnóstico que nos ayuden a establecer la causa principal de este
escenario, debe asegurarse de que realmente está viendo una fuga de memoria (crecimiento de memoria). Puede
usar la herramienta dotnet-counters para confirmar eso.
Abra una ventana de consola y vaya al directorio donde descargó y descomprimió el destino de depuración de
ejemplo. Ejecute el destino:

dotnet run

En una consola independiente, busque el identificador del proceso mediante la herramienta dotnet-trace:

dotnet-trace ps

La salida debe ser similar a:

4807 DiagnosticScena
/home/user/git/samples/core/diagnostics/DiagnosticScenarios/bin/Debug/netcoreapp3.0/DiagnosticScenarios
Ahora, compruebe el uso de memoria administrada con la herramienta dotnet-counters. --refresh-interval
especifica el número de segundos entre las actualizaciones:

dotnet-counters monitor --refresh-interval 1 -p 4807

La salida en directo debe ser similar a:

Press p to pause, r to resume, q to quit.


Status: Running

[System.Runtime]
# of Assemblies Loaded 118
% Time in GC (since last GC) 0
Allocation Rate (Bytes / sec) 37,896
CPU Usage (%) 0
Exceptions / sec 0
GC Heap Size (MB) 4
Gen 0 GC / sec 0
Gen 0 Size (B) 0
Gen 1 GC / sec 0
Gen 1 Size (B) 0
Gen 2 GC / sec 0
Gen 2 Size (B) 0
LOH Size (B) 0
Monitor Lock Contention Count / sec 0
Number of Active Timers 1
ThreadPool Completed Work Items / sec 10
ThreadPool Queue Length 0
ThreadPool Threads Count 1
Working Set (MB) 83

Establecimiento del foco en esta línea:

GC Heap Size (MB) 4

Puede ver que la memoria de montón administrado es de 4 MB justo después del inicio.
Ahora, visite la dirección URL http://localhost:5000/api/diagscenario/memleak/20000 .
Observe que el uso de memoria ha aumentado a 30 MB.

GC Heap Size (MB) 30

Al observar el uso de memoria, puede indicar con seguridad el aumento o la fuga de memoria. El siguiente paso
consiste en recopilar los datos adecuados para el análisis de memoria.
Generación de un volcado de memoria
Al analizar posibles fugas de memoria, debe tener acceso al montón de memoria de la aplicación. A continuación,
puede analizar el contenido de la memoria. Al observarse las relaciones entre los objetos, se crean teorías de por
qué no se libera la memoria. Un origen de datos de diagnóstico habitual es un volcado de memoria en Windows o
el volcado de memoria principal equivalente en Linux. Para generar un volcado de memoria de una aplicación .NET
Core, puede usar la herramienta dotnet-dump).
Con el destino de depuración de ejemplo iniciado anteriormente, ejecute el siguiente comando para generar un
volcado de memoria principal de Linux:
dotnet-dump collect -p 4807

El resultado es un volcado de memoria principal ubicado en la misma carpeta.

Writing minidump with heap to ./core_20190430_185145


Complete

Reinicio del proceso con errores


Una vez recopilado el volcado de memoria, debe tener suficiente información para diagnosticar el proceso con
errores. Si el proceso con errores se ejecuta en un servidor de producción, ahora es el momento ideal para la
corrección a corto plazo reiniciando el proceso.
En este tutorial, ya ha terminado con el destino de depuración de ejemplo y puede cerrarlo. Vaya al terminal que
inició el servidor y presione Control-C .
Análisis del volcado de memoria principal
Ahora que ha generado un volcado de memoria principal, use la herramienta dotnet-dump) para analizar el
volcado de memoria:

dotnet-dump analyze core_20190430_185145

Donde core_20190430_185145 es el nombre del volcado de memoria principal que desea analizar.

NOTE
Si ve un error que indica que no se encuentra libdl.so, es posible que tenga que instalar el paquete libc6-dev. Para más
información, consulte Requisitos previos para .NET Core en Linux.

Se le mostrará un mensaje en el que puede escribir comandos SOS. Normalmente, lo primero que desea ver es el
estado general del montón administrado:

> dumpheap -stat

Statistics:
MT Count TotalSize Class Name
...
00007f6c1eeefba8 576 59904 System.Reflection.RuntimeMethodInfo
00007f6c1dc021c8 1749 95696 System.SByte[]
00000000008c9db0 3847 116080 Free
00007f6c1e784a18 175 128640 System.Char[]
00007f6c1dbf5510 217 133504 System.Object[]
00007f6c1dc014c0 467 416464 System.Byte[]
00007f6c21625038 6 4063376 testwebapi.Controllers.Customer[]
00007f6c20a67498 200000 4800000 testwebapi.Controllers.Customer
00007f6c1dc00f90 206770 19494060 System.String
Total 428516 objects

Aquí puede ver que la mayoría de los objetos son objetos String o Customer .
Puede volver a usar el comando dumpheap con la tabla del método (MT) para obtener una lista de todas las
instancias de String :
> dumpheap -mt 00007faddaa50f90

Address MT Size
...
00007f6ad09421f8 00007faddaa50f90 94
...
00007f6ad0965b20 00007f6c1dc00f90 80
00007f6ad0965c10 00007f6c1dc00f90 80
00007f6ad0965d00 00007f6c1dc00f90 80
00007f6ad0965df0 00007f6c1dc00f90 80
00007f6ad0965ee0 00007f6c1dc00f90 80

Statistics:
MT Count TotalSize Class Name
00007f6c1dc00f90 206770 19494060 System.String
Total 206770 objects

Ahora puede usar el comando gcroot en una instancia de System.String para ver cómo y por qué se considera
raíz el objeto. Tenga paciencia, ya que este comando tarda varios minutos con un montón de 30 MB:

> gcroot -all 00007f6ad09421f8

Thread 3f68:
00007F6795BB58A0 00007F6C1D7D0745 System.Diagnostics.Tracing.CounterGroup.PollForValues()
[/_/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/CounterGroup.cs @ 260]
rbx: (interior)
-> 00007F6BDFFFF038 System.Object[]
-> 00007F69D0033570 testwebapi.Controllers.Processor
-> 00007F69D0033588 testwebapi.Controllers.CustomerCache
-> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer,
DiagnosticScenarios]]
-> 00007F6C000148A0 testwebapi.Controllers.Customer[]
-> 00007F6AD0942258 testwebapi.Controllers.Customer
-> 00007F6AD09421F8 System.String

HandleTable:
00007F6C98BB15F8 (pinned handle)
-> 00007F6BDFFFF038 System.Object[]
-> 00007F69D0033570 testwebapi.Controllers.Processor
-> 00007F69D0033588 testwebapi.Controllers.CustomerCache
-> 00007F69D00335A0 System.Collections.Generic.List`1[[testwebapi.Controllers.Customer,
DiagnosticScenarios]]
-> 00007F6C000148A0 testwebapi.Controllers.Customer[]
-> 00007F6AD0942258 testwebapi.Controllers.Customer
-> 00007F6AD09421F8 System.String

Found 2 roots.

Puede ver que el objeto Customer mantiene directamente String y un objeto CustomerCache lo hace
indirectamente.
Puede seguir volcando objetos para ver que la mayoría de los objetos String siguen un patrón similar. En este
punto, la investigación proporcionó suficiente información para identificar la causa principal en su código.
Este procedimiento general le permite identificar el origen de las principales fugas de memoria.

Limpiar los recursos


En este tutorial, inició un servidor web de ejemplo. Este servidor debería haberse apagado como se explica en la
sección Reinicio del proceso con errores.
También puede eliminar el archivo de volcado de memoria que se creó.
Pasos siguientes
Enhorabuena por completar este tutorial.
Todavía estamos publicando más tutoriales de diagnóstico. Puede leer las versiones de borrador en el repositorio
dotnet/diagnostics.
En este tutorial se han tratado los aspectos básicos de las herramientas de diagnóstico de .NET clave. Para el uso
avanzado, consulte la siguiente documentación de referencia:
dotnet-trace para mostrar procesos.
dotnet-counters para comprobar el uso de memoria administrada.
dotnet-dump para recopilar y analizar un archivo de volcado de memoria.
Pruebas unitaria en .NET Core y .NET Standard
11/01/2020 • 6 minutes to read • Edit Online

.NET Core facilita la creación de pruebas unitarias. En este artículo se presentan las pruebas unitarias y se indican
las diferencias con otros tipos de pruebas. En los recursos vinculados al final de la página se muestra cómo
agregar un proyecto de prueba a una solución. Una vez que haya configurado el proyecto de prueba, podrá
ejecutar las pruebas unitarias con la línea de comandos o con Visual Studio.
Si está realizando pruebas con un proyecto de ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.
.NET Core 2.0 y versiones posteriores admiten .NET Standard 2.0, cuyas bibliotecas usaremos para mostrar las
pruebas unitarias.
Puede usar plantillas de proyecto de prueba unitaria integradas de .NET Core 2.0 y versiones posteriores para C#,
F# y Visual Basic como punto inicial para su proyecto personal.

¿Qué son las pruebas unitarias?


Automatizar pruebas es un método magnífico para asegurarse de que una aplicación de software hace lo que sus
autores pretenden. Hay varios tipos de pruebas para aplicaciones de software. Estas incluyen pruebas de
integración, pruebas web y pruebas de carga, entre otras. Con las pruebas unitarias se comprueban
componentes y métodos de software individuales. Estas solo deberían probar código que pueda controlar el
desarrollador. No se deberían usar para comprobar problemas con la infraestructura. Estos problemas incluyen los
relacionados con bases de datos, el sistema de archivos o recursos de red.
Además, es recomendable que tenga en cuenta que hay procedimientos recomendados para la escritura de
pruebas. Por ejemplo, Test Driven Development (TTD ) es un proceso en el que una prueba unitaria se escribe
antes que el código que debería comprobar. Este método se puede comparar a la creación del esquema de un libro
antes de escribirlo. Está diseñado para ayudar a los desarrolladores a escribir código más simple, legible y eficaz.

NOTE
El equipo de ASP.NET sigue estas convenciones para ayudar a los desarrolladores a asignar buenos nombres a clases de
prueba y métodos.

No intente incluir dependencias en la infraestructura al escribir pruebas unitarias. Estas vuelven las pruebas lentas
y frágiles, por lo que deberían reservarse para pruebas de integración. Puede evitar esas dependencias en su
aplicación si sigue el Explicit Dependencies Principle (Principio de dependencias explícitas) y usando la Inserción
de dependencias. También puede mantener las pruebas unitarias en un proyecto separado de las pruebas de
integración. Esto asegurará que el proyecto de pruebas unitarias no tiene referencias a paquetes de infraestructura
ni dependencias de estos.

Pasos siguientes
Puede encontrar más información sobre las pruebas unitarias en proyectos de .NET Core:
Los proyectos de pruebas unitarias de .NET Core son compatibles con los siguientes lenguajes:
C#
F#
Visual Basic
También puede elegir entre las siguientes opciones:
xUnit
NUnit
MSTest
Puede obtener más información en los siguientes tutoriales:
Cree pruebas unitarias mediante xUnit y C# con la CLI de .NET Core.
Cree pruebas unitarias mediante NUnit y C# con la CLI de .NET Core.
Cree pruebas unitarias mediante MSTest y C# con la CLI de .NET Core.
Cree pruebas unitarias mediante xUnit y F# con la CLI de .NET Core.
Cree pruebas unitarias mediante NUnit y F# con la CLI de .NET Core.
Cree pruebas unitarias mediante MSTest y F# con la CLI de .NET Core.
Cree pruebas unitarias mediante xUnit y Visual Basic con la CLI de .NET Core.
Cree pruebas unitarias mediante NUnit y Visual Basic con la CLI de .NET Core.
Cree pruebas unitarias mediante MSTest y Visual Basic con la CLI de .NET Core.
Puede obtener más información en los siguientes artículos:
Visual Studio Enterprise proporciona herramientas de pruebas fantásticas para .NET Core. Consulte Live Unit
Testing o Cobertura de código para obtener más información.
Para obtener más información sobre cómo ejecutar pruebas unitarias, vea Ejecución de pruebas unitarias
selectivas o Incluir y excluir proyectos de prueba y métodos de prueba.
Cómo usar xUnit con .NET Core y Visual Studio.
Procedimientos recomendados de pruebas unitarias
con .NET Core y .NET Standard
12/01/2020 • 26 minutes to read • Edit Online

La escritura de pruebas unitarias reporta muchos beneficios; las pruebas ayudan con la regresión, proporcionan
documentación y facilitan un buen diseño. Pero también son difíciles de leer y, si son frágiles, pueden causar
estragos en el código base. En este artículo se describen algunos procedimientos recomendados sobre el diseño de
pruebas unitarias para proyectos de .NET Core y .NET Standard.
En esta guía, aprenderá algunos procedimientos recomendados para escribir pruebas unitarias resistentes y fáciles
de entender.
De John Reese, con agradecimientos especiales a Roy Osherove

El porqué de las pruebas unitarias


Menos tiempo para realizar pruebas funcionales
Las pruebas funcionales son costosas. Normalmente implican la apertura de la aplicación y la realización de una
serie de pasos que usted (u otro usuario) debe seguir para validar el comportamiento esperado. Es posible que
estos pasos no sean siempre conocidos para el evaluador, lo que significa tener que recurrir a alguien con más
conocimientos en el tema para llevar a cabo la prueba. Las pruebas en sí mismas podrían llevar segundos en el
caso de cambios triviales, o minutos en el de cambios más importantes. Por último, este proceso debe repetirse
para cada cambio que se realice en el sistema.
Por otra parte, las pruebas unitarias duran milisegundos, se pueden ejecutar con solo presionar un botón y no
exigen necesariamente ningún conocimiento del sistema en general. El que la prueba se supere o no depende del
ejecutor de pruebas, no del usuario.
Protección frente a regresión
Los defectos de regresión son aquellos que se presentan cuando se realiza un cambio en la aplicación. Es habitual
que los evaluadores no solo prueben una nueva característica, sino también las ya existentes con el fin de
comprobar que siguen funcionando según lo previsto.
Con las pruebas unitarias, es posible volver a ejecutar el conjunto completo de pruebas después de cada
compilación o incluso después de cambiar una línea de código. Eso da confianza en que el nuevo código no
interrumpa la funcionalidad existente.
Documentación ejecutable
Es posible que no siempre sea evidente lo que hace un método determinado o cómo se comporta ante una acción
concreta. Es posible que se pregunte: ¿cómo se comporta este método si se le pasa una cadena en blanco? ¿Null?
Si tiene un conjunto de pruebas unitarias con un nombre adecuado, cada prueba debe ser capaz de explicar con
claridad el resultado esperado de una acción determinada. Además, debe ser capaz de comprobar que funciona.
Menos código acoplado
Cuando el código está estrechamente acoplado, puede resultar difícil realizar pruebas unitarias. Sin crear pruebas
unitarias para el código que se está escribiendo, el acoplamiento puede ser menos evidente.
Al escribir pruebas para el código, este se desacopla naturalmente, ya que, de otra forma, sería más difícil de
probar.
Características de una buena prueba unitaria
Rápida. No es infrecuente que los proyectos maduros tengan miles de pruebas unitarias. Las pruebas unitarias
deberían tardar muy poco tiempo en ejecutarse. Milisegundos.
Aislada. Las pruebas unitarias son independientes, se pueden ejecutar de forma aislada y no tienen ninguna
dependencia en ningún factor externo, como sistemas de archivos o bases de datos.
Reiterativa. La ejecución de una prueba unitaria debe ser coherente con sus resultados, es decir, devolver
siempre el mismo resultado si no cambia nada entre ejecuciones.
Autocomprobada. La prueba debe ser capaz de detectar automáticamente si el resultado ha sido correcto o
incorrecto sin necesidad de intervención humana.
Oportuna. Una prueba unitaria no debe tardar un tiempo desproporcionado en escribirse en comparación con
el código que se va a probar. Si observa que la prueba del código tarda mucho en comparación con su escritura,
considere un diseño más fácil de probar.

Vamos a hablar el mismo idioma


El término ficticio desafortunadamente se emplea muy mal cuando se habla sobre las pruebas. A continuación se
definen los tipos más comunes de emulaciones al escribir pruebas unitarias:
Emulación: una emulación es un término genérico que se puede usar para describir un stub o un objeto ficticio. Si
es un stub o un objeto ficticio depende del contexto en el que se use. Es decir, una emulación puede ser un stub o
un objeto ficticio.
Objeto ficticio: un objeto ficticio es una emulación del sistema que decide si una prueba unitaria se ha superado o
no. Un objeto ficticio comienza como una emulación hasta que se declara en ella.
Stub: un stub es un reemplazo controlable para una dependencia existente (o colaborador) en el sistema. Con un
stub, puede probar el código sin tratar directamente con la dependencia. De forma predeterminada, una emulación
empieza como un stub.
Tenga en cuenta el fragmento de código siguiente:

var mockOrder = new MockOrder();


var purchase = new Purchase(mockOrder);

purchase.ValidateOrders();

Assert.True(purchase.CanBeShipped);

Es un ejemplo de stub al que se hace referencia como un objeto ficticio. En este caso, es un stub. Simplemente está
pasando el pedido para poder crear una instancia de Purchase (el sistema sometido a prueba). El nombre
MockOrder también es muy confuso porque, una vez más, el pedido no es un objeto ficticio.

Un mejor enfoque sería

var stubOrder = new FakeOrder();


var purchase = new Purchase(stubOrder);

purchase.ValidateOrders();

Assert.True(purchase.CanBeShipped);

Al cambiar el nombre de la clase FakeOrder , la ha convertido en mucho más genérica, con lo que puede usarse
como objeto ficticio o stub. Lo que sea mejor para el caso de prueba. En el ejemplo anterior, FakeOrder se usa
como un stub. No usa FakeOrder de ninguna forma durante la aserción. FakeOrder simplemente se ha pasado a la
clase Purchase para satisfacer los requisitos del constructor.
Para usarlo como un objeto ficticio, podría hacer algo parecido a esto:

var mockOrder = new FakeOrder();


var purchase = new Purchase(mockOrder);

purchase.ValidateOrders();

Assert.True(mockOrder.Validated);

En este caso, va a registrar una propiedad en la emulación (la declara en ella), por lo que en el fragmento de código
anterior, mockOrder es un objeto simulado.

IMPORTANT
Es importante tener clara esta terminología. Si se denomina a los stubs "objetos ficticios", los demás desarrolladores van a
realizar suposiciones falsas sobre su intención.

Lo principal que debe recordar sobre los objetos ficticios frente a los stubs es que los objetos ficticios son como los
stubs, pero se declara en el objeto ficticio, y no en un stub.

Procedimientos recomendados
Asignar nombre a las pruebas
El nombre de la prueba debe constar de tres partes:
Nombre del método que se va a probar.
Escenario en el que se está probando.
Comportamiento esperado al invocar al escenario.
¿ Por qué?
Los estándares de nomenclatura son importantes porque expresan de forma explícita la intención de la prueba.
Las pruebas van más allá de garantizar que el código funciona, también proporcionan documentación. Con solo
mirar el conjunto de pruebas unitarias, debe ser capaz de deducir el comportamiento del código sin ni siquiera
mirar el propio código. Además, cuando no se superan las pruebas, puede ver exactamente qué escenarios no
cumplen las expectativas.
Malo:

[Fact]
public void Test_Single()
{
var stringCalculator = new StringCalculator();

var actual = stringCalculator.Add("0");

Assert.Equal(0, actual);
}

Mejor:
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();

var actual = stringCalculator.Add("0");

Assert.Equal(0, actual);
}

Organizar las pruebas


Organizar, actuar, declarar es un patrón común al realizar pruebas unitarias. Como el propio nombre implica,
consta de tres acciones principales:
Organizar los objetos, crearlos y configurarlos según sea necesario.
Actuar en un objeto.
Declarar que algo es como se espera.
¿ Por qué?
Separa claramente lo que se está probando de los pasos organizar y declarar.
Menos posibilidad de mezclar aserciones con el código para "actuar".
La legibilidad es uno de los aspectos más importantes a la hora de escribir una prueba. Al separar cada una de
estas acciones dentro de la prueba, se resaltan claramente las dependencias necesarias para llamar al código, la
forma de llamarlo y lo que se intenta declarar. Aunque es posible combinar algunos pasos y reducir el tamaño de la
prueba, el objetivo principal es que sea lo más legible posible.
Malo:

[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();

// Assert
Assert.Equal(0, stringCalculator.Add(""));
}

Mejor:

[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();

// Act
var actual = stringCalculator.Add("");

// Assert
Assert.Equal(0, actual);
}

Escribir pruebas correctas lo más sencillas posible


La entrada que se use en una prueba unitaria debe ser lo más sencilla posible para comprobar el comportamiento
que se está probando.
¿ Por qué?
Las pruebas se hacen más resistentes a los cambios futuros en el código base.
Más cercano al comportamiento de prueba que a la implementación.
Las pruebas que incluyen más información de la necesaria para superarse tienen una mayor posibilidad de
incorporar errores en la prueba y pueden hacer confusa su intención. Al escribir pruebas, el usuario quiere
centrarse en el comportamiento. El establecimiento de propiedades adicionales en los modelos o el empleo de
valores distintos de cero cuando no es necesario solo resta de lo que se quiere probar.
Malo:

[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();

var actual = stringCalculator.Add("42");

Assert.Equal(42, actual);
}

Mejor:

[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();

var actual = stringCalculator.Add("0");

Assert.Equal(0, actual);
}

Evitar cadenas mágicas


La asignación de nombres a las variables de las pruebas unitarias es tan importante, si no más, que la asignación
de nombres a las variables del código de producción. Las pruebas unitarias no deben contener cadenas mágicas.
¿ Por qué?
Evita la necesidad de que el lector de la prueba inspeccione el código de producción con el fin de averiguar lo
que hace que el valor sea especial.
Muestra explícitamente lo que se intenta probar, en lugar de lo que se intenta lograr.
Las cadenas mágicas pueden provocar confusión al lector de las pruebas. Si una cadena tiene un aspecto fuera de
lo normal, puede preguntarse por qué se ha elegido un determinado valor para un parámetro o valor devuelto.
Esto puede dar lugar a un vistazo más detallado a los detalles de implementación, en lugar de centrarse en la
prueba.

TIP
Al escribir pruebas, su objetivo debe ser expresar tanta intención como sea posible. En el caso de las cadenas mágicas, un
buen enfoque es asignar estos valores a constantes.

Malo:
[Fact]
public void Add_BigNumber_ThrowsException()
{
var stringCalculator = new StringCalculator();

Action actual = () => stringCalculator.Add("1001");

Assert.Throws<OverflowException>(actual);
}

Mejor:

[Fact]
void Add_MaximumSumResult_ThrowsOverflowException()
{
var stringCalculator = new StringCalculator();
const string MAXIMUM_RESULT = "1001";

Action actual = () => stringCalculator.Add(MAXIMUM_RESULT);

Assert.Throws<OverflowException>(actual);
}

Evitar la lógica en las pruebas


Al escribir las pruebas unitarias, evite la concatenación de cadenas manual y las condiciones lógicas como if ,
while , for , switch , etc.

¿ Por qué?
Menos posibilidad de incorporar un error a las pruebas.
El foco está en el resultado final, en lugar de en los detalles de implementación.
Al incorporar lógica al conjunto de pruebas, aumenta considerablemente la posibilidad de agregar un error. El
último lugar en el que se quiere encontrar un error es el conjunto de pruebas. Debe tener mucha confianza en que
las pruebas funcionan, de lo contrario, no confiará en ellas. Las pruebas en las que no se confía, no proporcionan
ningún valor. Cuando se produce un error en una prueba, quiere saber que algo va mal realmente con el código y
que no se puede omitir.

TIP
Si la lógica en la prueba parece inevitable, considere la posibilidad de dividirla en dos o más pruebas diferentes.

Malo:
[Fact]
public void Add_MultipleNumbers_ReturnsCorrectResults()
{
var stringCalculator = new StringCalculator();
var expected = 0;
var testCases = new[]
{
"0,0,0",
"0,1,2",
"1,2,3"
};

foreach (var test in testCases)


{
Assert.Equal(expected, stringCalculator.Add(test));
expected += 3;
}

Mejor:

[Theory]
[InlineData("0,0,0", 0)]
[InlineData("0,1,2", 3)]
[InlineData("1,2,3", 6)]
public void Add_MultipleNumbers_ReturnsSumOfNumbers(string input, int expected)
{
var stringCalculator = new StringCalculator();

var actual = stringCalculator.Add(input);

Assert.Equal(expected, actual);
}

Se prefieren métodos auxiliares a la instalación y el desmontaje


Si necesita un objeto o un estado similares para las pruebas, se prefiere un método auxiliar al aprovechamiento de
los atributos de instalación y desmontaje, si existen.
¿ Por qué?
Menos confusión al leer las pruebas, puesto que todo el código es visible desde dentro de cada prueba.
Menor posibilidad de configurar demasiado o muy poco para la prueba.
Menor posibilidad de compartir el estado entre las pruebas, lo que crea dependencias no deseadas entre ellas.
En los marcos de trabajo de pruebas unitarias, se llama a Setup antes de cada prueba unitaria del conjunto de
pruebas. Aunque algunos puedan verlo como una herramienta útil, por lo general termina por dar lugar a pruebas
recargadas y difíciles de leer. Cada prueba normalmente tendrá requisitos diferentes para funcionar y ejecutarse.
Por desgracia, Setup obliga a usar los mismos requisitos para cada prueba.

NOTE
xUnit ha quitado la instalación y el desmontaje a partir de la versión 2.x

Malo:
private readonly StringCalculator stringCalculator;
public StringCalculatorTests()
{
stringCalculator = new StringCalculator();
}

// more tests...

[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var result = stringCalculator.Add("0,1");

Assert.Equal(1, result);
}

Mejor:

[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var stringCalculator = CreateDefaultStringCalculator();

var actual = stringCalculator.Add("0,1");

Assert.Equal(1, actual);
}

// more tests...

private StringCalculator CreateDefaultStringCalculator()


{
return new StringCalculator();
}

Evitar varias aserciones


Al escribir las pruebas, intente incluir solo una aserción por prueba. Los enfoques comunes para usar solo una
aserción incluyen:
Crear una prueba independiente para cada aserción.
Usar pruebas con parámetros.
¿ Por qué?
Si se produce un error en una aserción, no se evalúan las aserciones posteriores.
Garantiza que no se estén declarando varios casos en las pruebas.
Proporciona la imagen completa de por qué se producen errores en las pruebas.
Al incorporar varias aserciones en un caso de prueba, no se garantiza que se ejecuten todas. En la mayoría de los
marcos de trabajo de pruebas unitarias, una vez que se produce un error en una aserción de una prueba unitaria,
las pruebas siguientes se consideran erróneas automáticamente. Esto puede ser confuso, ya que funciones que
realmente están funcionando se muestran como erróneas.
NOTE
Una excepción común a esta regla es cuando se declara en un objeto. En este caso, suele ser aceptable que haya varias
aserciones en cada propiedad para asegurarse de que el objeto está en el estado que se espera que esté.

Malo:

[Fact]
public void Add_EdgeCases_ThrowsArgumentExceptions()
{
Assert.Throws<ArgumentException>(() => stringCalculator.Add(null));
Assert.Throws<ArgumentException>(() => stringCalculator.Add("a"));
}

Mejor:

[Theory]
[InlineData(null)]
[InlineData("a")]
public void Add_InputNullOrAlphabetic_ThrowsArgumentException(string input)
{
var stringCalculator = new StringCalculator();

Action actual = () => stringCalculator.Add(input);

Assert.Throws<ArgumentException>(actual);
}

Validar métodos privados mediante la prueba unitaria de métodos públicos


En la mayoría de los casos, no debería haber necesidad de probar un método privado. Los métodos privados son
un detalle de implementación. Se puede considerar de esta forma: los métodos privados nunca existen de forma
aislada. En algún momento, va a haber un método público que llame al método privado como parte de su
implementación. Lo que debería importarle es el resultado final del método público que llama al privado.
Considere el caso siguiente

public string ParseLogLine(string input)


{
var sanitizedInput = TrimInput(input);
return sanitizedInput;
}

private string TrimInput(string input)


{
return input.Trim();
}

Su primera reacción puede ser empezar a escribir una prueba para TrimInput porque quiere asegurarse de que el
método funciona según lo previsto. Pero es muy posible que ParseLogLine manipule a sanitizedInput de una
forma totalmente imprevista, con lo que una prueba en TrimInput sería inútil.
La prueba real debe realizarse en el método público ParseLogLine , porque eso es lo debe importarle en última
instancia.
public void ParseLogLine_ByDefault_ReturnsTrimmedResult()
{
var parser = new Parser();

var result = parser.ParseLogLine(" a ");

Assert.Equals("a", result);
}

Con este punto de vista, si ve un método privado, busque el método público y escriba las pruebas en ese método.
Simplemente porque un método privado devuelva el resultado esperado, no significa que el sistema que
finalmente llama al método privado use el resultado correctamente.
Referencias estáticas de stub
Uno de los principios de una prueba unitaria es que debe tener control total del sistema sometido a prueba. Esto
puede ser problemático cuando el código de producción incluye llamadas a referencias estáticas (por ejemplo,
DateTime.Now ). Considere el código siguiente

public int GetDiscountedPrice(int price)


{
if(DateTime.Now.DayOfWeek == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}

¿Cómo se podrían realizar pruebas unitarias de este código? Puede probar un enfoque como

public void GetDiscountedPrice_ByDefault_ReturnsFullPrice()


{
var priceCalculator = new PriceCalculator();

var actual = priceCalculator.GetDiscountedPrice(2);

Assert.Equals(2, actual)
}

public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()


{
var priceCalculator = new PriceCalculator();

var actual = priceCalculator.GetDiscountedPrice(2);

Assert.Equals(1, actual);
}

Lamentablemente, pronto comprobará que hay un par de problemas con las pruebas.
Si el conjunto de pruebas se ejecuta un martes, se superará la segunda prueba, pero se producirá un error en la
primera.
Si el conjunto de pruebas se ejecuta otro día, se superará la primera prueba, pero se producirá un error en la
segunda.
Para solucionar estos problemas, debe incorporar un arreglo en el código de producción. Un enfoque consiste en
encapsular el código que necesita controlar en una interfaz y hacer que el código de producción dependa de esa
interfaz.

public interface IDateTimeProvider


{
DayOfWeek DayOfWeek();
}

public int GetDiscountedPrice(int price, IDateTimeProvider dateTimeProvider)


{
if(dateTimeProvider.DayOfWeek() == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}

El conjunto de pruebas ahora se convierte

public void GetDiscountedPrice_ByDefault_ReturnsFullPrice()


{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Monday);

var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);

Assert.Equals(2, actual);
}

public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()


{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Tuesday);

var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);

Assert.Equals(1, actual);
}

Ahora el conjunto de pruebas tiene control total sobre DateTime.Now y puede convertir en stub cualquier valor al
llamar al método.
Prueba unitaria de C# en .NET Core mediante
pruebas de dotnet y xUnit
20/01/2020 • 8 minutes to read • Edit Online

En este tutorial se muestra cómo compilar una solución que contiene un proyecto de prueba unitaria y un
proyecto de código fuente. Para seguir el tutorial con una solución precompilada, vea o descargue el código de
ejemplo. Para obtener instrucciones de descarga, vea Ejemplos y tutoriales.

Creación de la solución
En esta sección, se crea una solución que contiene los proyectos de prueba y origen. La solución completada tiene
la siguiente estructura de directorios:

/unit-testing-using-dotnet-test
unit-testing-using-dotnet-test.sln
/PrimeService
PrimeService.cs
PrimeService.csproj
/PrimeService.Tests
PrimeService_IsPrimeShould.cs
PrimeServiceTests.csproj

Las instrucciones siguientes proporcionan los pasos para crear la solución de prueba. Consulte la sección sobre
comandos para crear la solución de prueba a fin de obtener instrucciones para crear la solución de prueba en un
paso.
Abra una ventana del Shell.
Ejecute el siguiente comando:

dotnet new sln -o unit-testing-using-dotnet-test

El comando dotnet new sln crea una nueva solución en el directorio unit-testing -using -dotnet-test.
Cambie el directorio a la carpeta unit-testing -using -dotnet-test.
Ejecute el siguiente comando:

dotnet new classlib -o PrimeService

El comando dotnet new classlib crea un nuevo proyecto de biblioteca de clases en la carpeta
PrimeService. La nueva biblioteca de clases contendrá el código que se va a probar.
Cambie el nombre de Class1.cs a PrimeService.cs.
Reemplace el código de PrimeService.cs por el código siguiente:
using System;

namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Not implemented.");
}
}
}

El código anterior:
Produce una excepción NotImplementedException con un mensaje que indica que no se ha
implementado.
Se actualiza más adelante en el tutorial.
En el directorio unit-testing -using -dotnet-test, ejecute el comando siguiente para agregar el proyecto de
biblioteca de clases a la solución:

dotnet sln add ./PrimeService/PrimeService.csproj

Cree el proyecto PrimeService.Tests ejecutando el comando siguiente:

dotnet new xunit -o PrimeService.Tests

El comando anterior:
Crea el proyecto PrimeService.Tests en el directorio PrimeService.Tests. El proyecto de prueba usa xUnit
como biblioteca de pruebas.
Configura el ejecutor de pruebas agregando los siguientes <PackageReference /> elementos al archivo
del proyecto:
"Microsoft.NET.Test.Sdk"
"xunit"
"xunit.runner.visualstudio"
Agregue el proyecto de prueba al archivo de solución ejecutando el siguiente comando:

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Agregue la biblioteca de clases PrimeService como dependencia al proyecto PrimeService.Tests:

dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj

Comandos para crear la solución


En esta sección se resumen todos los comandos de la sección anterior. Omita esta sección si ha completado los
pasos en la sección anterior.
Los siguientes comandos crean la solución de prueba en una máquina Windows. Para macOS y Unix, actualice el
comando ren a la versión del SO de ren para cambiar el nombre de un archivo:
dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Siga las instrucciones de "Reemplace el código de PrimeService.cs por el siguiente código" de la sección anterior.

Creación de una prueba


Un enfoque popular en el desarrollo controlado por pruebas (TDD ) consiste en escribir una prueba antes de
implementar un código de destino. En este tutorial se usa el enfoque TDD. Se puede llamar al método IsPrime ,
pero sin implementar. Se produce un error en una llamada de prueba a IsPrime . Con TDD, se escribe una prueba
a sabiendas de que en esta se produce un error. El código de destino se actualiza para conseguir que se supere la
prueba. Siga repitiendo este enfoque, escribiendo una prueba con errores y, a continuación, actualizando el código
de destino que se va a pasar.
Actualice el proyecto PrimeService.Tests:
Elimine PrimeService.Tests/UnitTest1.cs.
Cree un archivo PrimeService.Tests/PrimeService_IsPrimeShould.cs.
Reemplace el código de PrimeService_IsPrimeShould.cs por el código siguiente:

using Xunit;
using Prime.Services;

namespace Prime.UnitTests.Services
{
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService;

public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
var result = _primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");


}
}
}

El atributo [Fact] declara un método de prueba que el ejecutor de pruebas ejecuta. En la carpeta
PrimeService.Tests, ejecute dotnet test . El comando dotnet test compila ambos proyectos y ejecuta las pruebas.
El ejecutor de pruebas de xUnit tiene el punto de entrada del programa para ejecutar las pruebas. dotnet test
inicia el ejecutor de pruebas con el proyecto de prueba unitaria.
Se produce un error en la prueba porque no se ha implementado IsPrime . Con el enfoque TDD, solo tiene que
escribir código suficiente para que se supere esta prueba. Actualice IsPrime con el siguiente código:
public bool IsPrime(int candidate)
{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}

Ejecute dotnet test . La prueba se supera.


Incorporación de más pruebas
Agregue pruebas de números primos para 0 y -1. Podría copiar la prueba anterior y cambiar el siguiente código
para usar 0 y -1:

var result = _primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");

La copia de código de prueba cuando solamente es un parámetro el que cambia da lugar a la duplicación de
código y al sobredimensionamiento de pruebas. Los siguientes atributos de xUnit habilitan la escritura de un
conjunto de pruebas similares:
Un elemento [Theory] representa un conjunto de pruebas que ejecutan el mismo código, pero tienen
diferentes argumentos de entrada.
Un atributo [InlineData] especifica valores para esas entradas.

En lugar de crear pruebas nuevas, aplique los atributos de xUnit anteriores para crear una sola teoría. Reemplace
el código siguiente:

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
var result = _primeService.IsPrime(1);

Assert.False(result, "1 should not be prime");


}

por el siguiente código:

[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);

Assert.False(result, $"{value} should not be prime");


}

En el código anterior, [Theory] y [InlineData] habilitan la prueba de varios valores inferiores a dos. Dos es el
número primo más pequeño.
Al ejecutar dotnet test , se produce un error en dos de las pruebas. Para que se superen todas las pruebas,
actualice el método IsPrime con el siguiente código:
public bool IsPrime(int candidate)
{
if (candidate < 2)
{
return false;
}
throw new NotImplementedException("Not fully implemented.");
}

Siguiendo el enfoque TDD, agregue más pruebas con errores y, a continuación, actualice el código de destino.
Consulte la versión terminada de las pruebas y la implementación completa de la biblioteca.
El método IsPrime completado no es un algoritmo eficaz para probar los números primos.
Recursos adicionales
Sitio oficial de xUnit.net
Probar la lógica del controlador en ASP.NET Core
dotnet add reference
Prueba unitaria de C# con NUnit y .NET Core
12/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Requisitos previos
SDK de .NET Core 2.1 o versiones posteriores.
Un editor de texto o un editor de código de su elección.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -using -nunit que contenga la solución. En este
directorio nuevo, ejecute el comando siguiente para crear un archivo de solución nuevo para la biblioteca de clases
y el proyecto de prueba:

dotnet new sln

A continuación, cree un directorio PrimeService. En el esquema siguiente se muestra la estructura de directorios y


archivos hasta el momento:

/unit-testing-using-nunit
unit-testing-using-nunit.sln
/PrimeService

Convierta PrimeService en el directorio actual y ejecute el siguiente comando para crear el proyecto de origen:

dotnet new classlib

Cambie el nombre de Class1.cs a PrimeService.cs. Creará una implementación de errores de la clase PrimeService :

using System;

namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first.");
}
}
}

Cambie nuevamente el directorio a unit-testing -using -nunit. Ejecute el siguiente comando para agregar el
proyecto de biblioteca de clases a la solución:

dotnet sln add PrimeService/PrimeService.csproj

Crear el proyecto de prueba


A continuación, cree el directorio PrimeService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-using-nunit
unit-testing-using-nunit.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests

Convierta el directorio PrimeService.Tests en el directorio actual y cree un proyecto nuevo con el comando
siguiente:

dotnet new nunit

El comando dotnet new crea un proyecto de prueba que usa NUnit como la biblioteca de pruebas. La plantilla
generada configura el ejecutor de pruebas en el archivo PrimeService.Tests.csproj:

<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. En el paso anterior,
dotnet new agrega el SDK de prueba de Microsoft, el marco de pruebas de NUnit y el adaptador de prueba de
NUnit. Ahora, agregue la biblioteca de clases PrimeService como otra dependencia al proyecto. Use el comando
dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.csproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


En el esquema siguiente se muestra el diseño de solución final:

/unit-testing-using-nunit
unit-testing-using-nunit.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Test Source Files
PrimeService.Tests.csproj

Ejecute el comando siguiente en el directorio unit-testing -using -nunit:


dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. En el directorio PrimeService.Tests,
cambie el nombre del archivo UnitTest1.cs por PrimeService_IsPrimeShould.cs y reemplace todo su contenido por
el código siguiente:

using NUnit.Framework;
using Prime.Services;

namespace Prime.UnitTests.Services
{
[TestFixture]
public class PrimeService_IsPrimeShould
{
[Test]
public void IsPrime_InputIs1_ReturnFalse()
{
PrimeService primeService = CreatePrimeService();
var result = primeService.IsPrime(1);

Assert.IsFalse(result, "1 should not be prime");


}

/*
More tests
*/

private PrimeService CreatePrimeService()


{
return new PrimeService();
}
}
}

El atributo [TestFixture] indica una clase que contiene pruebas unitarias. El atributo [Test] indica que un
método es un método de prueba.
Guarde este archivo y ejecute dotnet test para compilar las pruebas y la biblioteca de clases y luego ejecutar las
pruebas. El ejecutor de pruebas de NUnit tiene el punto de entrada del programa para ejecutar las pruebas desde
la consola. dotnet test inicia el ejecutor de pruebas con el proyecto de prueba unitaria que creó.
La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase PrimeService que funciona:

public bool IsPrime(int candidate)


{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Please create a test first.");
}

En el directorio unit-testing -using -nunit, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.
Agregar más características
Ahora que la prueba se ha superado, es el momento de escribir más. Hay otros casos simples para números
primos: 0, -1. Puede agregar pruebas nuevas con el atributo [Test] , pero enseguida este proceso se hace tedioso.
Hay otros atributos de NUnit que le permiten escribir un conjunto de pruebas similares. Un atributo [TestCase] se
usa para crear un conjunto de pruebas que ejecutan el mismo código pero tienen diferentes argumentos de
entrada. Puede usar el atributo [TestCase] para especificar valores para esas entradas.
En lugar de crear pruebas, aplique este atributo para crear una sola prueba controlada por datos. La prueba
controlada por datos es un método que prueba varios valores menores que dos, que es el número primo menor:

[TestCase(-1)]
[TestCase(0)]
[TestCase(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);

Assert.IsFalse(result, $"{value} should not be prime");


}

Ejecute dotnet test , y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula
if al principio del método Main en el archivo PrimeService.cs:

if (candidate < 2)

Puede continuar recorriendo en iteración agregando más pruebas, más teorías y más código en la biblioteca
principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.
Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.
Prueba unitaria de C# con MSTest y .NET Core
12/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Creación del proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -using -mstest que contenga la solución. En este
directorio nuevo, ejecute dotnet new sln para crear un archivo de solución nuevo para la biblioteca de clases y el
proyecto de prueba. A continuación, cree un directorio PrimeService. En el esquema siguiente se muestra la
estructura de directorios y archivos hasta el momento:

/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService

Convierta PrimeService en el directorio actual y ejecute dotnet new classlib para crear el proyecto de origen.
Cambie el nombre de Class1.cs a PrimeService.cs. Creará una implementación de errores de la clase PrimeService
:

using System;

namespace Prime.Services
{
public class PrimeService
{
public bool IsPrime(int candidate)
{
throw new NotImplementedException("Please create a test first.");
}
}
}

Cambie nuevamente el directorio al directorio unit-testing -using -mstest. Ejecute


dotnet sln add PrimeService/PrimeService.csproj para agregar el proyecto de biblioteca de clases a la solución.

Crear el proyecto de prueba


A continuación, cree el directorio PrimeService.Tests. En el esquema siguiente se muestra la estructura de
directorios:
/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests

Convierta el directorio PrimeService.Tests en el directorio actual y cree un proyecto nuevo con dotnet new mstest .
Este comando de dotnet nuevo crea un proyecto de prueba que usa MSTest como la biblioteca de pruebas. La
plantilla generada configura el ejecutor de pruebas en el archivo PrimeServiceTests.csproj:

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso
anterior agregó el SDK de MSTest, el marco de prueba de MSTest y el ejecutor de MSTest. Ahora, agregue la
biblioteca de clases PrimeService como otra dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.csproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


En el esquema siguiente se muestra el diseño de solución final:

/unit-testing-using-mstest
unit-testing-using-mstest.sln
/PrimeService
Source Files
PrimeService.csproj
/PrimeService.Tests
Test Source Files
PrimeServiceTests.csproj

Ejecute dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj en el directorio unit-testing -using -mstest.

Creación de la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Quite UnitTest1.cs del directorio
PrimeService.Tests y cree un nuevo archivo de C# denominado PrimeService_IsPrimeShould.cs con el siguiente
contenido:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;

namespace Prime.UnitTests.Services
{
[TestClass]
public class PrimeService_IsPrimeShould
{
private readonly PrimeService _primeService;

public PrimeService_IsPrimeShould()
{
_primeService = new PrimeService();
}

[TestMethod]
public void IsPrime_InputIs1_ReturnFalse()
{
var result = _primeService.IsPrime(1);

Assert.IsFalse(result, "1 should not be prime");


}
}
}

El atributo TestClass indica una clase que contiene pruebas unitarias. El atributo TestMethod indica que un método
es un método de prueba.
Guarde este archivo y ejecute dotnet test para compilar las pruebas y la biblioteca de clases y luego ejecutar las
pruebas. El ejecutor de pruebas de MSTest tiene el punto de entrada del programa para ejecutar las pruebas desde
la consola. dotnet test inicia el ejecutor de pruebas con el proyecto de prueba unitaria que creó.
La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase PrimeService que funciona:

public bool IsPrime(int candidate)


{
if (candidate == 1)
{
return false;
}
throw new NotImplementedException("Please create a test first.");
}

En el directorio unit-testing -using -mstest, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.

Adición de más características


Ahora que la prueba se ha superado, es el momento de escribir más. Hay otros casos simples para números
primos: 0, -1. Puede agregar pruebas nuevas con el atributo TestMethod, pero este proceso enseguida se hace
tedioso. Hay otros atributos de MSTest que le permiten escribir un conjunto de pruebas similares. Un atributo
DataTestMethod representa un conjunto de pruebas que ejecutan el mismo código, pero tienen diferentes
argumentos de entrada. Puede usar el atributo DataRow para especificar valores para esas entradas.
En lugar de crear pruebas nuevas, aplique estos dos atributos para crear una sola prueba controlada por datos. La
prueba controlada por datos es un método que prueba varios valores menores que dos, que es el número primo
menor:
[DataTestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
var result = _primeService.IsPrime(value);

Assert.IsFalse(result, $"{value} should not be prime");


}

Ejecute dotnet test , y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula
if al principio del método:

if (candidate < 2)

Puede continuar recorriendo en iteración agregando más pruebas, más teorías y más código en la biblioteca
principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.
Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la
mayor parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.

Vea también
Microsoft.VisualStudio.TestTools.UnitTesting
Usar el marco de trabajo MSTest en pruebas unitarias
Documentos del marco de pruebas de MSTest V2
Bibliotecas de F# de prueba unitaria en .NET Core
con pruebas de dotnet y xUnit
20/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -with-fsharp que contenga la solución. En este
directorio nuevo, ejecute dotnet new sln para crear una solución nueva. Esto permite facilitar la administración de
la biblioteca de clases y del proyecto de prueba unitaria. En el directorio de la solución, cree un directorio
MathService. Esta es la estructura de directorios y archivos hasta el momento:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService

Convierta MathService en el directorio actual y ejecute dotnet new classlib -lang "F#" para crear el proyecto de
origen. Creará una implementación de errores del servicio de matemáticas:

module MyMath =
let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Cambie nuevamente el directorio al directorio unit-testing -with-fsharp. Ejecute


dotnet sln add .\MathService\MathService.fsproj para agregar el proyecto de biblioteca de clases a la solución.

Crear el proyecto de prueba


A continuación, cree el directorio MathService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests

Convierta el directorio MathService.Tests en el directorio actual y cree un proyecto nuevo con


dotnet new xunit -lang "F#" . Esto crea un proyecto de prueba que usa xUnit como biblioteca de pruebas. La
plantilla generada configura el ejecutor de pruebas en MathServiceTests.fsproj:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso
anterior, agregó xUnit y el ejecutor de xUnit. Ahora, agregue la biblioteca de clases MathService como otra
dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../MathService/MathService.fsproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de solución final siguiente:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Test Source Files
MathServiceTests.fsproj

Ejecute dotnet sln add .\MathService.Tests\MathService.Tests.fsproj en el directorio unit-testing -with-fsharp.

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Abra Tests.fs y agregue el código
siguiente:

[<Fact>]
let ``My test`` () =
Assert.True(true)

[<Fact>]
let ``Fail every time`` () = Assert.True(false)

El atributo [<Fact>] indica un método de prueba que el ejecutor de pruebas ejecuta. En unit-testing -with-fsharp,
ejecute dotnet test para compilar las pruebas y la biblioteca de clases y luego ejecutar las pruebas. El ejecutor de
pruebas de xUnit tiene el punto de entrada del programa para ejecutar las pruebas desde la consola. dotnet test
inicia el ejecutor de pruebas con el proyecto de prueba unitaria que creó.
Estas dos pruebas muestran las pruebas superadas y con errores más básicas. My test indica que se supera y
Fail every time indica que no. Ahora, cree una prueba para el método squaresOfOdds . El método squaresOfOdds
devuelve una secuencia de los cuadrados de todos los valores enteros impares que forman parte de la secuencia
de entrada. En lugar de intentar escribir todas esas funciones a la vez, puede crear de forma iterativa pruebas que
validen la funcionalidad. Hacer cada prueba superada significa crear la funcionalidad necesaria para el método.
La prueba más sencilla que se puede escribir es llamar a squaresOfOdds con todos los números impares, donde el
resultado sea una secuencia de enteros vacía. Aquí se muestra la prueba:
[<Fact>]
let ``Sequence of Evens returns empty collection`` () =
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)

La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase MathService que funciona:

let squaresOfOdds xs =
Seq.empty<int>

En el directorio unit-testing -with-fsharp, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto MathService y luego del proyecto MathService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.

Finalización de los requisitos


Ahora que la prueba se ha superado, es el momento de escribir más. El próximo caso simple funciona con una
secuencia cuyo único número impar es 1 . El número 1 es más simple, porque el cuadrado de 1 es 1. Aquí está la
prueba siguiente:

[<Fact>]
let ``Sequences of Ones and Evens returns Ones`` () =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.Equal<Collections.Generic.IEnumerable<int>>(expected, actual)

La ejecución de dotnet test ejecuta las pruebas y muestra que la prueba nueva no se supera. Ahora actualice el
método squaresOfOdds para controlar esta prueba nueva. Filtre todos los números impares y quítelos de la
secuencia para que se supere esta prueba. Para hacerlo, escriba una función de filtro pequeña y use Seq.filter :

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd

Falta un paso todavía: el cuadrado de cada uno de los números impares. Comience escribiendo una prueba nueva:

[<Fact>]
let ``SquaresOfOdds works`` () =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.Equal(expected, actual)

Puede corregir la prueba si canaliza la secuencia filtrada a través de una operación de asignación para calcular el
cuadrado de cada número impar:
let private square x = x * x
let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square

Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.

Vea también
dotnet new
dotnet sln
dotnet add reference
dotnet test
Bibliotecas de F# de prueba unitaria en .NET Core
con pruebas de dotnet y NUnit
20/01/2020 • 9 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Requisitos previos
SDK de .NET Core 2.1 o versiones posteriores.
Un editor de texto o un editor de código de su elección.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -with-fsharp que contenga la solución. En este
directorio nuevo, ejecute el comando siguiente para crear un archivo de solución nuevo para la biblioteca de clases
y el proyecto de prueba:

dotnet new sln

A continuación, cree un directorio MathService. En el esquema siguiente se muestra la estructura de directorios y


archivos hasta el momento:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService

Convierta MathService en el directorio actual y ejecute el siguiente comando para crear el proyecto de origen:

dotnet new classlib -lang "F#"

Creará una implementación de errores del servicio de matemáticas:

module MyMath =
let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Cambie nuevamente el directorio al directorio unit-testing -with-fsharp. Ejecute el siguiente comando para agregar
el proyecto de biblioteca de clases a la solución:

dotnet sln add .\MathService\MathService.fsproj


Crear el proyecto de prueba
A continuación, cree el directorio MathService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests

Convierta el directorio MathService.Tests en el directorio actual y cree un proyecto nuevo con el comando
siguiente:

dotnet new nunit -lang "F#"

Esto crea un proyecto de prueba que usa NUnit como el marco de pruebas. La plantilla generada configura el
ejecutor de pruebas en MathServiceTests.fsproj:

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="NUnit" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. En el paso anterior,
dotnet new agrega NUnit y el adaptador de prueba NUnit. Ahora, agregue la biblioteca de clases MathService
como otra dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../MathService/MathService.fsproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de solución final siguiente:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Test Source Files
MathService.Tests.fsproj

Ejecute el comando siguiente en el directorio unit-testing -with-fsharp:

dotnet sln add .\MathService.Tests\MathService.Tests.fsproj

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Abra UnitTest1.fs y agregue el código
siguiente:
namespace MathService.Tests

open System
open NUnit.Framework
open MathService

[<TestFixture>]
type TestClass () =

[<Test>]
member this.TestMethodPassing() =
Assert.True(true)

[<Test>]
member this.FailEveryTime() = Assert.True(false)

El atributo [<TestFixture>] indica una clase que contiene pruebas. El atributo [<Test>] indica un método de
prueba que el ejecutor de pruebas ejecuta. En el directorio unit-testing -with-fsharp, ejecute dotnet test para
compilar las pruebas y la biblioteca de clases y luego ejecutar las pruebas. El ejecutor de pruebas de NUnit tiene el
punto de entrada del programa para ejecutar las pruebas desde la consola. dotnet test inicia el ejecutor de
pruebas con el proyecto de prueba unitaria que creó.
Estas dos pruebas muestran las pruebas superadas y con errores más básicas. My test indica que se supera y
Fail every time indica que no. Ahora, cree una prueba para el método squaresOfOdds . El método squaresOfOdds
devuelve una secuencia de los cuadrados de todos los valores enteros impares que forman parte de la secuencia
de entrada. En lugar de intentar escribir todas esas funciones a la vez, puede crear de forma iterativa pruebas que
validen la funcionalidad. Hacer cada prueba superada significa crear la funcionalidad necesaria para el método.
La prueba más sencilla que se puede escribir es llamar a squaresOfOdds con todos los números impares, donde el
resultado sea una secuencia de enteros vacía. Aquí se muestra la prueba:

[<Test>]
member this.TestEvenSequence() =
let expected = Seq.empty<int>
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.That(actual, Is.EqualTo(expected))

Observe que la secuencia expected se convirtió en lista. El marco de NUnit se basa en muchos tipos de .NET
estándar. Esa dependencia significa que la interfaz pública y los resultados esperados admiten ICollection en lugar
de IEnumerable.
Cuando ejecuta la prueba, se observa que no se supera la prueba. Todavía no ha creado la implementación. Haga
que esta prueba se supere escribiendo el código más simple de la clase Library.fs en su proyecto MathService que
funciona:

let squaresOfOdds xs =
Seq.empty<int>

En el directorio unit-testing -with-fsharp, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto MathService y luego del proyecto MathService.Tests . Después de compilar ambos
proyectos, las pruebas se ejecutan. Ahora se superan dos pruebas.

Finalización de los requisitos


Ahora que la prueba se ha superado, es el momento de escribir más. El próximo caso simple funciona con una
secuencia cuyo único número impar es 1 . El número 1 es más simple, porque el cuadrado de 1 es 1. Aquí está la
prueba siguiente:

[<Test>]
member public this.TestOnesAndEvens() =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.That(actual, Is.EqualTo(expected))

Si se ejecuta dotnet test , la prueba nueva se falla. Debe actualizar el método squaresOfOdds para controlar esta
prueba nueva. Debe filtrar todos los números impares y quitarlos de la secuencia para que se supere esta prueba.
Para hacerlo, escriba una función de filtro pequeña y use Seq.filter :

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd

Observe la llamada a Seq.toList . Esa acción crea una lista, que implemente la interfaz ICollection.
Falta un paso todavía: el cuadrado de cada uno de los números impares. Comience escribiendo una prueba nueva:

[<Test>]
member public this.TestSquaresOfOdds() =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.That(actual, Is.EqualTo(expected))

Puede corregir la prueba si canaliza la secuencia filtrada a través de una operación de asignación para calcular el
cuadrado de cada número impar:

let private square x = x * x


let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square

Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.

Vea también
dotnet add reference
dotnet test
Bibliotecas de F# de prueba unitaria en .NET Core
con pruebas de dotnet y MSTest
20/01/2020 • 9 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -with-fsharp que contenga la solución. En este
directorio nuevo, ejecute dotnet new sln para crear una solución nueva. Esto permite facilitar la administración de
la biblioteca de clases y del proyecto de prueba unitaria. En el directorio de la solución, cree un directorio
MathService. Esta es la estructura de directorios y archivos hasta el momento:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService

Convierta MathService en el directorio actual y ejecute dotnet new classlib -lang "F#" para crear el proyecto de
origen. Creará una implementación de errores del servicio de matemáticas:

module MyMath =
let squaresOfOdds xs = raise (System.NotImplementedException("You haven't written a test yet!"))

Cambie nuevamente el directorio al directorio unit-testing -with-fsharp. Ejecute


dotnet sln add .\MathService\MathService.fsproj para agregar el proyecto de biblioteca de clases a la solución.

Crear el proyecto de prueba


A continuación, cree el directorio MathService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests

Convierta el directorio MathService.Tests en el directorio actual y cree un proyecto nuevo con


dotnet new mstest -lang "F#" . Esto crea un proyecto de prueba que usa MSTest como el marco de pruebas. La
plantilla generada configura el ejecutor de pruebas en MathServiceTests.fsproj:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso
anterior agregó MSTest y el ejecutor de MSTest. Ahora, agregue la biblioteca de clases MathService como otra
dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../MathService/MathService.fsproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de solución final siguiente:

/unit-testing-with-fsharp
unit-testing-with-fsharp.sln
/MathService
Source Files
MathService.fsproj
/MathService.Tests
Test Source Files
MathServiceTests.fsproj

Ejecute dotnet sln add .\MathService.Tests\MathService.Tests.fsproj en el directorio unit-testing -with-fsharp.

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Abra Tests.fs y agregue el código
siguiente:

namespace MathService.Tests

open System
open Microsoft.VisualStudio.TestTools.UnitTesting
open MathService

[<TestClass>]
type TestClass () =

[<TestMethod>]
member this.TestMethodPassing() =
Assert.IsTrue(true)

[<TestMethod>]
member this.FailEveryTime() = Assert.IsTrue(false)

El atributo [<TestClass>] indica una clase que contiene pruebas. El atributo [<TestMethod>] indica un método de
prueba que el ejecutor de pruebas ejecuta. En el directorio unit-testing -with-fsharp, ejecute dotnet test para
compilar las pruebas y la biblioteca de clases y luego ejecutar las pruebas. El ejecutor de pruebas de MSTest tiene
el punto de entrada del programa para ejecutar las pruebas desde la consola. dotnet test inicia el ejecutor de
pruebas con el proyecto de prueba unitaria que creó.
Estas dos pruebas muestran las pruebas superadas y con errores más básicas. My test indica que se supera y
Fail every time indica que no. Ahora, cree una prueba para el método squaresOfOdds . El método squaresOfOdds
devuelve una lista de los cuadrados de todos los valores enteros impares que forman parte de la secuencia de
entrada. En lugar de intentar escribir todas esas funciones a la vez, puede crear de forma iterativa pruebas que
validen la funcionalidad. Hacer cada prueba superada significa crear la funcionalidad necesaria para el método.
La prueba más sencilla que se puede escribir es llamar a squaresOfOdds con todos los números impares, donde el
resultado sea una secuencia de enteros vacía. Aquí se muestra la prueba:

[<TestMethod>]
member this.TestEvenSequence() =
let expected = Seq.empty<int> |> Seq.toList
let actual = MyMath.squaresOfOdds [2; 4; 6; 8; 10]
Assert.AreEqual(expected, actual)

Observe que la secuencia expected se convirtió en lista. La biblioteca de MSTest se basa en muchos tipos de .NET
estándar. Esa dependencia significa que la interfaz pública y los resultados esperados admiten ICollection en lugar
de IEnumerable.
Cuando ejecuta la prueba, se observa que no se supera la prueba. Todavía no ha creado la implementación. Cree
esta prueba que se supera escribiendo el código más simple en la clase Mathservice que funciona:

let squaresOfOdds xs =
Seq.empty<int> |> Seq.toList

En el directorio unit-testing -with-fsharp, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto MathService y luego del proyecto MathService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.

Finalización de los requisitos


Ahora que la prueba se ha superado, es el momento de escribir más. El próximo caso simple funciona con una
secuencia cuyo único número impar es 1 . El número 1 es más simple, porque el cuadrado de 1 es 1. Aquí está la
prueba siguiente:

[<TestMethod>]
member public this.TestOnesAndEvens() =
let expected = [1; 1; 1; 1]
let actual = MyMath.squaresOfOdds [2; 1; 4; 1; 6; 1; 8; 1; 10]
Assert.AreEqual(expected, actual)

Si se ejecuta dotnet test , la prueba nueva se falla. Debe actualizar el método squaresOfOdds para controlar esta
prueba nueva. Debe filtrar todos los números impares y quitarlos de la secuencia para que se supere esta prueba.
Para hacerlo, escriba una función de filtro pequeña y use Seq.filter :

let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd |> Seq.toList

Observe la llamada a Seq.toList . Esa acción crea una lista, que implemente la interfaz ICollection.
Falta un paso todavía: el cuadrado de cada uno de los números impares. Comience escribiendo una prueba nueva:
[<TestMethod>]
member public this.TestSquaresOfOdds() =
let expected = [1; 9; 25; 49; 81]
let actual = MyMath.squaresOfOdds [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Assert.AreEqual(expected, actual)

Puede corregir la prueba si canaliza la secuencia filtrada a través de una operación de asignación para calcular el
cuadrado de cada número impar:

let private square x = x * x


let private isOdd x = x % 2 <> 0

let squaresOfOdds xs =
xs
|> Seq.filter isOdd
|> Seq.map square
|> Seq.toList

Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.

Vea también
dotnet new
dotnet sln
dotnet add reference
dotnet test
Bibliotecas de .NET Core de prueba unitaria de
Visual Basic con pruebas de dotnet y xUnit
12/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio denominado unit-testing -vb -using -dotnet-test que contenga la
solución. En este directorio nuevo, ejecute dotnet new sln para crear una solución nueva. Esta práctica permite
facilitar la administración de la biblioteca de clases y del proyecto de prueba unitaria. En el directorio de la
solución, cree un directorio PrimeService. Hasta el momento, esta es la estructura de directorios y archivos:

/unit-testing-using-dotnet-test
unit-testing-using-dotnet-test.sln
/PrimeService

Convierta PrimeService en el directorio actual y ejecute dotnet new classlib -lang VB para crear el proyecto de
origen. Cambie el nombre de Class1.VB a PrimeService.VB. Creará una implementación de errores de la clase
PrimeService :

Namespace Prime.Services
Public Class PrimeService
Public Function IsPrime(candidate As Integer) As Boolean
Throw New NotImplementedException("Please create a test first")
End Function
End Class
End Namespace

Cambie nuevamente el directorio al directorio unit-testing -vb -using -dotnet-test. Ejecute


dotnet sln add .\PrimeService\PrimeService.vbproj para agregar el proyecto de biblioteca de clases a la solución.

Crear el proyecto de prueba


A continuación, cree el directorio PrimeService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-vb-using-dotnet-test
unit-testing-vb-using-dotnet-test.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests
Convierta el directorio PrimeService.Tests en el directorio actual y cree un proyecto nuevo con
dotnet new xunit -lang VB . Este comando crea un proyecto de prueba que usa xUnit como biblioteca de pruebas.
La plantilla generada ha configurado el ejecutor de pruebas en PrimeServiceTests.vbproj:

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso
anterior, agregó xUnit y el ejecutor de xUnit. Ahora, agregue la biblioteca de clases PrimeService como otra
dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.vbproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de carpeta final siguiente:

/unit-testing-using-dotnet-test
unit-testing-using-dotnet-test.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests
Test Source Files
PrimeServiceTests.vbproj

Ejecute dotnet sln add .\PrimeService.Tests\PrimeService.Tests.vbproj en el directorio unit-testing -vb -using -


dotnet-test.

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Quite UnitTest1.vb del directorio
PrimeService.Tests y cree un archivo de Visual Basic nuevo denominado PrimeService_IsPrimeShould.VB. Agregue
el código siguiente:

Imports Xunit

Namespace PrimeService.Tests
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<Fact>
Sub IsPrime_InputIs1_ReturnFalse()
Dim result As Boolean = _primeService.IsPrime(1)

Assert.False(result, "1 should not be prime")


End Sub

End Class
End Namespace

El atributo <Fact> indica un método de prueba que el ejecutor de pruebas ejecuta. En unit-testing -using -dotnet-
test, ejecute dotnet test para compilar las pruebas y la biblioteca de clases y luego ejecutar las pruebas. El
ejecutor de pruebas de xUnit tiene el punto de entrada del programa para ejecutar las pruebas desde la consola.
dotnet test inicia el ejecutor de pruebas con el proyecto de prueba unitaria que creó.
La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase PrimeService que funciona:

Public Function IsPrime(candidate As Integer) As Boolean


If candidate = 1 Then
Return False
End If
Throw New NotImplementedException("Please create a test first.")
End Function

En el directorio unit-testing -vb -using -dotnet-test, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta
una compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests . Después de compilar
ambos proyectos, se ejecuta esta única prueba. Pasa.

Agregar más características


Ahora que la prueba se ha superado, es el momento de escribir más. Hay otros casos simples para números
primos: 0, -1. Puede agregar esos casos como nuevas pruebas con el atributo <Fact> , pero enseguida este
proceso se hace tedioso. Hay otros atributos de xUnit que le permiten escribir un conjunto de pruebas similares.
Un atributo <Theory> representa un conjunto de pruebas que ejecutan el mismo código, pero tienen diferentes
argumentos de entrada. Puede usar el atributo <InlineData> para especificar valores para esas entradas.
En lugar de crear pruebas nuevas, aplique estos dos atributos para crear una sola teoría. La teoría es un método
que prueba varios valores menores que dos, que es el número primo menor:
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<Theory>
<InlineData(-1)>
<InlineData(0)>
<InlineData(1)>
Sub IsPrime_ValueLessThan2_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.False(result, $"{value} should not be prime")


End Sub

<Theory>
<InlineData(2)>
<InlineData(3)>
<InlineData(5)>
<InlineData(7)>
Public Sub IsPrime_PrimesLessThan10_ReturnTrue(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.True(result, $"{value} should be prime")


End Sub

<Theory>
<InlineData(4)>
<InlineData(6)>
<InlineData(8)>
<InlineData(9)>
Public Sub IsPrime_NonPrimesLessThan10_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.False(result, $"{value} should not be prime")


End Sub
End Class

Ejecute dotnet test , y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula
if al principio del método:

if candidate < 2

Puede continuar recorriendo en iteración agregando más pruebas, más teorías y más código en la biblioteca
principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.
Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.
Bibliotecas de .NET Core de prueba unitaria de
Visual Basic con pruebas de dotnet y NUnit
12/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Requisitos previos
SDK de .NET Core 2.1 o versiones posteriores.
Un editor de texto o un editor de código de su elección.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -vb -nunit que contenga la solución. En este
directorio nuevo, ejecute el comando siguiente para crear un archivo de solución nuevo para la biblioteca de clases
y el proyecto de prueba:

dotnet new sln

A continuación, cree un directorio PrimeService. En el esquema siguiente se muestra la estructura de archivos


hasta el momento:

/unit-testing-vb-nunit
unit-testing-vb-nunit.sln
/PrimeService

Convierta PrimeService en el directorio actual y ejecute el siguiente comando para crear el proyecto de origen:

dotnet new classlib -lang VB

Cambie el nombre de Class1.VB a PrimeService.VB. Creará una implementación de errores de la clase


PrimeService :

Namespace Prime.Services
Public Class PrimeService
Public Function IsPrime(candidate As Integer) As Boolean
Throw New NotImplementedException("Please create a test first.")
End Function
End Class
End Namespace

Cambien nuevamente el directorio al directorio unit-testing -vb -using -mstest. Ejecute el siguiente comando para
agregar el proyecto de biblioteca de clases a la solución:
dotnet sln add .\PrimeService\PrimeService.vbproj

Crear el proyecto de prueba


A continuación, cree el directorio PrimeService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-vb-nunit
unit-testing-vb-nunit.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests

Convierta el directorio PrimeService.Tests en el directorio actual y cree un proyecto nuevo con el comando
siguiente:

dotnet new nunit -lang VB

El comando dotnet new crea un proyecto de prueba que usa NUnit como la biblioteca de pruebas. La plantilla
generada ha configurado el ejecutor de pruebas en el archivo PrimeServiceTests.vbproj:

<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. En el paso anterior,
dotnet new agrega NUnit y el adaptador de prueba NUnit. Ahora, agregue la biblioteca de clases PrimeService
como otra dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.vbproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de solución final siguiente:

/unit-testing-vb-nunit
unit-testing-vb-nunit.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests
Test Source Files
PrimeService.Tests.vbproj

Ejecute el comando siguiente en el directorio unit-testing -vb -nunit:

dotnet sln add .\PrimeService.Tests\PrimeService.Tests.vbproj

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. En el directorio PrimeService.Tests,
cambie el nombre del archivo UnitTest1.vb por PrimeService_IsPrimeShould.VB y reemplace todo su contenido
por el código siguiente:

Imports NUnit.Framework

Namespace PrimeService.Tests
<TestFixture>
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<Test>
Sub IsPrime_InputIs1_ReturnFalse()
Dim result As Boolean = _primeService.IsPrime(1)

Assert.False(result, "1 should not be prime")


End Sub

End Class
End Namespace

El atributo <TestFixture> indica una clase que contiene pruebas. El atributo <Test> indica un método que el
ejecutor de pruebas ejecuta. En unit-testing -vb -nunit, ejecute dotnet test para compilar las pruebas y la
biblioteca de clases y luego ejecutar las pruebas. El ejecutor de pruebas de NUnit tiene el punto de entrada del
programa para ejecutar las pruebas desde la consola. dotnet test inicia el ejecutor de pruebas con el proyecto de
prueba unitaria que creó.
La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase PrimeService que funciona:

Public Function IsPrime(candidate As Integer) As Boolean


If candidate = 1 Then
Return False
End If
Throw New NotImplementedException("Please create a test first.")
End Function

En el directorio unit-testing -vb -nunit, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.

Agregar más características


Ahora que la prueba se ha superado, es el momento de escribir más. Hay otros casos simples para números
primos: 0, -1. Puede agregar esos casos como nuevas pruebas con el atributo <Test> , pero enseguida este
proceso se hace tedioso. Hay otros atributos de xUnit que le permiten escribir un conjunto de pruebas similares.
Un atributo <TestCase> representa un conjunto de pruebas que ejecutan el mismo código, pero tienen diferentes
argumentos de entrada. Puede usar el atributo <TestCase> para especificar valores para esas entradas.
En lugar de crear pruebas, aplique estos dos atributos para crear un conjunto de pruebas que pruebe algunos
valores inferiores a 2, que es el número primo más bajo:
<TestFixture>
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<TestCase(-1)>
<TestCase(0)>
<TestCase(1)>
Sub IsPrime_ValuesLessThan2_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsFalse(result, $"{value} should not be prime")


End Sub

<TestCase(2)>
<TestCase(3)>
<TestCase(5)>
<TestCase(7)>
Public Sub IsPrime_PrimesLessThan10_ReturnTrue(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsTrue(result, $"{value} should be prime")


End Sub

<TestCase(4)>
<TestCase(6)>
<TestCase(8)>
<TestCase(9)>
Public Sub IsPrime_NonPrimesLessThan10_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsFalse(result, $"{value} should not be prime")


End Sub
End Class

Ejecute dotnet test , y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula
if al principio del método Main en el archivo PrimeService.cs:

if candidate < 2

Puede continuar recorriendo en iteración agregando más pruebas, más teorías y más código en la biblioteca
principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.
Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.
Bibliotecas de .NET Core de prueba unitaria de
Visual Basic con pruebas de dotnet y MSTest
12/01/2020 • 8 minutes to read • Edit Online

Este tutorial le guía por una experiencia interactiva de creación de una solución de ejemplo paso a paso para
aprender los conceptos de pruebas unitarias. Si prefiere seguir el tutorial con una solución precompilada, vea o
descargue el código de ejemplo antes de comenzar. Para obtener instrucciones de descarga, vea Ejemplos y
tutoriales.
Este artículo trata sobre la prueba de un proyecto de .NET Core. Si está realizando pruebas con un proyecto de
ASP.NET Core, consulte Pruebas de integración en ASP.NET Core.

Crear el proyecto de origen


Abra una ventana del Shell. Cree un directorio llamado unit-testing -vb -mstest que contenga la solución. En este
directorio nuevo, ejecute dotnet new sln para crear una solución nueva. Esta práctica permite facilitar la
administración de la biblioteca de clases y del proyecto de prueba unitaria. En el directorio de la solución, cree un
directorio PrimeService. Hasta el momento, esta es la estructura de directorios y archivos:

/unit-testing-vb-mstest
unit-testing-vb-mstest.sln
/PrimeService

Convierta PrimeService en el directorio actual y ejecute dotnet new classlib -lang VB para crear el proyecto de
origen. Cambie el nombre de Class1.VB a PrimeService.VB. Creará una implementación de errores de la clase
PrimeService :

Namespace Prime.Services
Public Class PrimeService
Public Function IsPrime(candidate As Integer) As Boolean
Throw New NotImplementedException("Please create a test first")
End Function
End Class
End Namespace

Cambien nuevamente el directorio al directorio unit-testing -vb -using -mstest. Ejecute


dotnet sln add .\PrimeService\PrimeService.vbproj para agregar el proyecto de biblioteca de clases a la solución.

Crear el proyecto de prueba


A continuación, cree el directorio PrimeService.Tests. En el esquema siguiente se muestra la estructura de
directorios:

/unit-testing-vb-mstest
unit-testing-vb-mstest.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests
Convierta el directorio PrimeService.Tests en el directorio actual y cree un proyecto nuevo con
dotnet new mstest -lang VB . Este comando crea un proyecto de prueba que usa MSTest como biblioteca de
pruebas. La plantilla generada ha configurado el ejecutor de pruebas en PrimeServiceTests.vbproj:

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</ItemGroup>

El proyecto de prueba requiere otros paquetes para crear y ejecutar pruebas unitarias. dotnet new en el paso
anterior agregó MSTest y el ejecutor de MSTest. Ahora, agregue la biblioteca de clases PrimeService como otra
dependencia al proyecto. Use el comando dotnet add reference :

dotnet add reference ../PrimeService/PrimeService.vbproj

Puede ver todo el archivo en el repositorio de muestras en GitHub.


Tiene el diseño de solución final siguiente:

/unit-testing-vb-mstest
unit-testing-vb-mstest.sln
/PrimeService
Source Files
PrimeService.vbproj
/PrimeService.Tests
Test Source Files
PrimeServiceTests.vbproj

Ejecute dotnet sln add .\PrimeService.Tests\PrimeService.Tests.vbproj en el directorio unit-testing -vb -mstest.

Crear la primera prueba


Escribirá una prueba de errores, la aprobará y, luego, repetirá el proceso. Quite UnitTest1.vb del directorio
PrimeService.Tests y cree un archivo de Visual Basic nuevo denominado PrimeService_IsPrimeShould.VB. Agregue
el código siguiente:

Imports Microsoft.VisualStudio.TestTools.UnitTesting

Namespace PrimeService.Tests
<TestClass>
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<TestMethod>
Sub IsPrime_InputIs1_ReturnFalse()
Dim result As Boolean = _primeService.IsPrime(1)

Assert.IsFalse(result, "1 should not be prime")


End Sub

End Class
End Namespace

El atributo <TestClass> indica una clase que contiene pruebas. El atributo <TestMethod> indica un método que el
ejecutor de pruebas ejecuta. En unit-testing -vb -mstest, ejecute dotnet test para compilar las pruebas y la
biblioteca de clases y luego ejecutar las pruebas. El ejecutor de pruebas de MSTest tiene el punto de entrada del
programa para ejecutar las pruebas desde la consola. dotnet test inicia el ejecutor de pruebas con el proyecto de
prueba unitaria que creó.
La prueba produce un error. Todavía no ha creado la implementación. Cree esta prueba que se supera escribiendo
el código más simple en la clase PrimeService que funciona:

Public Function IsPrime(candidate As Integer) As Boolean


If candidate = 1 Then
Return False
End If
Throw New NotImplementedException("Please create a test first.")
End Function

En el directorio unit-testing -vb -mstest, vuelva a ejecutar dotnet test . El comando dotnet test ejecuta una
compilación del proyecto PrimeService y luego del proyecto PrimeService.Tests . Después de compilar ambos
proyectos, se ejecuta esta única prueba. Pasa.

Agregar más características


Ahora que la prueba se ha superado, es el momento de escribir más. Hay otros casos simples para números
primos: 0, -1. Puede agregar esos casos como nuevas pruebas con el atributo <TestMethod> , pero enseguida este
proceso se hace tedioso. Hay otros atributos de MSTest que le permiten escribir un conjunto de pruebas similares.
Un atributo <DataTestMethod> representa un conjunto de pruebas que ejecutan el mismo código, pero tienen
diferentes argumentos de entrada. Puede usar el atributo <DataRow> para especificar valores para esas entradas.
En lugar de crear pruebas nuevas, aplique estos dos atributos para crear una sola teoría. La teoría es un método
que prueba varios valores menores que dos, que es el número primo menor:
<TestClass>
Public Class PrimeService_IsPrimeShould
Private _primeService As Prime.Services.PrimeService = New Prime.Services.PrimeService()

<DataTestMethod>
<DataRow(-1)>
<DataRow(0)>
<DataRow(1)>
Sub IsPrime_ValuesLessThan2_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsFalse(result, $"{value} should not be prime")


End Sub

<DataTestMethod>
<DataRow(2)>
<DataRow(3)>
<DataRow(5)>
<DataRow(7)>
Public Sub IsPrime_PrimesLessThan10_ReturnTrue(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsTrue(result, $"{value} should be prime")


End Sub

<DataTestMethod>
<DataRow(4)>
<DataRow(6)>
<DataRow(8)>
<DataRow(9)>
Public Sub IsPrime_NonPrimesLessThan10_ReturnFalse(value As Integer)
Dim result As Boolean = _primeService.IsPrime(value)

Assert.IsFalse(result, $"{value} should not be prime")


End Sub
End Class

Ejecute dotnet test , y dos de estas pruebas no se superarán. Para superar todas las pruebas, cambie la cláusula
if al principio del método:

if candidate < 2

Puede continuar recorriendo en iteración agregando más pruebas, más teorías y más código en la biblioteca
principal. Ya tiene la versión terminada de las pruebas y la implementación completa de la biblioteca.
Ha creado una biblioteca pequeña y un conjunto de pruebas unitarias para esa biblioteca. Ha estructurado la
solución, por lo que agregar pruebas y paquetes nuevos es parte del flujo de trabajo normal. Ha centrado la mayor
parte del tiempo y del esfuerzo en resolver los objetivos de la aplicación.
Ejecución de pruebas unitarias selectivas
20/01/2020 • 4 minutes to read • Edit Online

Con el comando dotnet test en .NET Core, se puede usar una expresión de filtro para ejecutar pruebas
selectivas. En este artículo se muestra cómo filtrar qué pruebas se ejecutan. En los siguientes ejemplos, se utiliza
dotnet test . Si está usando vstest.console.exe , reemplace --filter por --testcasefilter: .

MSTest
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MSTestNamespace
{
[TestClass]
public class UnitTest1
{
[TestCategory("CategoryA")]
[Priority(1)]
[TestMethod]
public void TestMethod1()
{
}

[Priority(2)]
[TestMethod]
public void TestMethod2()
{
}
}
}

EXPRESIÓN RESULTADO

dotnet test --filter Method Ejecuta pruebas cuyo FullyQualifiedName contenga


Method . Disponible en vstest 15.1+ .

dotnet test --filter Name~TestMethod1 Ejecuta pruebas cuyo nombre contenga TestMethod1 .

dotnet test --filter Ejecuta pruebas que están en la clase


ClassName=MSTestNamespace.UnitTest1 MSTestNamespace.UnitTest1 .
Nota: El valor ClassName debe tener un espacio de
nombres, por lo que ClassName=UnitTest1 no funcionará.

dotnet test --filter Ejecuta todas las pruebas excepto


FullyQualifiedName!=MSTestNamespace.UnitTest1.TestMethod1 MSTestNamespace.UnitTest1.TestMethod1 .

dotnet test --filter TestCategory=CategoryA Ejecuta pruebas anotadas con


[TestCategory("CategoryA")] .

dotnet test --filter Priority=2 Ejecuta pruebas anotadas con [Priority(2)] .

Usar operadores condicionales | y &


EXPRESIÓN RESULTADO

dotnet test --filter Ejecuta pruebas que tienen UnitTest1 en


"FullyQualifiedName~UnitTest1|TestCategory=CategoryA" FullyQualifiedName o en las que TestCategory es
CategoryA .

dotnet test --filter Ejecuta pruebas que tienen UnitTest1 en


"FullyQualifiedName~UnitTest1&TestCategory=CategoryA" FullyQualifiedName y en las que TestCategory es
CategoryA .

dotnet test --filter " Ejecuta pruebas que tienen FullyQualifiedName con
(FullyQualifiedName~UnitTest1&TestCategory=CategoryA)|Priority=1"
UnitTest1 y en las que TestCategory es CategoryA o
en las que Priority es 1.

xUnit
using Xunit;

namespace XUnitNamespace
{
public class TestClass1
{
[Trait("Category", "CategoryA")]
[Trait("Priority", "1")]
[Fact]
public void Test1()
{
}

[Trait("Priority", "2")]
[Fact]
public void Test2()
{
}
}
}

EXPRESIÓN RESULTADO

dotnet test --filter Ejecuta solo una prueba,


DisplayName=XUnitNamespace.TestClass1.Test1 XUnitNamespace.TestClass1.Test1 .

dotnet test --filter Ejecuta todas las pruebas excepto


FullyQualifiedName!=XUnitNamespace.TestClass1.Test1 XUnitNamespace.TestClass1.Test1 .

dotnet test --filter DisplayName~TestClass1 Ejecuta pruebas cuyo nombre para mostrar contenga
TestClass1 .

En el ejemplo de código, los rasgos definidos con claves Category y Priority pueden usarse para filtrar.

EXPRESIÓN RESULTADO

dotnet test --filter XUnit Ejecuta pruebas cuyo FullyQualifiedName contenga


XUnit . Disponible en vstest 15.1+ .
EXPRESIÓN RESULTADO

dotnet test --filter Category=CategoryA Ejecuta las pruebas que tienen


[Trait("Category", "CategoryA")] .

Usar operadores condicionales | y &

EXPRESIÓN RESULTADO

dotnet test --filter Ejecuta pruebas que tienen TestClass1 en


"FullyQualifiedName~TestClass1|Category=CategoryA"
FullyQualifiedName o en las que Category es
CategoryA .

dotnet test --filter Ejecuta pruebas que tienen TestClass1 en


"FullyQualifiedName~TestClass1&Category=CategoryA" FullyQualifiedName y en las que Category es
CategoryA .

dotnet test --filter " Ejecuta pruebas que tienen FullyQualifiedName con
(FullyQualifiedName~TestClass1&Category=CategoryA)|Priority=1"
TestClass1 y en las que Category es CategoryA o en
las que Priority es 1.

NUnit
using NUnit.Framework;

namespace NUnitNamespace
{
public class UnitTest1
{
[Category("CategoryA")]
[Property("Priority", 1)]
[Test]
public void TestMethod1()
{
}

[Property("Priority", 2)]
[Test]
public void TestMethod2()
{
}
}
}

EXPRESIÓN RESULTADO

dotnet test --filter Method Ejecuta pruebas cuyo FullyQualifiedName contenga


Method . Disponible en vstest 15.1+ .

dotnet test --filter Name~TestMethod1 Ejecuta pruebas cuyo nombre contenga TestMethod1 .

dotnet test --filter Ejecuta pruebas que están en la clase


FullyQualifiedName~NUnitNamespace.UnitTest1 NUnitNamespace.UnitTest1 .

dotnet test --filter Ejecuta todas las pruebas excepto


FullyQualifiedName!=NUnitNamespace.UnitTest1.TestMethod1 NUnitNamespace.UnitTest1.TestMethod1 .
EXPRESIÓN RESULTADO

dotnet test --filter TestCategory=CategoryA Ejecuta pruebas anotadas con [Category("CategoryA")] .

dotnet test --filter Priority=2 Ejecuta pruebas anotadas con [Priority(2)] .

Usar operadores condicionales | y &

EXPRESIÓN RESULTADO

dotnet test --filter Ejecuta pruebas que tienen UnitTest1 en


"FullyQualifiedName~UnitTest1|TestCategory=CategoryA" FullyQualifiedName o en las que TestCategory es
CategoryA .

dotnet test --filter Ejecuta pruebas que tienen UnitTest1 en


"FullyQualifiedName~UnitTest1&TestCategory=CategoryA"
FullyQualifiedName y en las que TestCategory es
CategoryA .

dotnet test --filter " Ejecuta pruebas que tienen FullyQualifiedName con
(FullyQualifiedName~UnitTest1&TestCategory=CategoryA)|Priority=1"
UnitTest1 y en las que TestCategory es CategoryA o
en las que Priority es 1.
Prueba de la salida publicada con vstest dotnet
12/01/2020 • 2 minutes to read • Edit Online

Puede ejecutar pruebas en la salida ya publicada mediante el comando dotnet vstest . Esto funcionará en pruebas
de xUnit, MSTest y NUnit. Simplemente busque el archivo DLL que formaba parte de la salida publicada y ejecute:

dotnet vstest <MyPublishedTests>.dll

donde <MyPublishedTests> es el nombre del proyecto de prueba publicado.

Ejemplo
Los comandos siguientes muestran la ejecución de pruebas en un archivo DLL publicado.

dotnet new mstest -o MyProject.Tests


cd MyProject.Tests
dotnet publish -o out
dotnet vstest out/MyProject.Tests.dll

NOTE
Nota: Si la aplicación tiene como destino un marco distinto de netcoreapp , todavía puede ejecutar el comando
dotnet vstest si se pasa el marco de destino con una marca de marco. Por ejemplo:
dotnet vstest <MyPublishedTests>.dll --Framework:".NETFramework,Version=v4.6" . En Visual Studio 2017 Update 5 y
versiones posteriores, se detecta automáticamente el marco deseado.

Vea también
Pruebas unitarias con pruebas de dotnet y xUnit
Prueba unitaria de C# con NUnit y .NET Core
Pruebas unitarias con pruebas de dotnet y MSTest
Uso de .NET Core SDK y herramientas de integración
continua (CI)
20/01/2020 • 16 minutes to read • Edit Online

En este documento se describe el uso del SDK de .NET Core y sus herramientas en un servidor de compilación. El
conjunto de herramientas de .NET Core funciona tanto de forma interactiva, donde un desarrollador escribe
comandos en un símbolo del sistema, como de manera automática, donde un servidor de integración continua
(CI) ejecuta un script de compilación. Los comandos, las opciones, las entradas y las salidas son los mismos, y solo
lo que el usuario especifica sirve para adquirir las herramientas y un sistema para compilar la aplicación. Este
documento se centra en escenarios de adquisición de herramientas de integración continua, donde además se
ofrecen recomendaciones sobre cómo diseñar y estructurar los scripts de compilación.

Opciones de instalación para los servidores de compilación de CI


Uso de instaladores nativos
Los instaladores nativos están disponibles para macOS, Linux y Windows. Los instaladores requieren acceso de
administrador (sudo) para el servidor de compilación. El instalador nativo ofrece la ventaja de que instala todas las
dependencias nativas necesarias para la ejecución de las herramientas. Además, los instaladores nativos instalan el
SDK en todo el sistema.
Los usuarios de macOS deben usar los instaladores PKG. En Linux, se ofrece la posibilidad de usar un
administrador de paquetes basado en fuentes, como apt-get para Ubuntu o yum para CentOS, o de usar los
mismos paquetes (DEB o RPM ). En Windows, utilice el instalador MSI.
Los archivos binarios estables más recientes se encuentran en Descargas de .NET. Si desea utilizar las
herramientas de la última versión preliminar, que posiblemente sean inestables, use los vínculos proporcionados
en el repositorio de GitHub dotnet/core-sdk. Para las distribuciones de Linux, se encuentran disponibles los
archivos tar.gz (conocidos también como tarballs ); use los scripts de instalación dentro de los archivos para
instalar .NET Core.
Uso del script del instalador
El uso del script del instalador permite la instalación sin derechos administrativos en el servidor de compilación y
una sencilla automatización para obtener las herramientas. El script se encarga de descargar las herramientas y
extraerlas en una ubicación predeterminada o especificada para su uso. También puede especificar la versión de las
herramientas que desea instalar y si prefiere instalar el SDK completo o solo el runtime compartido.
El script del instalador se puede automatizar para que se ejecute al principio de la compilación, a fin de obtener e
instalar la versión deseada del SDK. La versión deseada se corresponde con cualquier versión del SKD que los
proyectos necesitan para la compilación. El script permite instalar el SDK en un directorio local del servidor,
ejecutar las herramientas desde la ubicación de instalación y limpiar después de la compilación, o bien dejar que el
servicio de CI realice dicha limpieza. Esto permite encapsular y aislar todo el proceso de compilación. La referencia
del script de instalación se encuentra en el artículo dotnet-install.

NOTE
Azure DevOps Services
Cuando se utiliza el script del instalador, las dependencias nativas no se instalan automáticamente. Debe instalarlas en caso
de el sistema operativo no las incluya. Para obtener más información, vea Dependencias y requisitos de .NET Core.
Ejemplos de configuración de CI
En esta sección se explica un procedimiento de instalación manual con un script de PowerShell o de Bash, además
de incluir una descripción de varias soluciones de CI de software como servicio (SaaS ). Las soluciones de CI de
SaaS tratadas son Travis CI, AppVeyor y Azure Pipelines.
Instalación manual
Cada servicio de SaaS tiene sus propios métodos para crear y configurar un proceso de compilación. Si usa una
solución de SaaS distinta a las que indican o necesita realizar alguna personalización aparte de la compatibilidad
preconfigurada, debe realizar al menos alguna configuración manual.
En general, para realizar una instalación manual, es necesario que adquiera una versión de las herramientas o las
últimas compilaciones nocturnas de las herramientas y que, después, ejecute el script de compilación. Puede usar
un script de PowerShell o de Bash para orquestar los comandos de .NET Core o utilizar un archivo del proyecto en
el que se describa el proceso de compilación. En la sección de orquestación se ofrece más información sobre estas
opciones.
Después de crear un script que realiza una instalación manual del servidor de compilación de CI, úselo en el
equipo de desarrollo para compilar el código de forma local con fines de pruebas. Cuando confirme que el script
se ejecuta de forma correcta en el entorno local, impleméntelo en el servidor de compilación de CI. Un script de
PowerShell relativamente sencillo demuestra cómo obtener el SDK de NET Core e instalarlo en un servidor de
compilación de Windows:
$ErrorActionPreference="Stop"
$ProgressPreference="SilentlyContinue"

# $LocalDotnet is the path to the locally-installed SDK to ensure the


# correct version of the tools are executed.
$LocalDotnet=""
# $InstallDir and $CliVersion variables can come from options to the
# script.
$InstallDir = "./cli-tools"
$CliVersion = "1.0.1"

# Test the path provided by $InstallDir to confirm it exists. If it


# does, it's removed. This is not strictly required, but it's a
# good way to reset the environment.
if (Test-Path $InstallDir)
{
rm -Recurse $InstallDir
}
New-Item -Type "directory" -Path $InstallDir

Write-Host "Downloading the CLI installer..."

# Use the Invoke-WebRequest PowerShell cmdlet to obtain the


# installation script and save it into the installation directory.
Invoke-WebRequest `
-Uri "https://dot.net/v1/dotnet-install.ps1" `
-OutFile "$InstallDir/dotnet-install.ps1"

Write-Host "Installing the CLI requested version ($CliVersion) ..."

# Install the SDK of the version specified in $CliVersion into the


# specified location ($InstallDir).
& $InstallDir/dotnet-install.ps1 -Version $CliVersion `
-InstallDir $InstallDir

Write-Host "Downloading and installation of the SDK is complete."

# $LocalDotnet holds the path to dotnet.exe for future use by the


# script.
$LocalDotnet = "$InstallDir/dotnet"

# Run the build process now. Implement your build script here.

Debe proporcionar la implementación para el proceso de compilación al final del script. El script adquiere las
herramientas y, después, ejecuta el proceso de compilación. En los equipos UNIX, el siguiente script de Bash
realiza las acciones descritas en el script de PowerShell de forma similar:
#!/bin/bash
INSTALLDIR="cli-tools"
CLI_VERSION=1.0.1
DOWNLOADER=$(which curl)
if [ -d "$INSTALLDIR" ]
then
rm -rf "$INSTALLDIR"
fi
mkdir -p "$INSTALLDIR"
echo Downloading the CLI installer.
$DOWNLOADER https://dot.net/v1/dotnet-install.sh > "$INSTALLDIR/dotnet-install.sh"
chmod +x "$INSTALLDIR/dotnet-install.sh"
echo Installing the CLI requested version $CLI_VERSION. Please wait, installation may take a few minutes.
"$INSTALLDIR/dotnet-install.sh" --install-dir "$INSTALLDIR" --version $CLI_VERSION
if [ $? -ne 0 ]
then
echo Download of $CLI_VERSION version of the CLI failed. Exiting now.
exit 0
fi
echo The CLI has been installed.
LOCALDOTNET="$INSTALLDIR/dotnet"
# Run the build process now. Implement your build script here.

Travis CI
Puede configurar Travis CI para instalar el SDK de .NET Core con el lenguaje csharp y la clave dotnet . Para más
información, consulte los documentos oficiales de Travis CI en Building a C#, F#, or Visual Basic Project
(Compilación de un proyecto de C#, F# o Visual Basic). Al acceder a la información de Travis CI, observará que el
identificador de lenguaje language: csharp de cuyo mantenimiento se encarga la comunidad funciona con todos
los lenguajes de .NET, incluidos F# y Mono.
Travis CI se ejecuta tanto en trabajos de macOS como de Linux en una matriz de compilación, donde debe
especificar una combinación de runtime, entorno y exclusiones/inclusiones para aceptar las combinaciones de
compilación de la aplicación. Para más información, vea el artículo Customizing the Build (Personalización de la
compilación) en la documentación de Travis CI. Las herramientas basadas en MSBuild incluyen los runtimes LTS
(1.0.x) y Current (1.1.x) en el paquete; por tanto, cuando instala el SDK, recibe todo lo que necesita para la
compilación.
AppVeyor
AppVeyor instala el SDK de .NET Core 1.0.1 con la imagen de trabajo de compilación de Visual Studio 2017 . Hay
disponibles otras imágenes de compilación con distintas versiones del SDK de .NET Core. Para más información,
consulte el ejemplo appveyor.yml y el artículo Build worker images (Imágenes de trabajo de compilación) en los
documentos de AppVeyor.
Los archivos binarios del SDK de .NET Core se descargan y descomprimen en un subdirectorio con la utilización
del script de instalación y, después, se agregan a la variable de entorno PATH . Agregue una matriz de compilación
para ejecutar las pruebas de integración con varias versiones del SDK de .NET Core:

environment:
matrix:
- CLI_VERSION: 1.0.1
- CLI_VERSION: Latest

install:
# See appveyor.yml example for install script

Azure DevOps Services


Configure Azure DevOps Services para compilar proyectos de .NET Core con alguno de estos enfoques:
1. Ejecute el script del paso de instalación manual con sus comandos.
2. Cree una compilación compuesta de varias tareas de compilación integradas en Azure DevOps Services que
están configuradas para usar herramientas de .NET Core.
Ambas soluciones son válidas. Con la utilización de un script de instalación manual, puede controlar la versión de
las herramientas que recibe, ya que las descarga como parte de la compilación. La compilación se ejecuta desde un
script que debe crear. En este artículo solo se trata la opción manual. Para más información sobre cómo elaborar
una compilación con las tareas de compilación de Azure DevOps Services, consulte la documentación de Azure
Pipelines.
Para usar un script de instalación manual en Azure DevOps Services, cree una definición de compilación y
especifique el script que va a ejecutar para el paso de compilación. Esto se realiza en la interfaz de usuario de
Azure DevOps Services:
1. Empiece por crear una definición de compilación. Cuando llegue a la pantalla en la que se ofrece la opción
de definir el tipo de compilación que desea crear, seleccione la opción Vacío.

2. Después de configurar el repositorio que va a compilar, se le remite a las definiciones de compilación.


Seleccione Agregar paso de compilación:
3. Se abre el Catálogo de tareas. El catálogo contiene tareas que se utilizan en la compilación. Como ya tiene
un script, haga clic en el botón Agregar en PowerShell: Ejecute un script de PowerShell.

4. Configure el paso de compilación. Agregue el script desde el repositorio que se va a compilar:

Orquestación de la compilación
En la mayor parte de este documento se describe cómo adquirir las herramientas de .NET Core y configurar varios
servicios de CI sin ofrecer información sobre cómo orquestar o compilar realmente el código con .NET Core. Las
opciones para estructurar el proceso de compilación dependen de muchos factores que no se pueden tratar aquí
en términos generales. Para más información sobre cómo orquestar las compilaciones con cada tecnología,
explore los recursos y los ejemplos que se proporciona en los conjuntos de documentación de Travis CI, AppVeyor
y Azure Pipelines.
Dos enfoques generales que se aplican para estructurar el proceso de compilación del código de .NET Core con
herramientas de .NET Core consisten en utilizar directamente MSBuild o en usar los comandos de la línea de
comandos de .NET Core. El enfoque que debe adoptar depende de lo cómo que se sienta con cada uno de ellos y
de los inconvenientes que presente su complejidad. MSBuild ofrece la posibilidad de expresar el proceso de
compilación como tareas y objetivos, pero presenta la complejidad añadida de tener que aprender la sintaxis del
archivo de proyecto de MSBuild. Quizá sea más sencillo usar las herramientas de línea de comandos de .NET
Core, pero, en este caso, es necesario escribir la lógica de orquestación en un lenguaje de scripting como bash o
PowerShell.

Vea también
Descargas de .NET: Linux
Introducción a la creación de versiones de .NET Core
10/01/2020 • 10 minutes to read • Edit Online

.NET Core se refiere al runtime y el SDK de .NET Core, que contiene las herramientas que necesita para
desarrollar aplicaciones. Los SDK de .NET Core están diseñados para funcionar con cualquier versión anteriores
del runtime de .NET Core. En este artículo se explican el runtime y la estrategia de la versión del SDK. En el
artículo .NET Standard se ofrece una explicación de los números de versión de .NET Standard.
El runtime y el SDK de .NET Core agregan características a un ritmo diferente; en general, el SDK de .NET Core
incluye herramientas actualizadas antes de que el runtime de .NET Core cambie el runtime que se usa en
producción.

Detalles de control de versiones


".NET Core 2.1" se refiere al número de versión del runtime de .NET Core. El runtime de .NET Core sigue el
esquema de control de versiones "principal/secundaria/revisón", que se basa en el control de versiones semántico.
El SDK de .NET Core no sigue el esquema de control de versiones semántico. El SDK de .NET Core se publica con
mayor rapidez, y sus versiones deben comunicar tanto el runtime alineado como la versión secundaria y las
publicaciones de revisiones del propio SDK. Las dos primeras posiciones de la versión del SDK de .NET Core
siempre reflejan el runtime de .NET Core con el que se publicó. Cada versión del SDK puede crear aplicaciones
tanto para este runtime como para cualquier versión anterior.
La tercera posición del número de versión del SDK comunica tanto la versión secundaria como el número de
revisión. La versión secundaria se multiplica por 100. La versión secundaria 1 y la revisión 2 se representan con
102. Los dos dígitos finales representan el número de revisión. Por ejemplo, la versión de .NET Core 2.2 puede
crear versiones como en la tabla siguiente:

CAMBIO RUNTIME DE .NET CORE SDK DE .NET CORE (*)

Versión inicial 2.2.0 2.2.100

Revisión del SDK 2.2.0 2.2.101

Runtime y revisión del SDK 2.2.1 2.2.102

Cambio de características del SDK 2.2.1 2.2.200

(*) En este gráfico se usa el entorno de ejecución 2.2 de .NET Core como ejemplo, ya que un artefacto histórico
indica que el primer SDK de .NET Core 2.1 es el de la versión 2.1.300. Para obtener más información, consulte
.Selección de la versión de .NET Core.
NOTAS:
Si el SDK tiene 10 actualizaciones de características anteriores a la actualización de una de las características
del runtime, los números de versión progresarán en la serie de 1000 con números como 2.2.1000, tal como la
publicación de características posterior a la versión 2.2.900. No se espera que esta situación llegue a
producirse.
Nunca se publicarán 99 versiones sin publicar ninguna característica. Si una versión se acercase a este número,
se forzaría una publicación de características.
Puede ver más detalles en la propuesta inicial, que forma parte del repositorio dotnet/designs.

Control de versiones semántico


En cierto modo, el runtime de .NET Core sigue el Versionamiento Semántico (SemVer), que adopta el uso del
esquema de control de versiones MAJOR.MINOR.PATCH y emplea las distintas partes del número de versión para
describir el grado y el tipo de cambio.

MAJOR.MINOR.PATCH[-PRERELEASE-BUILDNUMBER]

Los elementos opcionales PRERELEASE y BUILDNUMBER nunca forman parte de las versiones compatibles y solo
están presentes en las compilaciones nocturnas, en las compilaciones locales a partir de destinos de origen y en
las versiones preliminares no compatibles.
Comprender los cambios en el número de versión del runtime
MAJOR se incrementa cuando:

Se producen cambios importantes en el producto, o bien este toma una nueva dirección.
Se han realizado cambios importantes. Hay un nivel de aceptación de cambios importantes elevado.
Ya no se admite una versión antigua.
Se adopta una versión MAJOR más reciente de una dependencia existente.

MINOR se incrementa cuando:


Se agrega un área expuesta de API pública.
Se agrega un nuevo comportamiento.
Se adopta una versión MINOR más reciente de una dependencia existente.
Se presenta una nueva dependencia.
PATCH se incrementa cuando:
Se realizan correcciones de errores.
Se agrega compatibilidad con una plataforma más reciente.
Se adopta una versión PATCH más reciente de una dependencia existente.
Cualquier otro cambio no se ajusta a uno de los casos anteriores.
Cuando hay varios cambios, se incrementa el elemento superior afectado por cambios individuales, mientras que
los siguientes se restablecen a cero. Por ejemplo, cuando se incrementa MAJOR , MINOR y PATCH se restablecen a
cero. Cuando se incrementa MINOR , PATCH se restablece a cero mientras que MAJOR no se modifica.

Números de versión en los nombres de archivo


Los archivos descargados para .NET Core indican la versión; por ejemplo, dotnet-sdk-2.1.300-win10-x64.exe .
Versiones preliminares
Las versiones preliminares tienen un elemento -preview[number]-([build]|"final") anexado a la versión. Por
ejemplo: 2.0.0-preview1-final .
Versiones de mantenimiento
Cuando se lanza una versión, las ramas de la versión generalmente dejan de producir compilaciones diarias y, en
su lugar, empiezan a generar compilaciones de mantenimiento. Las versiones de mantenimiento tienen un
elemento -servicing-[number] anexado a la versión. Por ejemplo: 2.0.1-servicing-006924 .
Relación con versiones de .NET Standard
.NET Standard consta de un ensamblado de referencia de .NET. Hay varias implementaciones específicas de cada
plataforma. El ensamblado de referencia contiene la definición de las API de .NET que forman parte de una
versión concreta de .NET Standard. Cada implementación cumple el contrato de .NET Standard en una plataforma
en cuestión. Puede obtener más información sobre .NET Standard en el artículo .NET Standard de la guía de .NET.
El ensamblado de referencia de .NET Standard usa el esquema de control de versiones MAJOR.MINOR . El nivel
PATCH no es útil para .NET Standard porque solo expone una especificación de API en lugar de una
implementación, de modo que , por definición, cualquier cambio en la API representaría un cambio en el conjunto
de características (es decir, una versión de MINOR nueva).
Las implementaciones de cada plataforma pueden actualizarse, normalmente como parte de la versión de la
plataforma. Por tanto, es posible que no sean evidentes para los programadores que usen .NET Standard en la
plataforma en cuestión.
Cada versión de .NET Core implementa una versión de .NET Standard. Implementar una versión de .NET
Standard implica la compatibilidad con versiones anteriores de .NET Standard. Versión de .NET standard y .NET
Core por separado. Es una coincidencia que .NET Core 2.0 implemente .NET Standard 2.0. .NET Core 2.1 también
implementa .NET Standard 2.0. .NET Core será compatible con versiones futuras de .NET Standard en cuanto
estén disponibles.

.NET CORE .NET STANDARD

1.0 hasta la versión 1.6

2.0 hasta la versión 2.0

2.1 hasta la versión 2.0

2.2 hasta la versión 2.0

3.0 hasta la versión 2.1

Vea también
Marcos de trabajo de destino
Empaquetado de distribución de .NET Core
Hoja de información sobre el ciclo de vida de compatibilidad de .NET Core
.NET Core 2+ Version Binding (Enlace de versión de .NET Core 2+)
Imágenes de Docker para .NET Core
Selección de la versión de .NET Core que se va a
usar
12/01/2020 • 12 minutes to read • Edit Online

En este artículo se explican las directivas que usan las herramientas de .NET Core, el SDK y el runtime para la
selección de versiones. Estas directivas proporcionan un equilibrio entre la ejecución de aplicaciones con las
versiones especificadas y facilitan la actualización de los equipos del desarrollador y el usuario final. Estas
directivas realizan las siguientes acciones:
La implementación sencilla y eficaz de .NET Core, incluidas las actualizaciones de seguridad y confiabilidad.
Usar las herramientas y los comandos más recientes independientemente del runtime de destino.
La selección de versiones se produce:
Al ejecutar un comando del SDK, el SDK usa la versión instalada más reciente.
Al compilar un ensamblado, los monikers de la plataforma de destino definen las API de tiempo de
compilación.
Al ejecutar una aplicación .NET Core, las aplicaciones dependientes de la plataforma de destino se ponen al
día.
Al publicar una aplicación autocontenida, las implementaciones autocontenidas incluyen el runtime
seleccionado.
En el resto de este documento se examinan los cuatro escenarios.

El SDK usa la versión instalada más reciente


Los comandos de SDK incluyen dotnet new y dotnet run . La CLI de .NET Core debe elegir una versión del SDK
para cada comando dotnet . Usa el SDK más reciente instalado en el equipo de forma predeterminada, aunque:
El proyecto tenga como destino una versión anterior del entorno de ejecución de .NET Core.
La versión mas reciente del SDK de .NET Core sea una versión preliminar.
Puede beneficiarse de las características y mejoras del SDK más reciente mientras selecciona como destino
versiones anteriores del runtime de .NET Core. Puede tener como destino varias versiones del runtime de .NET
Core en otros proyectos, con las mismas herramientas del SDK para todos los proyectos.
En raras ocasiones, es posible que tenga que usar una versión anterior del SDK. Esa versión se especifica en un
archivo global.json. La directiva "usar la versión más reciente" significa que solo se usa global.json para
especificar una versión del SDK de .NET Core anterior a la versión instalada más reciente.
global.json se puede colocar en cualquier lugar de la jerarquía de archivos. La CLI busca el primer archivo
global.json hacia arriba desde el directorio del proyecto. Puede controlar a qué proyectos se aplica un archivo
global.json determinado mediante su lugar en el sistema de archivos. La CLI de .NET busca un archivo
global.json de forma iterativa desplazándose hacia arriba en la ruta de acceso desde el directorio de trabajo
actual. El primer archivo global.json que se encuentra especifica la versión que se usa. Si esa versión del SDK
está instalada, es la que se usa. Si no se encuentra el SDK especificado en global.json, la CLI de .NET usa reglas
de coincidencia para seleccionar un SDK compatible, o bien se produce un error si no se encuentra ninguno.
En el ejemplo siguiente se muestra la sintaxis de global.json:
{
"sdk": {
"version": "2.0.0"
}
}

El proceso de selección de una versión del SDK es la siguiente:


1. dotnet busca un archivo global.json de forma iterativa desplazándose hacia arriba de forma inversa en la
ruta de acceso desde el directorio de trabajo actual.
2. dotnet usa el SDK especificado en el primer archivo global.json que encuentra.
3. dotnet usa el SDK instalado más reciente si no se encuentra ningún archivo global.json.
Puede obtener más información sobre cómo seleccionar una versión del SDK en la sección Reglas de
coincidencia del artículo sobre global.json.

Los monikers de la plataforma de destino definen las API de tiempo


de compilación
El proyecto se compila con las API definidas en un moniker de la plataforma de destino (TFM ). La plataforma
de destino se especifica en el archivo del proyecto. Establezca el elemento TargetFramework del archivo del
proyecto como se muestra en el ejemplo siguiente:

<TargetFramework>netcoreapp2.0</TargetFramework>

Puede compilar el proyecto con varios TFM. Configurar varias plataformas de destino es más común para las
bibliotecas, pero también se puede hacer con las aplicaciones. Especifique una propiedad TargetFrameworks (el
plural de TargetFramework ). Las plataformas de destino se delimitan por punto y coma, como se muestra en el
ejemplo siguiente:

<TargetFrameworks>netcoreapp2.0;net47</TargetFrameworks>

Un SDK determinado admite un conjunto fijo de plataformas, limitado a la plataforma de destino del runtime
con el que se suministra. Por ejemplo, el SDK de .NET Core 2.0 incluye el runtime .NET Core 2.0, que es una
implementación de la plataforma de destino netcoreapp2.0 . El SDK de .NET Core 2.0 admite netcoreapp1.0 ,
netcoreapp1.1 y netcoreapp2.0 pero no netcoreapp2.1 (o una versión posterior ). El SDK de .NET Core 2.1 se
instala para compilar para netcoreapp2.1 .
Las plataformas de destino de .NET Standard también se limitan a la plataforma de destino del runtime con el
que se incluye el SDK. El SDK de .NET Core 2.0 está limitado a netstandard2.0 .

Puesta al día de las aplicaciones dependientes de la plataforma


Cuando una aplicación se ejecuta desde el origen con dotnet run , desde una implementación dependiente
del marco con dotnet myapp.dll o desde un ejecutable dependiente del marco con myapp.exe , el ejecutable
dotnet es el host de la aplicación.

El host elige la versión de revisión más reciente instalada en el equipo. Por ejemplo, si se especifica
netcoreapp2.0 en el archivo de proyecto, y 2.0.4 es el runtime de .NET instalado más reciente, se usa el
runtime 2.0.4 .
Si no se encuentra ninguna versión de 2.0.* aceptable, se usa una versión de 2.* nueva. Por ejemplo, si se
especificó netcoreapp2.0 y solo está instalado 2.1.0 , la aplicación se ejecuta con el runtime 2.1.0 . Este
comportamiento se conoce como "puesta al día de versión secundaria". Las versiones inferiores no se
considerarán. Cuando no hay ningún runtime aceptable instalado, la aplicación no se ejecutará.
Algunos ejemplos de uso muestran el comportamiento; si indica como destino la versión 2.0:
Se especifica la versión 2.0. 2.0.5 es la versión de revisión instalada más reciente. Se usa la versión 2.0.5.
Se especifica la versión 2.0. No hay ninguna versión 2.0.* instalada. 1.1.1 es el runtime superior instalado. Se
muestra un mensaje de error.
Se especifica la versión 2.0. No hay ninguna versión 2.0.* instalada. 2.2.2 es la versión del runtime 2.x
instalada más alta. Se usa la versión 2.2.2.
Se especifica la versión 2.0. No hay ninguna versión 2.x instalada. Se instala la versión 3.0.0. Se muestra un
mensaje de error.
La puesta al día de versión secundaria tiene un efecto secundario que puede afectar a los usuarios finales.
Considere el caso siguiente:
1. La aplicación especifica que se requiere la versión 2.0.
2. Cuando se ejecuta, la versión 2.0.* no está instalada, pero sí que lo está la 2.2.2. Se usará la versión 2.2.2.
3. Más adelante, el usuario instala la versión 2.0.5 y ejecuta de nuevo la aplicación. Ahora se usará la versión
2.0.5.
Es posible que las versiones 2.0.5 y 2.2.2 se comporten de forma diferente, especialmente en escenarios como la
serialización de datos binarios.

Las implementaciones autocontenidas incluyen el runtime


seleccionado.
Puede publicar una aplicación como una distribución autocontenida. Este enfoque empaqueta el runtime y las
bibliotecas de .NET Core con la aplicación. Las implementaciones autocontenidas no tienen una dependencia de
los entornos de runtime. La selección de la versión del runtime se produce en el momento de la publicación, no
en el tiempo de ejecución.
El proceso de publicación selecciona la versión de revisión más reciente de la familia de runtime indicada. Por
ejemplo, dotnet publish seleccionará .NET Core 2.0.4 si es la versión de revisión más reciente de la familia de
runtime de .NET Core 2.0. La plataforma de destino (incluidas las revisiones de seguridad instaladas más
recientes) se empaqueta con la aplicación.
Es un error que no se cumpla la versión mínima especificada para una aplicación. dotnet publish se enlaza a la
versión de revisión de runtime más reciente (dentro de una familia de versión principal.secundaria determinada).
dotnet publish no es compatible con la semántica de puesta al día de dotnet run . Para obtener más
información sobre las revisiones y las implementaciones autocontenidas, vea el artículo sobre selección de
revisión de runtime en la implementación de aplicaciones .NET Core.
Las implementaciones autocontenidas pueden requerir una versión de revisión específica. Puede invalidar la
versión de revisión de runtime mínima (para versiones superiores o inferiores) en el archivo del proyecto, como
se muestra en el ejemplo siguiente:

<RuntimeFrameworkVersion>2.0.4</RuntimeFrameworkVersion>

El elemento RuntimeFrameworkVersion invalida la directiva de versión predeterminada. Para las implementaciones


autocontenidas, RuntimeFrameworkVersion especifica la versión de la plataforma de runtime exacta. Para las
aplicaciones dependientes de la plataforma, RuntimeFrameworkVersion especifica la versión de la plataforma de
runtime mínima que se requiere.
Cómo quitar los componentes .NET Core Runtime y
SDK
20/01/2020 • 13 minutes to read • Edit Online

Con el tiempo, a medida que instale versiones actualizadas del runtime y el SDK de .NET Core, es posible que
quiera quitar del equipo versiones obsoletas de .NET Core. Al quitar versiones anteriores de runtime puede
cambiar el runtime elegido para ejecutar aplicaciones de marco compartidas, tal como se detalla en el artículo
sobre selección de la versión de .NET Core.

¿Puedo quitar una versión?


Los comportamientos de la selección de la versión de .NET Core y la compatibilidad de runtime de .NET Core en
diferentes actualizaciones permite quitar de forma segura las versiones anteriores. Las actualizaciones de .NET
Core Runtime son compatibles con una "banda" de versión principal, como 1.x y 2.x. Además, normalmente las
versiones más recientes del SDK de .NET Core mantienen la capacidad de crear aplicaciones destinadas a
versiones anteriores del tiempo de ejecución de una forma compatible.
En general, solo se necesita el SDK más reciente y la última versión de revisión de los runtimes necesarios para la
aplicación. Los casos en los que se conservan versiones anteriores del SDK o de entorno de ejecución incluyen el
mantenimiento de aplicaciones basadas en project.json. A menos que la aplicación tenga motivos concretos para
utilizar SDK o runtimes anteriores, puede quitar las versiones anteriores.

Determinación de lo instalado
A partir de .NET Core 2.1, la CLI de .NET tiene opciones que puede utilizar para enumerar las versiones del SDK y
de runtime que están instaladas en el equipo. Use dotnet --list-sdks para ver la lista de los SDK instalados en el
equipo. Use dotnet --list-runtimes para ver la lista de los runtimes instalados en el equipo. En el texto siguiente
se muestra el resultado típico para Windows, macOS o Linux:
Windows
Linux
macOS
C:\> dotnet --list-sdks
2.1.200-preview-007474 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007480 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007509 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007570 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007576 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007587 [C:\Program Files\dotnet\sdk]
2.1.200-preview-007589 [C:\Program Files\dotnet\sdk]
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.300-preview2-008533 [C:\Program Files\dotnet\sdk]
2.1.300 [C:\Program Files\dotnet\sdk]
2.1.400-preview-009063 [C:\Program Files\dotnet\sdk]
2.1.400-preview-009088 [C:\Program Files\dotnet\sdk]
2.1.400-preview-009171 [C:\Program Files\dotnet\sdk]

C:\> dotnet --list-runtimes


Microsoft.AspNetCore.All 2.1.0-preview2-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.0-preview2-final [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.0-preview2-26406-04 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

Desinstalación de .NET Core


Windows
Linux
macOS
.NET Core usa el cuadro de diálogo Agregar o quitar programas de Windows para quitar las versiones del
runtime de .NET Core y del SDK. En la siguiente ilustración se muestra el cuadro de diálogo Agregar o quitar
programas con varias versiones del runtime y SDK de .NET instaladas.
Seleccione las versiones que quiera quitar de su equipo y haga clic en Desinstalar.

Herramienta de desinstalación de .NET Core


La herramienta de desinstalación de .NET Core ( dotnet-core-uninstall ) permite quitar los SDK y los entornos de
ejecución de .NET Core de un sistema. Hay una colección de opciones disponible para especificar las versiones que
se deben desinstalar.

Dependencia de Visual Studio en versiones de SDK de .NET Core


Antes de la versión 16.3 de Visual Studio 2019, los instaladores de Visual Studio llamaron al instalador de SDK de
.NET Core independiente. Como resultado, las versiones del SDK aparecen en el cuadro de diálogo Agregar o
quitar programas de Windows. La eliminación de los SDK de .NET Core que se instalaron con Visual Studio
mediante el instalador independiente podría interrumpir Visual Studio. Si Visual Studio tiene problemas después
de desinstalar los SDK, ejecute reparar en esa versión específica de Visual Studio. En la tabla siguiente se muestran
algunas de las dependencias de Visual Studio en las versiones de SDK de .NET Core:

VERSIÓN DE VISUAL STUDIO VERSIÓN DEL SDK DE .NET CORE

Visual Studio 2019, versión 16.2 SDK de .NET Core 2.2.4xx, 2.1.8xx

Visual Studio 2019, versión 16.1 SDK de .NET Core 2.2.3xx, 2.1.7xx

Visual Studio 2019, versión 16.0 SDK de .NET Core 2.2.2xx, 2.1.6xx

Visual Studio 2017, versión 15.9 SDK de .NET Core 2.2.1xx, 2.1.5xx

Visual Studio 2017, versión 15.8 SDK de .NET Core 2.1.4xx

A partir de Visual Studio 2019 16.3, Visual Studio se encarga de su propia copia de la SDK de .NET Core. Por ese
motivo, ya no verá las versiones del SDK en el cuadro de diálogo Agregar o quitar programas.
Eliminación de la carpeta de reserva de NuGet
Antes del SDK de .NET Core 3.0, los instaladores de SDK de .NET Core usaban NuGetFallbackFolder para
almacenar una memoria caché de paquetes NuGet. Esta memoria caché se utilizó durante operaciones como
dotnet restore o dotnet build /t:Restore . NuGetFallbackFolder se encuentra en C:\Archivos de
programa\dotnet\sdk en Windows y en /usr/local/share/dotnet/sdk en macOS.
Es posible que desee quitar esta carpeta si:
Solo está desarrollando con el SDK de .NET Core 3.0 o versiones posteriores.
Está desarrollando con versiones SDK de .NET Core anteriores a la 3.0, pero puede trabajar en línea y las cosas
pueden ser más lentas una vez.
Si desea quitar la carpeta de reserva de NuGet, puede eliminarla, pero necesitará privilegios de administrador para
hacerlo.
No se recomienda eliminar la carpeta dotnet. Si lo hace, se quitarán las herramientas globales que haya instalado
previamente. Además, en Windows:
Interrumpirá Visual Studio 2019 versión 16.3 y versiones posteriores. Puede ejecutar Reparar para recuperarlo.
Si hay SDK de .NET Core entradas en el cuadro de diálogo Agregar o quitar programas, se quedarán
huérfanas.
Catálogo de identificadores de entorno de
ejecución (RID) de .NET Core
12/01/2020 • 9 minutes to read • Edit Online

RID es la abreviatura de identificador de entorno de ejecución. Los valores de RID se usan para identificar
las plataformas de destino donde se ejecuta la aplicación. Los paquetes de .NET los usan para presentar
los recursos específicos de la plataforma en los paquetes de NuGet. Los valores siguientes son ejemplos
de RID: linux-x64 , ubuntu.14.04-x64 , win7-x64 o osx.10.12-x64 . En el caso de los paquetes con
dependencias nativas, el RID designa las plataformas en las que se puede restauran el paquete.
Un único RID se puede establecer en el elemento <RuntimeIdentifier> del archivo del proyecto. Se
pueden definir varios RID como una lista delimitada por punto y coma en el elemento
<RuntimeIdentifiers> del archivo del proyecto. También se usan a través de la opción --runtime con los
comandos de la CLI de .NET Core siguientes:
dotnet build
dotnet clean
dotnet pack
dotnet publish
dotnet restore
dotnet run
dotnet store
Los RID que representan sistemas operativos concretos normalmente siguen este patrón:
[os].[version]-[architecture]-[additional qualifiers] , donde:

[os] es el moniker del sistema operativo o de plataforma. Por ejemplo: ubuntu .


[version] es la versión del sistema operativo en formato de número de versión separado por
punto ( . ). Por ejemplo: 15.10 .
La versión no se debe tratar como versiones de marketing, debido a que, a menudo,
representan varias versiones discretas del sistema operativo con un área expuesta de API de
plataforma diferente.
[architecture] es la arquitectura de procesador. Por ejemplo: x86 , x64 , arm o arm64 .

[additional qualifiers] diferencia aún más las distintas plataformas. Por ejemplo: aot .

Grafo de RID
El grado de RID o el grafo de reserva de entorno de ejecución es una lista de RID compatibles entre sí.
Los RID se definen en el paquete Microsoft.NETCore.Platforms. Pude ver la lista de RID compatibles y el
grafo de RID en el archivo runtime.json, que se encuentra en el repositorio de CoreFX. En este archivo
puede ver que todos los RID, excepto el RID de base, contienen una instrucción "#import" . Estas
instrucciones indican los RID compatibles.
Cuando NuGet restaura los paquetes, intenta encontrar una coincidencia exacta para el entorno de
ejecución especificado. Si no se encuentra una coincidencia exacta, NuGet vuelve al grafo hasta encontrar
el sistema compatible más cercano según el grafo de RID.
El ejemplo siguiente es la entrada real del RID osx.10.12-x64 :

"osx.10.12-x64": {
"#import": [ "osx.10.12", "osx.10.11-x64" ]
}

El RID anterior especifica que osx.10.12-x64 importa osx.10.11-x64 . Por tanto, cuando NuGet restaura
los paquetes, intenta encontrar una coincidencia exacta para osx.10.12-x64 en el paquete. Si NuGet no
puede encontrar el entorno de ejecución específico, puede restaurar, por ejemplo, los paquetes que
especifican entornos de ejecución osx.10.11-x64 .
En el ejemplo siguiente se muestra un grafo de RID ligeramente más grande que también se define en el
archivo runtime.json:

win7-x64 win7-x86
| \ / |
| win7 |
| | |
win-x64 | win-x86
\ | /
win
|
any

A la larga, todos los RID se asignarán de vuelta al RID any raíz.


Hay algunas consideraciones sobre los RID que debe tener en cuenta cuando trabaja con ellos:
Los RID son cadenas opacas y se deben tratar como cajas negras.
No compile RID mediante programación.
Use RID que ya estén definidos para la plataforma.
Los RID deben ser específicos, por lo que no se recomienda presuponer nada a partir del valor de RID
real.

Uso de los RID


Para poder usar los RID, debe saber cuáles son los RID que existen. Se agregan valores nuevos a la
plataforma de manera habitual. Para obtener la versión más reciente y completa, consulte el archivo
runtime.json que se encuentra en el repositorio CoreFX.
El SDK de .NET Core 2.0 presenta el concepto de RID portátiles. Son nuevos valores agregados al grafo
de RID que no están vinculados a una versión específica o distribución del sistema operativo, y son la
opción preferida cuando se usa .NET Core 2.0 y versiones posteriores. Resultan especialmente útiles al
tratar con varias distribuciones de Linux dado que la mayoría de los RID de distribución se asignan a los
RID portátiles.
En la lista siguiente se muestra un pequeño subconjunto de los RID más comunes que se usan con cada
sistema operativo.

RID de Windows
Solo se muestran los valores comunes. Para obtener la versión más reciente y completa, consulte el
archivo runtime.json que se encuentra en el repositorio CoreFX.
Portátil (.NET Core 2.0 o versiones posteriores)
win-x64
win-x86
win-arm
win-arm64
Windows 7/Windows Server 2008 R2
win7-x64
win7-x86
Windows 8.1/Windows Server 2012 R2
win81-x64
win81-x86
win81-arm
Windows 10/Windows Server 2016
win10-x64
win10-x86
win10-arm
win10-arm64

Para obtener más información, vea Dependencias y requisitos de .NET Core.

RID de Linux
Solo se muestran los valores comunes. Para obtener la versión más reciente y completa, consulte el
archivo runtime.json que se encuentra en el repositorio CoreFX. Los dispositivos que ejecutan una
distribución que no se muestran en la lista podrían funcionar con uno de los RID portátiles. Por ejemplo,
el destino de los dispositivos Raspberry Pi que ejecutan una distribución de Linux se puede establecer con
linux-arm .

Portátil (.NET Core 2.0 o versiones posteriores)


linux-x64 ( La mayoría de las distribuciones de escritorio como CentOS, Debian, Fedora,
Ubuntu y derivados)
linux-musl-x64 ( Distribuciones ligeras con musl como Alpine Linux)
linux-arm ( Distribuciones de Linux que se ejecutan en ARM, como Raspberry Pi)
Red Hat Enterprise Linux
rhel-x64 ( Se reemplaza por linux-x64 para RHEL por encima de la versión 6 )
rhel.6-x64 (.NET Core 2.0 o versiones posteriores)
Tizen (.NET Core 2.0 o versiones posteriores)
tizen
tizen.4.0.0
tizen.5.0.0

Para obtener más información, vea Dependencias y requisitos de .NET Core.

RID de macOS
Los RID de macOS usan la personalización de marca antigua "OSX". Solo se muestran los valores
comunes. Para obtener la versión más reciente y completa, consulte el archivo runtime.json que se
encuentra en el repositorio CoreFX.
Portátil (.NET Core 2.0 o versiones posteriores)
osx-x64 ( La versión mínima del sistema operativo es macOS 10.12 Sierra)
macOS 10.10 Yosemite
osx.10.10-x64
macOS 10.11 El Capitan
osx.10.11-x64
macOS 10.12 Sierra (.NET Core 1.1 o versiones posteriores)
osx.10.12-x64
macOS 10.13 High Sierra (.NET Core 1.1 o versiones posteriores)
osx.10.13-x64
macOS 10.14 Mojave (.NET Core 1.1 o versiones posteriores)
osx.10.14-x64

Para obtener más información, vea Dependencias y requisitos de .NET Core.

Vea también
Identificadores de entorno de ejecución
Información general sobre el SDK de .NET Core
23/10/2019 • 3 minutes to read • Edit Online

El SDK de .NET Core es un conjunto de bibliotecas y herramientas que permiten a los desarrolladores crear
aplicaciones y bibliotecas de .NET Core. Contiene los siguientes componentes que se usan para compilar y ejecutar
aplicaciones:
Herramientas de la CLI de .NET Core.
Bibliotecas y runtime de .NET Core.
Controlador dotnet .

Adquisición del SDK de .NET Core


Del mismo modo que ocurre con todas las herramientas, lo primero que debe hacer es instalar las herramientas en
su máquina. Según el escenario, puede instalar el SDK mediante uno de los métodos siguientes:
Los instaladores nativos.
El script de shell de instalación.
Los instaladores nativos están pensados principalmente para las máquinas de los desarrolladores. El SDK se
distribuye mediante el mecanismo de instalación nativo de cada plataforma compatible, como los paquetes DEB en
Ubuntu o los conjuntos de MSI en Windows. Estos instaladores instalan y configuran el entorno según sea
necesario para que el usuario use el SDK inmediatamente después de la instalación. Sin embargo, también se
necesitan privilegios administrativos en la máquina. Puede encontrar el SDK para instalar en la página de
descargas de .NET.
Por el contrario, los scripts de instalación no requieren privilegios administrativos, aunque tampoco instalan ningún
requisito previo en el equipo; debe instalarlos todos manualmente el usuario. Los scripts están pensados
principalmente para configurar servidores de compilación o cuando desee instalar las herramientas sin privilegios
de administración (tenga en cuenta la salvedad con respecto a los requisitos previos que ya se mencionó). Puede
encontrar más información en el artículo referencia de scripts de dotnet-install. Si está interesado en cómo
configurar el SDK en el servidor de compilación de CI, vea el artículo Uso de .NET Core SDK y herramientas de
integración continua (CI).
De forma predeterminada, el SDK se instala en paralelo (SxS ), lo que significa que varias versiones de las
herramientas de la CLI pueden coexistir en un único equipo en cualquier momento. La forma en que se detecta la
versión al ejecutar los comandos de la CLI se explica más detalladamente en el artículo Selección de la versión de
.NET Core que se va a usar.

Vea también
CLI de .NET Core
Introducción a la creación de versiones de .NET Core
Cómo quitar los componentes .NET Core Runtime y SDK
Selección de la versión de .NET Core que se va a usar
Herramientas de la interfaz de la línea de
comandos (CLI) de .NET Core
20/01/2020 • 7 minutes to read • Edit Online

La interfaz de la línea de comandos (CLI) de .NET Core es una cadena de herramientas multiplataforma para el
desarrollo de aplicaciones. NET. La CLI es una base sobre la que pueden descansar herramientas de nivel
superior, como los entornos de desarrollo integrados (IDE ), los editores y los orquestadores de compilación.

Instalación
Puede usar los instaladores nativos o los scripts de shell de instalación:
Los instaladores nativos se usan principalmente en máquinas del desarrollador y usan el mecanismo de
instalación nativo de cada plataforma compatible, por ejemplo, los paquetes DEB en Ubuntu o los paquetes
MSI en Windows. Estos instaladores instalan y configuran el entorno para su uso inmediato por el
desarrollador, pero requieren privilegios administrativos en la máquina. Puede ver las instrucciones de
instalación en la Guía de instalación de .NET Core.
Los scripts de shell se usan principalmente para configurar servidores de compilación o cuando desee
instalar las herramientas sin privilegios administrativos. Los scripts de instalación no instalan los requisitos
previos en la máquina, se deben instalar manualmente. Para más información, consulte el tema de
referencia sobre los scripts de instalación. Para más información sobre cómo configurar la CLI en el
servidor de compilación de integración continua (CI), consulte Uso de .NET Core SDK y herramientas de
integración continua (CI).
De forma predeterminada, la CLI se instala en paralelo (SxS ), para que varias versiones de las herramientas de
la CLI puedan coexistir en una única máquina. En la sección Controlador se explica más detalladamente cómo
determinar qué versión usar en una máquina en la que hay varias versiones instaladas.

Comandos de la CLI
De forma predeterminada, se instalan los siguientes comandos:
.NET Core 2.x
.NET Core 1.x
Comandos básicos
new
restore
build
publish
run
test
vstest
pack
migrate
clean
sln
help
store
Comandos de modificación del proyecto
add package
add reference
remove package
remove reference
list reference
Comandos avanzados
nuget delete
nuget locals
nuget push
msbuild
dotnet install script
La CLI adopta un modelo de extensibilidad que le permite especificar herramientas adicionales para sus
proyectos. Para más información, consulte el tema Modelo de extensibilidad de la CLI de .NET Core.

Estructura de comandos
La estructura de comandos de la CLI consta del controlador ("dotnet"), el comando y posiblemente de los
argumentos de comandos y otras opciones. Este patrón se puede ver en la mayoría de las operaciones de la
CLI, como la creación de una nueva aplicación de consola y su ejecución desde la línea de comandos, como
muestran los siguientes comandos cuando se ejecutan desde un directorio denominado my_app :
.NET Core 2.x
.NET Core 1.x

dotnet new console


dotnet build --output /build_output
dotnet /build_output/my_app.dll

Controlador
El controlador se denomina dotnet y tiene dos responsabilidades, ejecutar una aplicación dependiente del
marco o ejecutar un comando.
Para ejecutar una aplicación dependiente del marco, especifique la aplicación después del controlador, por
ejemplo, dotnet /path/to/my_app.dll . Cuando ejecute el comando desde la carpeta donde reside la DLL de la
aplicación, simplemente ejecute dotnet my_app.dll . Si quiere usar una versión específica del entorno de
ejecución .NET Core, use la opción --fx-version <VERSION> (consulte la referencia del comando dotnet).
Cuando se proporciona un comando para el controlador, dotnet.exe inicia el proceso de ejecución del
comando de la CLI. Por ejemplo:

dotnet build

En primer lugar, el controlador determina la versión de SDK que se debe usar.Si no hay ningún elemento
"global.json", se usa la última versión del SDK disponible. Podría tratarse de una versión preliminar o de una
versión estable, en función de lo último que esté disponible en el equipo. Una vez determinada la versión del
SDK, se ejecutará el comando.
Comando
El comando realiza una acción. Por ejemplo, dotnet build compila código. dotnet publish publica el código.
Los comandos se implementan como una aplicación de consola usando una convención dotnet {command} .
Argumentos
Los argumentos que se pasan en la línea de comandos son los argumentos para el comando invocado. Por
ejemplo, cuando ejecuta dotnet publish my_app.csproj , el argumento my_app.csproj indica el proyecto que se
publicará y se pasará al comando publish .
Opciones
Las opciones que se pasan en la línea de comandos son las opciones para el comando que se invoca. Por
ejemplo, cuando ejecuta dotnet publish --output /build_output , la opción --output y su valor se pasan al
comando publish .

Migración desde project.json


Si usó herramientas de la versión preliminar 2 para producir proyectos basados en project.json, consulte el
tema sobre dotnet migrate para más información sobre cómo migrar su proyecto a MSBuild/ .csproj para
usarlo con herramientas de versión. Para los proyectos de .NET Core creados antes del lanzamiento de las
herramientas de la versión preliminar 2, actualice manualmente el proyecto siguiendo las instrucciones que se
indican en Migración de DNX a CLI de .NET Core (project.json) y, luego, use dotnet migrate o actualice
directamente los proyectos.

Vea también
dotnet/repositorio de GitHub de la CLI
.NET Core installation guide (Guía de instalación de .NET Core)
Información general sobre las herramientas
globales de .NET Core
20/01/2020 • 8 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1


Una herramienta global de .NET Core es un paquete especial de NuGet que contiene una aplicación de
consola. Las herramientas globales se pueden instalar en una ubicación predeterminada del equipo incluida en
la variable de entorno PATH, o bien en una ubicación personalizada.
Si quiere usar una herramienta global de .NET Core:
Busque información sobre la herramienta (normalmente un sitio web o página de GitHub).
Compruebe el autor y las estadísticas en la página principal de la fuente (normalmente NuGet.org).
Instale la herramienta.
Llame a la herramienta.
Actualice la herramienta.
Desinstale la herramienta.

IMPORTANT
Las herramientas globales de .NET Core aparecen en su ruta de acceso y se ejecutan con plena confianza. No instale
herramientas globales de .NET Core a menos que confíe en el autor.

Buscar una herramienta global de .NET Core


Actualmente, no hay una característica que permita buscar herramientas globales en la interfaz de línea de
comandos (CLI) de .NET Core. A continuación se muestran algunas recomendaciones sobre cómo buscar
herramientas:
Aunque estas herramientas se pueden encontrar en NuGet, NuGet todavía no permite buscar de manera
específica herramientas globales de .NET Core.
Es posible que encuentre recomendaciones sobre herramientas en entradas de blog o en el repositorio de
GitHub natemcmaster/dotnet-tools.
Puede ver el código fuente de las herramientas globales creado por el equipo de ASP.NET en el repositorio
de GitHub dotnet/aspnetcore.
Puede obtener información sobre las herramientas de diagnóstico en herramientas globales de diagnóstico
de dotnet de .NET Core .

Comprobar el autor y las estadísticas


Dado que herramientas globales de .NET Core se ejecutan con plena confianza y generalmente se instalan en
su ruta de acceso, pueden ser muy eficaces. No descargue herramientas de personas en las que no confíe.
Si la herramienta está hospedada en NuGet, busque la herramienta para comprobar el autor y las estadísticas.

Instalar una herramienta global


Para instalar una herramienta global, use el comando de CLI de .NET Core dotnet tool install. En el ejemplo
siguiente se muestra cómo instalar una herramienta global en la ubicación predeterminada:

dotnet tool install -g dotnetsay

Si no se puede instalar la herramienta, se muestran mensajes de error. Verifique que se comprueban las
fuentes que esperaba.
Si está intentando instalar una versión preliminar o una versión específica de la herramienta, puede especificar
el número de versión con el formato siguiente:

dotnet tool install -g <package-name> --version <version-number>

Si la instalación es correcta, se muestra un mensaje similar al siguiente con el comando que se usa para llamar
a la herramienta y la versión instalada:

You can invoke the tool using the following command: dotnetsay
Tool 'dotnetsay' (version '2.0.0') was successfully installed.

Las herramientas globales pueden instalarse en el directorio predeterminado o en una ubicación específica. Los
directorios predeterminados son:

SO RUTA DE ACCESO

Linux/macOS $HOME/.dotnet/tools

Windows %USERPROFILE%\.dotnet\tools

Estas ubicaciones se agregan a la ruta de acceso del usuario cuando se ejecuta el SDK por primera vez,
permitiendo así llamar directamente a las herramientas globales allí instaladas.
Tenga en cuenta que las herramientas globales son específicas del usuario, no de la máquina. Específica del
usuario significa que no se puede instalar una herramienta global que está disponible para todos los usuarios
de la máquina. La herramienta solo está disponible para cada perfil de usuario en el que se instaló la
herramienta.
Las herramientas globales también pueden instalarse en un directorio específico. Cuando se instalan en un
directorio específico, el usuario debe incluir el directorio en la ruta de acceso a fin de asegurarse de que el
comando está disponible. Hay dos maneras de hacerlo: llamar al comando con el directorio especificado, o
llamar a la herramienta desde el directorio especificado. En este caso, la CLI de .NET Core no agrega esta
ubicación automáticamente a la variable de entorno PATH.

Usar la herramienta
Una vez que la herramienta se ha instalado, puede llamarla mediante su comando. Tenga en cuenta que el
comando podría no ser el mismo que el nombre del paquete.
Si el comando es dotnetsay , llame a la herramienta con:

dotnetsay

Si la intención del autor era mostrar la herramienta ante una petición de dotnet , puede haberla escrito de
manera que se llame como dotnet <command> , por ejemplo:
dotnet doc

Para ver las herramientas que están incluidas en un paquete de herramienta global instalado, enumere los
paquetes instalados con el comando dotnet tool list.
También puede buscar las instrucciones de uso en el sitio web de la herramienta o escribir uno de los
siguientes comandos:

<command> --help
dotnet <command> --help

Otros comandos de la CLI


El SDK de .NET Core contiene otros comandos que pueden usarse con las herramientas globales de .NET
Core. Utilice cualquiera de los comandos de dotnet tool combinado con las opciones siguientes:
--global o -g especifica que el comando es aplicable a las herramientas globales de todos los usuarios.
--tool-path especifica una ubicación personalizada para las herramientas globales.

Para saber qué comandos están disponibles con las herramientas globales:

dotnet tool --help

La actualización de una herramienta global implica desinstalarla y reinstalarla con la versión estable más
reciente. Para actualizar una herramienta global, utilice el comando dotnet tool update:

dotnet tool update -g <packagename>

Para quitar una herramienta global con dotnet tool uninstall:

dotnet tool uninstall -g <packagename>

Para mostrar todas las herramientas globales instaladas actualmente en el equipo, junto con su versión y los
comandos, use el comando dotnet tool list:

dotnet tool list -g

Vea también
Solución de problemas de uso de herramientas de .NET Core
Creación de una herramienta global de .NET Core
mediante la CLI de .NET Core
20/01/2020 • 7 minutes to read • Edit Online

En este artículo se explica cómo crear y empaquetar una herramienta global en .NET Core. La CLI de .NET Core
permite crear una aplicación de consola como una herramienta global, que otros usuarios pueden instalar y
ejecutar fácilmente. Las herramientas globales de .NET Core son paquetes de NuGet que se instalan desde la CLI
de .NET Core. Para más información sobre las herramientas globales, vea Información general sobre las
herramientas globales de .NET Core.
Este artículo se aplica a: ✓ SDK de .NET Core 2.1

Crear un proyecto
En este artículo se usa la CLI de .NET Core para crear y administrar un proyecto.
Nuestra herramienta de ejemplo será una aplicación de consola que genera un bot de ASCII e imprime un
mensaje. En primer lugar, cree una aplicación de consola de .NET Core.

dotnet new console -o botsay

Navegue hasta el directorio botsay creado por el comando anterior.

Agregar el código
Abra el archivo Program.cs con su editor de texto favorito, como vim o Visual Studio Code.
Agregue la siguiente directiva using a la parte superior del archivo, ya que esto ayuda a reducir el código para
mostrar la información de versión de la aplicación.

using System.Reflection;

A continuación, desplácese hacia abajo hasta el método Main . Reemplace el método con el siguiente código para
procesar los argumentos de la línea de comandos para la aplicación. Si no se pasa ningún argumento, se muestra
un mensaje de Ayuda breve. En caso contrario, todos los argumentos se transforman en una cadena y se imprimen
con el bot.
static void Main(string[] args)
{
if (args.Length == 0)
{
var versionString = Assembly.GetEntryAssembly()
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion
.ToString();

Console.WriteLine($"botsay v{versionString}");
Console.WriteLine("-------------");
Console.WriteLine("\nUsage:");
Console.WriteLine(" botsay <message>");
return;
}

ShowBot(string.Join(' ', args));


}

Crear el bot
A continuación, agregue un nuevo método denominado ShowBot que toma un parámetro de cadena. Este método
imprime el mensaje y el bot de ASCII. El código de bot de ASCII se ha tomado del ejemplo de dotnetbot.
static void ShowBot(string message)
{
string bot = $"\n {message}";
bot += @"
__________________
\
\
....
....'
....
..........
.............'..'..
................'..'.....
.......'..........'..'..'....
........'..........'..'..'.....
.'....'..'..........'..'.......'.
.'..................'... ......
. ......'......... .....
. _ __ ......
.. # ## ......
.... . .......
...... ....... ............
................ ......................
........................'................
......................'..'...... .......
.........................'..'..... .......
........ ..'.............'..'.... ..........
..'..'... ...............'....... ..........
...'...... ...... .......... ...... .......
........... ....... ........ ......
....... '...'.'. '.'.'.' ....
....... .....'.. ..'.....
.. .......... ..'........
............ ..............
............. '..............
...........'.. .'.'............
............... .'.'.............
.............'.. ..'..'...........
............... .'..............
......... ..............
.....
";
Console.WriteLine(bot);
}

Probar la herramienta
Ejecute el proyecto y observe la salida. Pruebe estas variaciones en la línea de comandos para ver resultados
diferentes:

dotnet run
dotnet run -- "Hello from the bot"
dotnet run -- hello from the bot

Todos los argumentos después del delimitador -- se pasan a la aplicación.

Configuración de la herramienta global


Antes de que pueda empaquetar y distribuir la aplicación como una herramienta global, debe modificar el archivo
de proyecto. Abra el archivo botsay.csproj y agregue tres nuevos nodos XML al nodo <Project><PropertyGroup> :
<PackAsTool>
[OBLIGATORIO ] Indica que la aplicación se empaquetará para la instalación como una herramienta global.
<ToolCommandName>
[OPCIONAL ] Un nombre alternativo para la herramienta; en caso contrario, el nombre del comando de la
herramienta se asignará después del archivo de proyecto. Puede tener varias herramientas en un paquete;
elegir un nombre único y descriptivo ayuda a diferenciar de otras herramientas en el mismo paquete.
<PackageOutputPath>
[OPCIONAL ] Dónde se generará el paquete NuGet. El paquete NuGet es el que las herramientas globales
de la CLI de .NET Core utilizan para instalar la herramienta.

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>

<PackAsTool>true</PackAsTool>
<ToolCommandName>botsay</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>

</PropertyGroup>

</Project>

Aunque <PackageOutputPath> es opcional, úselo en este ejemplo. Asegúrese de que lo establece:


<PackageOutputPath>./nupkg</PackageOutputPath> .

A continuación, cree un paquete NuGet para la aplicación.

dotnet pack

El archivo botsay.1.0.0.nupkg se crea en la carpeta identificada por el valor XML <PackageOutputPath> desde el
archivo botsay.csproj , que en este ejemplo es la carpeta ./nupkg . Esto facilita la instalación y las pruebas. Si
quiere lanzar una herramienta públicamente, cárguela en https://www.nuget.org. Una vez que la herramienta está
disponible en NuGet, los desarrolladores pueden realizar una instalación para todos los usuarios de dicha
herramienta mediante la opción --global del comando dotnet tool install.
Ahora que tiene un paquete, instale la herramienta desde ese paquete:

dotnet tool install --global --add-source ./nupkg botsay

El parámetro --add-source indica a la CLI de .NET Core que use temporalmente la carpeta ./nupkg (nuestra
carpeta <PackageOutputPath> ) como una fuente de origen adicional para los paquetes NuGet. Para más
información sobre la instalación de las herramientas globales, vea Información general sobre las herramientas
globales de .NET Core.
Si la instalación es correcta, se muestra un mensaje similar al siguiente con el comando que se usa para llamar a la
herramienta y la versión instalada:

You can invoke the tool using the following command: botsay
Tool 'botsay' (version '1.0.0') was successfully installed.

Ahora podrá escribir botsay y obtener una respuesta de la herramienta.


NOTE
Si la instalación fue correcta, pero no se puede usar el comando botsay , es posible que deba abrir un terminal nuevo para
actualizar la ruta de acceso.

Quitar la herramienta
Cuando haya terminado de experimentar con la herramienta, puede quitarla con el comando siguiente:

dotnet tool uninstall -g botsay


Solución de problemas de uso de herramientas de
.NET Core
24/11/2019 • 13 minutes to read • Edit Online

Es posible que surjan problemas al intentar instalar o ejecutar una herramienta de .NET Core, la cual puede ser
global o local. En este artículo se describen las causas principales más comunes y algunas posibles soluciones.

No se puede ejecutar la herramienta de .NET Core instalada


Cuando una herramienta de .NET Core no se ejecuta, lo más probable es que se haya producido uno de los
siguientes problemas:
No se encontró el archivo ejecutable de la herramienta.
No se encontró la versión correcta del runtime de .NET Core.
No se encontró el archivo ejecutable
Si no se encuentra el archivo ejecutable, verá un mensaje similar al siguiente:

Could not execute because the specified command or file was not found.
Possible reasons for this include:
* You misspelled a built-in dotnet command.
* You intended to execute a .NET Core program, but dotnet-xyz does not exist.
* You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on
the PATH.

El nombre del archivo ejecutable determina cómo se invoca la herramienta. En la siguiente tabla se describe el
formato:

FORMATO DEL NOMBRE DEL ARCHIVO EJECUTABLE FORMATO DE INVOCACIÓN

dotnet-<toolName>.exe dotnet <toolName>

<toolName>.exe <toolName>

Herramientas globales
Las herramientas globales pueden instalarse en el directorio predeterminado o en una ubicación específica.
Los directorios predeterminados son:

SO RUTA DE ACCESO

Linux/macOS $HOME/.dotnet/tools

Windows %USERPROFILE%\.dotnet\tools

Si intenta ejecutar una herramienta global, compruebe que la variable del entorno PATH de su máquina
contiene la ruta de acceso donde instaló la herramienta global y que el archivo ejecutable está en esa ruta de
acceso.
La primera vez que se usa, la CLI de .NET Core intenta agregar las ubicaciones predeterminadas a la
variable de entorno PATH. Sin embargo, hay un par de escenarios en los que la ubicación podría no
agregarse automáticamente a PATH, por lo que deberá editar PATH para configurarlo en los siguientes
casos:
Si usa Linux y ha instalado el SDK de .NET Core mediante el uso de archivos .tar.gz en lugar de “apt-get”
o “rpm”.
Si usa macOS 10.15 “Catalina” o versiones posteriores.
Si usa macOS 10.14 “Mojave” o versiones anteriores y ha instalado el SDK de .NET Core mediante el
uso de archivos .tar.gz en lugar de .pkg.
Si ha instalado el SDK de .NET Core 3.0 y ha establecido la variable de entorno
DOTNET_ADD_GLOBAL_TOOLS_TO_PATH en false .
Si ha instalado el SDK de .NET Core 2.2 o versiones anteriores y ha establecido la variable de entorno
DOTNET_SKIP_FIRST_TIME_EXPERIENCE en true .
Para obtener más información sobre las herramientas globales, vea Información general sobre las
herramientas globales de .NET Core.
Herramientas locales
Si intenta ejecutar una herramienta local, compruebe que hay un archivo de manifiesto denominado dotnet-
tools.json en el directorio actual o en cualquiera de sus directorios principales. Este archivo también puede
encontrarse en una carpeta denominada .config en cualquier lugar de la jerarquía de carpetas del proyecto,
en lugar de en la carpeta raíz. Si dotnet-tools.json existe, ábralo y busque la herramienta que intenta ejecutar.
Si el archivo no contiene una entrada para "isRoot": true , busque más arriba en la jerarquía de archivos
otros archivos de manifiesto de la herramienta.
Si intenta ejecutar una herramienta de .NET Core que se instaló con una ruta de acceso especificada, debe
incluir dicha ruta de acceso al usar la herramienta. Un ejemplo de uso de una herramienta instalada en una
ruta de acceso de herramientas es:

..\<toolDirectory>\dotnet-<toolName>

No se encontró el runtime
Las herramientas de .NET Core son aplicaciones dependientes del marco, lo que significa que se basan en un
runtime de .NET Core instalado en el equipo. Si no se encuentra el runtime esperado, se siguen las reglas
normales de puesta al día de runtime de .NET Core:
Una aplicación avanza a la versión de revisión más alta de las versiones principal y secundaria especificadas.
Si no hay ningún runtime que coincida con un número de versión principal y secundaria, se usa la siguiente
versión secundaria más alta.
Esta puesta al día no se produce entre versiones preliminares del runtime ni entre versiones preliminares y
versiones de lanzamiento. Por lo tanto, las herramientas de .NET Core creadas con versiones preliminares
deben ser recompiladas, publicadas nuevamente y reinstaladas por el autor.
La puesta al día no se producirá de forma predeterminada en dos escenarios comunes:
Solo están disponibles las versiones anteriores del runtime. La puesta al día solo selecciona versiones
posteriores del runtime.
Solo están disponibles las versiones posteriores principales del runtime. La puesta al día no traspasa los límites
de la versión principal.
Si una aplicación no encuentra el runtime apropiado, no se puede ejecutar y notifica un error.
Puede averiguar qué runtimes de .NET Core están instalados en su máquina con uno de los comandos siguientes:
dotnet --list-runtimes
dotnet --info

Si cree que la herramienta debería ser compatible con la versión de runtime que tiene instalada actualmente,
puede ponerse en contacto con el autor de la herramienta para ver si puede actualizar el número de versión o la
compatibilidad con varios destinos. Una vez que se vuelva a compilar y a publicar el paquete de herramientas en
NuGet con un número de versión actualizado, podrá actualizar su copia. Mientras tanto, la solución más rápida es
instalar una versión del runtime que funcione con la herramienta que intenta ejecutar. Para descargar una versión
específica del runtime de .NET Core, visite la página de descarga de .NET Core.
Si instala el SDK de .NET Core en una ubicación que no es la predeterminada, debe establecer la variable de
entorno DOTNET_ROOT en el directorio que contiene el archivo ejecutable dotnet .

Error en la instalación de una herramienta de .NET Core


Hay varias razones por las que se puede producir un error en la instalación de una herramienta local o global de
.NET Core. Cuando se produzca un error en la instalación de la herramienta, verá un mensaje similar al siguiente:

Tool '{0}' failed to install. This failure may have been caused by:

* You are attempting to install a preview release and did not use the --version option to specify the version.
* A package by this name was found, but it was not a .NET Core tool.
* The required NuGet feed cannot be accessed, perhaps because of an Internet connection problem.
* You mistyped the name of the tool.

For more reasons, including package naming enforcement, visit https://aka.ms/failure-installing-tool

Para ayudar a diagnosticar estos errores, los mensajes de NuGet se muestran directamente al usuario, junto con el
mensaje anterior. El mensaje de NuGet puede ayudarle a identificar el problema.
Cumplimiento de la nomenclatura de los paquetes
Microsoft ha cambiado sus instrucciones sobre los identificadores de paquetes para las herramientas, lo que ha
dado lugar a que no se encuentren diversas herramientas con el nombre previsto. Según las nuevas instrucciones,
todas las herramientas de Microsoft deben tener el prefijo “Microsoft”. Este prefijo está reservado y solo se puede
usar para los paquetes firmados con un certificado autorizado de Microsoft.
Durante la transición, algunas herramientas de Microsoft tendrán el formato anterior del identificador de paquete,
mientras que otras tendrán el nuevo formato:

dotnet tool install -g Microsoft.<toolName>


dotnet tool install -g <toolName>

A medida que se actualicen los identificadores de paquetes, deberá usar el nuevo identificador de paquete para
obtener las actualizaciones más recientes. Los paquetes con el nombre de herramienta simplificado estarán en
desuso.
Versiones preliminares
Intenta instalar una versión preliminar y no ha usado la opción --version para especificar la versión.

Las herramientas de .NET Core que se encuentran en versión preliminar deben especificarse con una parte del
nombre para indicar que están en versión preliminar. No es necesario incluir todo el nombre de la versión
preliminar. Si los números de versión tienen el formato esperado, puede usar algo parecido al ejemplo siguiente:
dotnet tool install -g --version 1.1.0-pre <toolName>

NOTE
El equipo de la CLI de .NET Core está planeando agregar un modificador --preview en una versión futura para facilitar esta
tarea.

El paquete no es una herramienta de .NET Core


Se encontró un paquete NuGet con este nombre, pero no era una herramienta .NET Core.
Si intenta instalar un paquete normal de NuGet que no es una herramienta de .NET Core, verá un error similar al
siguiente:

NU1212: combinación de paquete de proyecto no válida para <ToolName> . El estilo de proyecto


DotnetToolReference solo puede contener referencias de tipo DotnetTool.

No se puede acceder a la fuente NuGet


No se puede acceder a la fuente NuGet necesaria, quizás debido a un problema con la conexión a Internet.
La instalación de la herramienta requiere acceso a la fuente NuGet que contiene el paquete de la herramienta. Se
produce un error si la fuente no está disponible. Puede modificar las fuentes con nuget.config , solicitar un archivo
nuget.config determinado o especificar fuentes adicionales con el modificador --add-source . De forma
predeterminada, NuGet genera un error para cualquier fuente con la que no pueda conectar. La marca
--ignore-failed-sources puede omitir estos orígenes no accesibles.

Identificador de paquete incorrecto


No ha escrito correctamente el nombre de la herramienta.
Un motivo habitual de error es que el nombre de la herramienta no es correcto. Esto puede ocurrir cuando se
produce un error de escritura, o porque la herramienta se ha movido o está en desuso. En el caso de las
herramientas de NuGet.org, una manera de asegurarse de que tiene el nombre correcto es buscar la herramienta
en NuGet.org y copiar el comando de instalación.

Vea también
Información general sobre las herramientas globales de .NET Core
Acceso con privilegios elevados para comandos de
dotnet
23/10/2019 • 8 minutes to read • Edit Online

Los procedimientos recomendados de desarrollo de software sirven de guía a los desarrolladores para escribir
software que requiera la menor cantidad de privilegios. Sin embargo, algunos programas, como las herramientas
de supervisión de rendimiento, requieren permiso del administrador debido a las reglas del sistema operativo. En
las siguientes instrucciones se describen los escenarios admitidos para escribir dicho software con .NET Core.
Los siguientes comandos se pueden ejecutar con privilegios elevados:
Comandos dotnet tool , como dotnet tool install.
dotnet run --no-build

No se recomienda ejecutar otros comandos con privilegios elevados. En concreto, no se recomienda usar
privilegios elevados con los comandos que usa MSBuild, como dotnet restore, dotnet build y dotnet run. Los
problemas de administración de permisos son el principal problema cuando un usuario cambia varias veces entre
una cuenta restringida y otra raíz después de emitir comandos de dotnet. Como usuario restringido, es posible que
no tenga acceso al archivo generado por un usuario raíz. Hay maneras de resolver esta situación, pero, para
empezar, no es necesario que surjan.
Puede ejecutar comandos como raíz siempre y cuando no cambie repetidas veces entre una cuenta restringida y
otra raíz. Por ejemplo, los contenedores de Docker se ejecutan como raíz de forma predeterminada, por lo que
tienen esta característica.

Instalación de herramienta global


Las instrucciones siguientes muestran la manera recomendada para instalar, ejecutar y desinstalar las herramientas
de .NET Core que requieren privilegios elevados para ejecutarse.
Windows
Linux
macOS
Instalación de la herramienta global
Si la carpeta %ProgramFiles%\dotnet-tools ya existe, siga este procedimiento para comprobar si el grupo
"Usuarios" tiene permiso para escribir o modificar ese directorio:
Haga clic con el botón derecho en la carpeta %ProgramFiles%\dotnet-tools y seleccione Propiedades. Se abrirá
el cuadro de diálogo Propiedades comunes.
Seleccione la pestaña Seguridad. En Nombres de grupos o usuarios, compruebe si el grupo "Usuarios" tiene
permiso para escribir o modificar el directorio.
Si el grupo "Usuarios" puede escribir o modificar el directorio, al instalar las herramientas, use otro nombre de
directorio de dotnet-tools.
Para instalar las herramientas, ejecute el siguiente comando en un símbolo del sistema con privilegios elevados.
Creará la carpeta dotnet-tools durante la instalación.

dotnet tool install PACKAGEID --tool-path "%ProgramFiles%\dotnet-tools".


Ejecución de la herramienta global
Opción 1 Use la ruta de acceso completa con privilegios elevados:

"%ProgramFiles%\dotnet-tools\TOOLCOMMAND"

Opción 2 Agregue la carpeta recién creada a %Path% . Solo necesita realizar esta operación una vez.

setx Path "%Path%;%ProgramFiles%\dotnet-tools\"

Y ejecute con:

TOOLCOMMAND

Desinstalación de la herramienta global


En un símbolo del sistema con privilegios elevados, escriba el siguiente comando:

dotnet tool uninstall PACKAGEID --tool-path "%ProgramFiles%\dotnet-tools"

Herramientas locales
Las herramientas locales se limitan al árbol de subdirectorio, por usuario. Cuando se ejecutan con privilegios
elevados, las herramientas locales comparten un entorno de usuario con privilegios restringidos en el entorno con
privilegios elevados. En Linux y macOS, esto da como resultado archivos que establecen con acceso de solo
usuario raíz. Si el usuario cambia a una cuenta restringida, el usuario ya no podrá acceder a los archivos ni escribir
en ellos. Por tanto, no se recomienda instalar las herramientas que necesiten permisos elevados como
herramientas locales. En su lugar, use la opción --tool-path y las instrucciones anteriores para las herramientas
globales.

Elevación durante el desarrollo


Durante el desarrollo, puede que necesite acceso con privilegios elevados para probar la aplicación. Este escenario
es común para las aplicaciones de IoT, por ejemplo. Se recomienda que compile la aplicación sin la elevación y, a
continuación, la ejecute con privilegios elevados. Hay unos pocos patrones, como los siguientes:
Uso de archivo ejecutable generado (proporciona el mejor rendimiento de inicio):

dotnet build
sudo ./bin/Debug/netcoreapp3.0/APPLICATIONNAME

Mediante el comando dotnet run con la marca —no-build para evitar que se generen nuevos archivos
binarios:

dotnet build
sudo dotnet run --no-build

Vea también
Información general sobre las herramientas globales de .NET Core
Modelo de extensibilidad de las herramientas de la
CLI de .NET Core
12/01/2020 • 16 minutes to read • Edit Online

En este documento se tratan las maneras diferentes en las que puede ampliar las herramientas de la interfaz de la
línea de comandos (CLI) de .NET Core y se explican los escenarios que impulsan cada una de ellas. Verá cómo
usar las herramientas así como la manera de crear los diferentes tipos de herramientas.

Cómo extender las herramientas de la CLI


Las herramientas de la CLI pueden extenderse de tres maneras principales:
1. A través de paquetes NuGet por proyecto
Las herramientas por proyecto se incluyen en el contexto del proyecto, pero permiten la instalación fácil
mediante la restauración.
2. A través de paquetes NuGet con destinos personalizados
Los destinos personalizados permiten extender fácilmente el proceso de compilación con tareas
personalizadas.
3. A través de la RUTA DE ACCESO del sistema
Las herramientas basadas en la RUTA DE ACCESO son buenas para herramientas entre proyectos
generales que se pueden usar en una sola máquina.
Los tres mecanismos de extensibilidad descritos anteriormente no son exclusivos. Puede usar uno, o todos, o una
combinación de ellos. La selección de uno u otro depende en gran medida del objetivo que intenta alcanzar con su
extensión.

Extensibilidad por proyecto


Las herramientas por proyecto son implementaciones dependientes del marco que se distribuyen como paquetes
NuGet. Las herramientas solo están disponibles en el contexto del proyecto que les hace referencia y para el que
se restauran. La invocación fuera del contexto del proyecto (por ejemplo, fuera del directorio que contiene el
proyecto) producirá un error porque el comando no puede encontrarse.
Estas herramientas son perfectas para servidores de compilación, dado que no se necesita nada fuera del archivo
de proyecto. El proceso de compilación ejecuta la restauración para el proyecto que se compila y hay herramientas
disponibles. Los proyectos de lenguajes, como F#, también están en esta categoría ya que cada proyecto solo se
puede escribir en un lenguaje específico.
Finalmente, este modelo de extensibilidad proporciona compatibilidad con la creación de herramientas que
necesitan acceso a la salida compilada del proyecto. Por ejemplo, varias herramientas de vista de Razor de
aplicaciones ASP.NET MVC se incluyen dentro de esta categoría.
Consumo de herramientas por proyecto
Para consumir estas herramientas es necesario agregar un elemento <DotNetCliToolReference> a su archivo del
proyecto para cada herramienta que quiera usar. Dentro del elemento <DotNetCliToolReference> , se hace
referencia al paquete en el que reside la herramienta y se especifica la versión necesaria. Después de ejecutar
dotnet restore , se restauran la herramienta y sus dependencias.
NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

Para las herramientas que necesitan cargar la salida de compilación del proyecto para su ejecución, hay
normalmente otra dependencia que aparece en las dependencias normales del archivo de proyecto. Como la CLI
usa MSBuild como motor de compilación, recomendamos que estas partes de la herramienta se escriban como
destinos y tareas de MSBuild personalizados, ya que pueden formar parte del proceso de compilación general.
Además, pueden obtener fácilmente todos y cada uno de los datos que se producen mediante la compilación,
como la ubicación de los archivos de salida, la configuración actual que se compila, etc. Toda esta información se
convierte en un conjunto de propiedades de MSBuild que se puede leer desde cualquier destino. Más adelante en
este documento puede ver cómo agregar un destino personalizado mediante NuGet.
Vamos a ver un ejemplo de cómo agregar una herramienta sencilla tools-only a un proyecto sencillo. Dado un
comando de ejemplo llamado dotnet-api-search que le permite examinar los paquetes de NuGet hasta encontrar
la API especificada, este es un archivo de proyecto de la aplicación de consola que usa esa herramienta:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<!-- The tools reference -->


<ItemGroup>
<DotNetCliToolReference Include="dotnet-api-search" Version="1.0.0" />
</ItemGroup>
</Project>

El elemento <DotNetCliToolReference> está estructurado de forma similar al elemento <PackageReference> .


Necesita el identificador del paquete que contiene la herramienta y su versión para que pueda realizarse la
restauración.
Compilación de herramientas
Como se ha mencionado, las herramientas son simples aplicaciones de consola portátiles. Compila herramientas
como lo haría en cualquier otra aplicación de consola. Después de compilarla, puede usar el comando
dotnet pack para crear un paquete de NuGet (archivo .nupkg) que contiene el código e información sobre sus
dependencias, entre otros. Puede proporcionar cualquier nombre al paquete, pero la aplicación que contiene, el
archivo binario de la herramienta real, debe respetar las convenciones de dotnet-<command> para que dotnet
pueda invocarlo.

NOTE
En las versiones anteriores a RC3 de las herramientas de línea de comandos de .NET Core, el comando dotnet pack tenía
un error que provocaba que .runtimeconfig.json no se empaquetase con la herramienta. La falta de dicho archivo provoca
errores en tiempo de ejecución. Si se produce este comportamiento, asegúrese de actualizar a las últimas herramientas y
pruebe dotnet pack nuevo.

Como las herramientas son aplicaciones portátiles, el usuario que las consume debe tener la versión de las
bibliotecas .NET Core con la que se ha compilado la herramienta para poder ejecutar esta. Cualquier otra
dependencia que use la herramienta y que no esté contenida en las bibliotecas .NET Core se restauran y colocan
en la caché de NuGet. Por lo tanto, la herramienta entera se ejecuta con los ensamblados de las bibliotecas .NET
Core, así como los ensamblados de la caché de NuGet.
Estas clases de herramientas tienen un gráfico de dependencias que es completamente independiente del gráfico
de dependencias del proyecto que los usa. El proceso de restauración restaura primero las dependencias del
proyecto y, después, cada una de las herramientas y sus dependencias.
Puede encontrar más ejemplos y diferentes combinaciones de esto en el repositorio de la CLI de .NET Core.
También puede ver las herramientas de implementación usadas en el mismo repositorio.

Destinos personalizados
NuGet tiene la capacidad de empaquetar archivos de propiedades y destinos de MSBuild personalizados. Con el
paso de las herramientas de la CLI de .NET Core para usar MSBuild, el mismo mecanismo de extensibilidad se
aplica ahora en proyectos de .NET Core. Este tipo de extensibilidad se usaría cuando quisiera extender el proceso
de compilación o quisiera acceder a alguno de los artefactos de dicho proceso, como los archivos generados, o si
quiere inspeccionar la configuración bajo la que se invoca la compilación, etc.
En el ejemplo siguiente, puede ver el archivo del proyecto de destino con la sintaxis csproj . Esto indica al
comando dotnet pack qué empaquetar, colocando los archivos de destinos así como los ensamblados en la
carpeta build dentro del paquete. Observe el elemento <ItemGroup> que tiene la propiedad Label establecida en
dotnet pack instructions , y el destino que se define por debajo.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Sample Packer</Description>
<VersionPrefix>0.1.0-preview</VersionPrefix>
<TargetFramework>netstandard1.3</TargetFramework>
<DebugType>portable</DebugType>
<AssemblyName>SampleTargets.PackerTarget</AssemblyName>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Pkg\dist-template.xml;compiler\resources\**\*"
Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<None Include="build\SampleTargets.PackerTarget.targets" />
</ItemGroup>
<ItemGroup Label="dotnet pack instructions">
<Content Include="build\*.targets">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
<Target Name="CollectRuntimeOutputs" BeforeTargets="_GetPackageFiles">
<!-- Collect these items inside a target that runs after build but before packaging. -->
<ItemGroup>
<Content Include="$(OutputPath)\*.dll;$(OutputPath)\*.json">
<Pack>true</Pack>
<PackagePath>build\</PackagePath>
</Content>
</ItemGroup>
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.0.1-beta-000933"/>
<PackageReference Include="Microsoft.Build.Framework" Version="0.1.0-preview-00028-160627" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="0.1.0-preview-00028-160627" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup />
<PropertyGroup Label="Globals">
<ProjectGuid>463c66f0-921d-4d34-8bde-7c9d0bffaf7b</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<DefineConstants>$(DefineConstants);NETSTANDARD1_3</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
</PropertyGroup>
</Project>

Para consumir destinos personalizados se proporciona un elemento <PackageReference> que apunta al paquete y
su versión dentro del proyecto que se extiende. A diferencia de las herramientas, el paquete de destinos
personalizados se incluye en el cierre de dependencia del proyecto de consumo.
El uso del destino personalizado depende exclusivamente de cómo se configure. Como es un destino de MSBuild,
puede depender de un destino dado, ejecutarse después de otro destino e invocarse también manualmente
mediante el comando dotnet msbuild -t:<target-name> .
En cambio, si quiere proporcionar una mejor experiencia de usuario, puede combinar las herramientas por
proyecto y los destinos personalizados. En este escenario, la herramienta por proyecto básicamente solo aceptaría
todos los parámetros necesarios y lo traduciría en la invocación de dotnet msbuild necesaria que ejecutaría el
destino. Puede ver una muestra de esta clase de sinergia en el repositorio de ejemplos de MVP Summit 2016
Hackathon del proyecto dotnet-packer .

Extensibilidad basada en la RUTA DE ACCESO


La extensibilidad basada en la RUTA DE ACCESO se suele usar con equipos de desarrollo, donde necesita una
herramienta que abarque conceptualmente más de un único proyecto. La principal desventaja de este mecanismo
de extensión es que está vinculado a la máquina donde existe la herramienta. Si lo necesita en otro equipo, tendría
que implementarlo.
Este patrón de extensibilidad del conjunto de herramientas de la CLI es muy sencillo. Como se explica en la
información general de la CLI de .NET Core, el controlador dotnet puede ejecutar cualquier comando que se
nombre según la convención dotnet-<command> . La lógica de resolución predeterminada sondea primero varias
ubicaciones y finalmente vuelve a la RUTA DE ACCESO del sistema. Si el comando solicitado existe en la RUTA
DE ACCESO del sistema y es un archivo binario que se puede invocar, el controlador dotnet lo invoca.
El archivo debe ser ejecutable. En sistemas Unix, esto significa todo lo que tiene el bit de ejecución establecido
mediante chmod +x . En Windows, puede usar archivos cmd.
Echemos un vistazo a una implementación muy sencilla de una herramienta "Hola mundo". Usaremos bash y
cmd en Windows. En el siguiente comando simplemente reflejaremos "Hola mundo" en la consola.

#!/bin/bash

echo "Hello World!"

echo "Hello World"

En macOS, podemos guardar este script como dotnet-hello y establecer su bit ejecutable con
chmod +x dotnet-hello . Luego, podemos crear un vínculo simbólico a él en /usr/local/bin con el comando
ln -s <full_path>/dotnet-hello /usr/local/bin/ . De esta manera se podrá invocar el comando mediante la
sintaxis dotnet hello .
En Windows, podemos guardar este script como dotnet-hello.cmd y colocarlo en una ubicación que esté en una
ruta de acceso del sistema (o puede agregarlo en una carpeta que ya se encuentre en la ruta de acceso). Después
de esto, simplemente puede usar dotnet hello para ejecutar este ejemplo.
Plantillas personalizadas para dotnet new
04/11/2019 • 18 minutes to read • Edit Online

El SDK de .NET Core cuenta con muchas plantillas ya instaladas y listas para su uso. El comando dotnet new no
es solo la forma de usar una plantilla, sino también cómo instalarlas y desinstalarlas. A partir de .NET Core 2.0,
puede crear sus propias plantillas personalizadas para cualquier tipo de proyecto, como una aplicación, un
servicio, una herramienta o una biblioteca de clases. Incluso puede crear una plantilla que genere uno o más
archivos independientes, como un archivo de configuración.
Puede instalar plantillas personalizadas desde un paquete NuGet en cualquier fuente NuGet, haciendo referencia
a un archivo .nupkg de NuGet directamente o especificando un directorio del sistema de archivos que contenga
la plantilla. El motor de plantillas ofrece características que le permiten reemplazar valores, incluir y excluir
archivos y ejecutar operaciones de procesamiento personalizadas cuando se usa la plantilla.
El motor de plantillas es de código abierto, y el repositorio de código en línea está en dotnet/templating en
GitHub. Visite el repositorio dotnet/dotnet-template-samples para obtener ejemplos de plantillas. Puede
encontrar más plantillas, incluidas las plantillas de terceros, en Plantillas disponibles para dotnet new en GitHub.
Para obtener información sobre cómo crear y usar plantillas personalizadas, vea Cómo crear sus propias
plantillas para dotnet new y la Wiki del repositorio de GitHub dotnet/templating.
Para seguir un tutorial y crear una plantilla, vea el tutorial Creación de una plantilla personalizada para dotnet
new.
Plantillas predeterminadas .NET
Cuando instala el SDK de .NET Core, recibe más de una docena de plantillas integradas para crear proyectos y
archivos, incluidas las aplicaciones de consola, bibliotecas de clases, proyectos de prueba unitaria, aplicaciones de
ASP.NET Core (incluidos los proyectos Angular y React), y archivos de configuración. Para enumerar las
plantillas integradas, ejecute el comando dotnet new con la opción -l|--list :

dotnet new --list

Configuración
Una plantilla consta de las siguientes partes:
Archivos de origen y carpetas.
Un archivo de configuración (template.json).
Archivos de origen y carpetas
Los archivos de origen y las carpetas incluyen todos los archivos y carpetas que quiera que el motor de plantilla
use cuando se ejecuta el comando dotnet new <TEMPLATE> . El motor de plantillas está diseñado para usar
proyectos ejecutables como código fuente para generar proyectos. Esto presenta varias ventajas:
El motor de plantillas no necesita que inserte tokens especiales en su código de origen del proyecto.
Los archivos de código no son archivos especiales ni se modifican de ninguna manera para que funcionen
con el motor de plantillas. Por lo tanto, las herramientas que usa normalmente para trabajar con los proyectos
también funcionan con el contenido de la plantilla.
Compile, ejecute y depure sus proyectos de plantilla de la forma en que lo hace para cualquiera de sus otros
proyectos.
Puede crear rápidamente una plantilla de un proyecto existente simplemente agregando un archivo de
configuración ./.template.config/template.json al proyecto.
Los archivos y las carpetas que se almacenan en la plantilla no se limitan a tipos de proyectos .NET formales. Los
archivos de origen y las carpetas pueden constar de cualquier contenido que quiera crear cuando se use la
plantilla, incluso si el motor de plantillas genera solo un archivo como su salida.
Los archivos que genera la plantilla se pueden modificar según la lógica y la configuración que ha proporcionado
en el archivo de configuración template.json. El usuario puede invalidar esta configuración pasando las opciones
al comando dotnet new <TEMPLATE> . Un ejemplo común de una lógica personalizada es proporcionar un nombre
para una clase o variable en el archivo de código que se implementa mediante una plantilla.
template.json
El archivo template.json se coloca en una carpeta .template.config en el directorio raíz de la plantilla. El archivo
proporciona información de configuración al motor de plantillas. La configuración mínima necesita los miembros
que se muestran en la tabla siguiente, que es suficiente para crear una plantilla funcional.

MIEMBRO TIPO DESCRIPCIÓN

$schema Identificador URI El esquema JSON para el archivo


template.json. Los editores que
admiten los esquemas JSON habilitan
las características de edición JSON
cuando se especifica el esquema. Por
ejemplo, Visual Studio Code necesita
este miembro para habilitar
IntelliSense. Use un valor de
http://json.schemastore.org/template
.

author cadena El autor de la plantilla.

classifications array(string) Cero o más características de la


plantilla que un usuario puede usar
para buscar la plantilla al buscarla. Las
clasificaciones también aparecen en la
columna Etiquetas cuando aparece en
una lista de plantillas que se han
generado mediante el comando
dotnet new -l|--list .

identity cadena Un nombre único para esta plantilla.

name cadena El nombre de la plantilla que los


usuarios deben ver.

shortName cadena Un nombre abreviado predeterminado


para seleccionar la plantilla que se
aplica a entornos donde el usuario
especifica el nombre de la plantilla; no
se selecciona mediante una GUI. Por
ejemplo, un nombre abreviado es útil al
usar plantillas desde un símbolo del
sistema con comandos de la CLI.

El esquema completo del archivo template.json puede encontrarse en el Almacenamiento del esquema JSON.
Para más información sobre el archivo template.json, consulte la wiki de plantillas dotnet.
Ejemplo
Por ejemplo, esta es una carpeta de plantillas que tiene dos archivos de contenido: console.cs y readme.txt. Tenga
en cuenta que existe la carpeta requerida denominada .template.config que contiene el archivo template.json.

└───mytemplate
│ console.cs
│ readme.txt

└───.template.config
template.json

El archivo template.json tiene un aspecto parecido al siguiente:

{
"$schema": "http://json.schemastore.org/template",
"author": "Travis Chau",
"classifications": [ "Common", "Console" ],
"identity": "AdatumCorporation.ConsoleTemplate.CSharp",
"name": "Adatum Corporation Console Application",
"shortName": "adatumconsole"
}

La carpeta mytemplate es un paquete de plantilla instalable. Una vez instalado el paquete, shortName se puede
utilizar con el comando dotnet new . Por ejemplo, dotnet new adatumconsole generaría los archivos console.cs y
readme.txt en la carpeta actual.

Empaquetar una plantilla en un paquete NuGet (archivo nupkg)


Una plantilla personalizada se empaqueta con el comando la dotnet pack y un archivo .csproj. Como alternativa,
se puede usar NuGet con el comando nuget pack junto con un archivo .nuspec. Sin embargo, NuGet requiere
.NET Framework en Windows y Mono en Linux y MacOS.
El archivo .csproj es ligeramente diferente al archivo .csproj de un proyecto de código tradicional. Tenga en
cuenta la siguiente configuración:
1. El valor <PackageType> se agrega y se establece en Template .
2. El valor <PackageVersion> se agrega y establece en un número de versión de NuGet.
3. El valor <PackageId> se agrega y se establece en un identificador único. Este identificador se usa para
desinstalar el paquete de plantillas y lo usan las fuentes NuGet para registrar su paquete de plantillas.
4. Se debe establecer la configuración de metadatos genérica: <Title> , <Authors> , <Description> y
<PackageTags> .
5. Debe establecerse la configuración <TargetFramework> , aunque no se usen los datos binarios generados por el
proceso de la plantilla. En el ejemplo siguiente se establece en netstandard2.0 .
Un paquete de plantillas, en forma de un paquete NuGet .nupkg, requiere que todas las plantillas se almacenan
en la carpeta content dentro del paquete. Hay algunas opciones de configuración más para agregar a un archivo
.csproj para asegurarse de que el paquete .nupkg generado se puede instalar como un paquete de plantilla:
1. El valor <IncludeContentInPack> se establece en true para incluir cualquier archivo que el proyecto establece
como content en el paquete NuGet.
2. El valor <IncludeBuildOutput> se establece en false para excluir todos los archivos binarios generados por
el compilador desde el paquete NuGet.
3. El valor <ContentTargetFolders> se establece en content . Esto garantiza que los archivos establecidos como
content se almacenan en la carpeta content carpeta en el paquete NuGet. Esta carpeta del paquete NuGet la
analiza el sistema de plantillas dotnet.
Una manera sencilla de excluir todos los archivos de código para que el proyecto de su plantilla no los compile es
usando el elemento <Compile Remove="**\*" /> del archivo de proyecto, dentro de un elemento <ItemGroup> .
Una manera sencilla de estructurar su paquete de plantillas es colocar todas las plantillas en carpetas
individuales y luego cada carpeta de plantillas dentro de una carpeta templates que se encuentra en el mismo
directorio que el archivo .csproj . De esta manera, puede usar un solo elemento del proyecto para incluir todos
los archivos y carpetas en templates como content. Dentro de un elemento <ItemGroup> , cree un elemento
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" /> .

Este es un archivo .csproj de ejemplo que sigue todas las pautas anteriores. Empaqueta la carpeta secundaria
templates en la carpeta del paquete content y excluye cualquier archivo de código de la compilación.

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageType>Template</PackageType>
<PackageVersion>1.0</PackageVersion>
<PackageId>AdatumCorporation.Utility.Templates</PackageId>
<Title>AdatumCorporation Templates</Title>
<Authors>Me</Authors>
<Description>Templates to use when creating an application for Adatum Corporation.</Description>
<PackageTags>dotnet-new;templates;contoso</PackageTags>
<TargetFramework>netstandard2.0</TargetFramework>

<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
</PropertyGroup>

<ItemGroup>
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
<Compile Remove="**\*" />
</ItemGroup>

</Project>

En el siguiente ejemplo se muestra la estructura de archivos y carpetas de usar .csproj para crear un paquete de
plantillas. El archivo MyDotnetTemplates.csproj y la carpeta templates se encuentran en la raíz de un directorio
denominado project_folder. La carpeta templates contiene dos plantillas: mytemplate1 y mytemplate2. Cada
plantilla tiene archivos de contenido y una carpeta .template.config con un archivo de configuración
template.json.

project_folder
│ MyDotnetTemplates.csproj

└───templates
├───mytemplate1
│ │ console.cs
│ │ readme.txt
│ │
│ └───.template.config
│ template.json

└───mytemplate2
│ otherfile.cs

└───.template.config
template.json

Instalar una plantilla


Use el comando dotnet new -i|--install para instalar un paquete.
Para instalar una plantilla de un paquete NuGet almacenado en nuget.org
Use el identificador del paquete NuGet para instalar un paquete de plantillas.

dotnet new -i <NUGET_PACKAGE_ID>

Para instalar una plantilla de un archivo nupkg local


Proporcione la ruta de acceso a un archivo de paquete NuGet .nupkg.

dotnet new -i <PATH_TO_NUPKG_FILE>

Para instalar una plantilla desde un directorio de sistema de archivos


Las plantillas se pueden instalar desde una carpeta de plantillas, como la carpeta mytemplate1 del ejemplo
anterior. Especifique la ruta de acceso de la carpeta .template.config. La ruta de acceso al directorio de plantillas
no es necesario que sea absoluto. Sin embargo, se requiere una ruta de acceso absoluta para desinstalar una
plantilla que se instala desde una carpeta.

dotnet new -i <FILE_SYSTEM_DIRECTORY>

Obtención de una lista de plantillas instaladas


El comando de desinstalación, sin ningún otro parámetro, enumerará todas las plantillas instaladas.

dotnet new -u

Ese comando devuelve algo similar a la salida siguiente:

Template Instantiation Commands for .NET Core CLI

Currently installed items:


Microsoft.DotNet.Common.ItemTemplates
Templates:
global.json file (globaljson)
NuGet Config (nugetconfig)
Solution File (sln)
Dotnet local tool manifest file (tool-manifest)
Web Config (webconfig)
Microsoft.DotNet.Common.ProjectTemplates.3.0
Templates:
Class library (classlib) C#
Class library (classlib) F#
Class library (classlib) VB
Console Application (console) C#
Console Application (console) F#
Console Application (console) VB
...

El primer nivel de los elementos situados después de Currently installed items: son los identificadores usados
en la desinstalación de una plantilla. Y en el ejemplo anterior, se enumeran
Microsoft.DotNet.Common.ItemTemplates y Microsoft.DotNet.Common.ProjectTemplates.3.0 . Si la plantilla se instaló
mediante una ruta de acceso del sistema de archivos, este identificador será la ruta de acceso de la carpeta
.template.config.
Desinstalación de una plantilla
Use el comando dotnet new -u|--uninstall para desinstalar un paquete.
Si el paquete lo instaló una fuente de NuGet o un archivo .nupkg directamente, proporcione el identificador.

dotnet new -u <NUGET_PACKAGE_ID>

Si el paquete se instaló mediante la especificación de una ruta de acceso a la carpeta .template.config, use esa
ruta de acceso absoluta para desinstalar el paquete. Puede ver la ruta de acceso absoluta de la plantilla en el
resultado proporcionado por el comando dotnet new -u . Para obtener más información, consulte la sección
Obtención de una lista de plantillas instaladas anterior.

dotnet new -u <ABSOLUTE_FILE_SYSTEM_DIRECTORY>

Crear un proyecto con una plantilla personalizada


Después de que se instale una plantilla, use la plantilla ejecutando el comando dotnet new <TEMPLATE> como lo
haría con cualquier otra plantilla preinstalada. También puede especificar opciones en el comando dotnet new ,
incluidas las opciones específicas de plantilla que ha definido en la configuración de la plantilla. Proporcione el
nombre breve de la plantilla directamente al comando:

dotnet new <TEMPLATE>

Vea también
Creación de una plantilla personalizada para dotnet new (tutorial)
Wiki del repositorio de GitHub dotnet/templating
Repositorio de GitHub dotnet/dotnet-template-samples
How to create your own templates for dotnet new (Cómo crear sus propias plantillas para dotnet new )
Esquema template.json en el Almacenamiento del esquema JSON
Cómo habilitar la finalización con tabulación para la
CLI de .NET Core
10/11/2019 • 4 minutes to read • Edit Online

A partir del SDK de .NET Core 2.0, la CLI de .NET Core admite la finalización con tabulación. En este artículo se
describe cómo configurar la finalización con tabulación para tres shells: PowerShell, Bash y zsh. Otros shells
pueden tener compatibilidad con la finalización automática. Consulte su documentación sobre cómo configurar la
finalización automática, los pasos deben ser similares a los que se describen en este artículo.
Este artículo se aplica a: ✓ SDK de .NET Core 2.x
Una vez configurada, para desencadenar la finalización con tabulación para la CLI de .NET Core, escriba un
comando dotnet en el shell y, después, presione el tabulador. La línea de comandos que se envía al comando
dotnet complete y los resultados se procesan mediante el shell. Puede probar los resultados sin habilitar la
finalización con tabulación si envía algo directamente al comando dotnet complete . Por ejemplo:

> dotnet complete "dotnet a"


add
clean
--diagnostics
migrate
pack

Si ese comando no funciona, asegúrese de que está instalado el SDK de .NET Core 2.0 o una versión superior. Si
está instalado, pero el comando sigue sin funcionar, asegúrese de que dotnet se resuelva como mínimo en la
versión 2.0 del SDK de .NET Core. Use el comando dotnet --version para ver en qué versión de dotnet se
resuelve la ruta de acceso actual. Para obtener más información, vea Selección de la versión de .NET Core que se
va a usar.
Ejemplos
Estos son algunos ejemplos de lo que proporciona la finalización con tabulación:

ENTRADA SE CONVIERTE EN PORQUE

dotnet a ⇥ dotnet add add es el primer subcomando, por


orden alfabético.

dotnet add p ⇥ dotnet add --help La finalización con tabulación hace


coincidir las subcadenas y --help
aparece primero alfabéticamente.

dotnet add p ⇥⇥ dotnet add package Al presionar la tecla Tab una segunda
vez aparece la siguiente sugerencia.

dotnet add package Microsoft ⇥ dotnet add package Los resultados se devuelven por orden
Microsoft.ApplicationInsights.Web alfabético.

dotnet remove reference ⇥ dotnet remove reference La finalización con tabulación es


..\..\src\OmniSharp.DotNet\OmniSharp.DotNet.csproj
compatible con archivos de proyecto.
PowerShell
Para agregar finalización con tabulación a PowerShell para la CLI de .NET Core, cree o edite el perfil almacenado
en la variable $PROFILE . Para obtener más información, vea Cómo crear el perfil y Los perfiles y la directiva de
ejecución.
Agregue el código siguiente al perfil:

# PowerShell parameter completion shim for the dotnet CLI


Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
param($commandName, $wordToComplete, $cursorPosition)
dotnet complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}

Bash
Para agregar finalización con tabulación al shell de bash para la CLI de .NET Core, agregue el código siguiente al
archivo .bashrc :

# bash parameter completion for the dotnet CLI

_dotnet_bash_complete()
{
local word=${COMP_WORDS[COMP_CWORD]}

local completions
completions="$(dotnet complete --position "${COMP_POINT}" "${COMP_LINE}" 2>/dev/null)"
if [ $? -ne 0 ]; then
completions=""
fi

COMPREPLY=( $(compgen -W "$completions" -- "$word") )


}

complete -f -F _dotnet_bash_complete dotnet

zsh
Para agregar finalización con tabulación al shell de zsh para la CLI de .NET Core, agregue el código siguiente al
archivo .zshrc :

# zsh parameter completion for the dotnet CLI

_dotnet_zsh_complete()
{
local completions=("$(dotnet complete "$words")")

reply=( "${(ps:\n:)completions}" )
}

compctl -K _dotnet_zsh_complete dotnet


Telemetría del SDK de .NET Core
20/01/2020 • 10 minutes to read • Edit Online

El SDK de .NET Core incluye una característica de telemetría que recopila datos de uso e información de excepción
cuando se bloquea el CLI de .NET Core. El CLI de .NET Core incluye el SDK de .NET Core y es el conjunto de
verbos que permiten compilar, probar y publicar las aplicaciones de .NET Core. Es importante que el equipo de
.NET entienda cómo se usan las herramientas con el fin de mejorarlas. Con la información sobre los errores, el
equipo consigue resolver problemas y corregir errores.
Los datos recopilados son anónimos y se publican de forma agregada bajo la licencia de atribución de Creative
Commons.

Ámbito
dotnet tiene dos funciones: ejecutar aplicaciones y ejecutar comandos de la CLI. La telemetría no se recopila
cuando se usa dotnet para iniciar una aplicación con el siguiente formato:
dotnet [path-to-app].dll

La telemetría se recopila cuando se usa cualquiera de los comandos de la CLI de .NET Core, como:
dotnet build
dotnet pack
dotnet run

Cómo desactivar la característica


La característica de telemetría del SDK de .NET Core está habilitada de manera predeterminada. Para desactivar la
característica de telemetría, establezca la variable de entorno DOTNET_CLI_TELEMETRY_OPTOUT en 1 o true .
El instalador del SDK de .NET Core también envía una única entrada de telemetría cuando se produce una
instalación correcta. Para desactivarla, establezca la variable de entorno de DOTNET_CLI_TELEMETRY_OPTOUT antes de
instalar el SDK de .NET Core.

Divulgación
El SDK de .NET Core muestra texto similar al siguiente cuando se ejecuta por primera vez uno de los comandos de
la CLI de .NET Core (por ejemplo, dotnet build ). El texto puede variar ligeramente según la versión del SDK que
ejecute. Esta experiencia de "primera vista" es la forma en que Microsoft le notifica sobre la recopilación de datos.

Telemetry
---------
The .NET Core tools collect usage data in order to help us improve your experience. The data is anonymous. It
is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the
DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.

Read more about .NET Core CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry

Puntos de datos
La característica de telemetría no recopila datos personales, como direcciones de correo electrónico o nombres de
usuario. No examina el código ni extrae datos de nivel de proyecto, como el nombre, el repositorio o el autor. Los
datos se envían de forma segura a los servidores de Microsoft con tecnología de Azure Monitor, se conservan bajo
acceso restringido y se publican bajo controles de seguridad estrictos de sistemas seguros de Azure Storage.
La protección de su privacidad es importante para nosotros. Si sospecha que la telemetría está recopilando datos
confidenciales o que los datos se están tratando de forma no segura o inapropiada, informe de un problema en el
repositorio de dotnet/cli o envíenos un correo electrónico a dotnet@microsoft.com para que lo investiguemos.
La característica de telemetría recopila los siguientes datos:

VERSIONES DEL SDK DATOS

Todas Marca de tiempo de la invocación.

Todas Comando invocado (por ejemplo, "build"), con hash a partir de


2.1.

Todas Dirección IP de tres octetos usada para determinar la


ubicación geográfica.

Todas Sistema operativo y versión.

Todas Identificador de tiempo de ejecución (RID) en el que se ejecuta


el SDK.

Todas Versión del SDK de .NET Core.

Todas Perfil de telemetría: valor opcional usado internamente en


Microsoft y que solo se usa con la participación explícita del
usuario.

>=2.0 Opciones y argumentos del comando: se recopilan varias


opciones y argumentos (no cadenas arbitrarias). Vea opciones
recopiladas. Con hash a partir de la versión 2.1.300.

>=2.0 Si el SDK se ejecuta en un contenedor.

>=2.0 Plataformas de destino (desde el evento TargetFramework ),


con hash a partir de 2.1.

>=2.0 Dirección MAC con hash: identificador único y anónimo


criptográficamente (SHA256) para una máquina.

>=2.0 Directorio de trabajo actual con hash.

>=2.0 Informe de instalación correcta, con el nombre de archivo exe


del instalador con hash.

>=2.1.300 Versión de kernel.

>=2.1.300 Versión/versión de libc.

>=3.0.100 Indica si la salida se redirigió (true o false).


VERSIONES DEL SDK DATOS

>=3.0.100 En un bloqueo de CLI/SDK, el tipo de excepción y su


seguimiento de pila (solo el código de CLI/SDK se incluye en el
seguimiento de la pila enviado). Para más información, vea
Telemetría de la excepción de bloqueo de SDK/CLI de .NET
Core recopilada.

Opciones recopiladas
Determinados comandos envían datos adicionales. Un subconjunto de comandos envía el primer argumento:

COMANDO DATOS DEL PRIMER ARGUMENTO ENVIADOS

dotnet help <arg> Se está consultando la ayuda del comando.

dotnet new <arg> Nombre de la plantilla (con hash).

dotnet add <arg> La palabra package o reference .

dotnet remove <arg> La palabra package o reference .

dotnet list <arg> La palabra package o reference .

dotnet sln <arg> La palabra add , list o remove .

dotnet nuget <arg> La palabra delete , locals o push .

Un subconjunto de comandos envía las opciones seleccionadas, si se usan, junto con sus valores:

OPCIÓN COMANDOS

--verbosity Todos los comandos

--language dotnet new

--configuration dotnet build , dotnet clean , dotnet publish ,


dotnet run , dotnet test

--framework dotnet build , dotnet clean , dotnet publish ,


dotnet run , dotnet test , dotnet vstest

--runtime dotnet build , dotnet publish

--platform dotnet vstest

--logger dotnet vstest

--sdk-package-version dotnet migrate

A excepción de --verbosity y --sdk-package-version , se aplica un algoritmo hash a los demás valores a partir del
SDK de .NET Core 2.1.100.
Telemetría de la excepción de bloqueo de SDK/CLI de .NET Core
recopilada
Si el SDK/CLI de .NET Core se bloquea, se recopila el nombre de la excepción y el seguimiento de la pila del
código de CLI/SDK. Esta información se recopila para evaluar los problemas y mejorar la calidad del SDK de .NET
Core y la CLI. En este artículo se proporciona información sobre los datos que se recopilan. También se ofrecen
sugerencias para que los usuarios que compilan su propia versión del SDK de .NET Core eviten la divulgación
involuntaria de información personal o confidencial.
Tipos de datos recopilados
El CLI de .NET Core recopila información solo de las excepciones de CLI/SDK, pero no de las excepciones de la
aplicación. Los datos recopilados contienen el nombre de la excepción y el seguimiento de la pila. Este seguimiento
de la pila es del código de CLI/SDK.
En este ejemplo se muestra el tipo de datos que se recopilan:

System.IO.IOException
at System.ConsolePal.WindowsConsoleStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(Char[] buffer)
at System.IO.TextWriter.WriteLine()
at System.IO.TextWriter.SyncTextWriter.WriteLine()
at Microsoft.DotNet.Cli.Utils.Reporter.WriteLine()
at Microsoft.DotNet.Tools.Run.RunCommand.EnsureProjectIsBuilt()
at Microsoft.DotNet.Tools.Run.RunCommand.Execute()
at Microsoft.DotNet.Tools.Run.RunCommand.Run(String[] args)
at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
at Microsoft.DotNet.Cli.Program.Main(String[] args)

Evitar divulgación involuntaria de información


Los colaboradores de .NET Core y cualquier otro usuario que ejecute una versión del SDK de .NET Core compilada
por ellos mismos deben tener en cuenta la ruta de acceso al código fuente del SDK. Si se produce un bloqueo
mientras se usa un SDK de .NET Core que es una compilación de depuración personalizada o está configurado con
archivos de símbolos de compilación personalizados, la ruta de acceso del archivo de origen del SDK desde el
equipo de compilación se recopila como parte del seguimiento de la pila y no tiene un algoritmo hash.
Por este motivo, las compilaciones personalizadas del SDK de .NET Core no deben almacenarse en directorios
cuyos nombres de ruta de acceso expongan información personal o confidencial.

Vea también
Telemetría de la CLI de .NET Core: datos del segundo trimestre de 2019
Fuente de referencia de telemetría (repositorio dotnet/cli)
Información general de global.json
12/01/2020 • 10 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x
El archivo global.json permite definir qué versión del SDK de .NET Core se usa al ejecutar comandos de la CLI de
.NET Core. La selección del SDK de .NET Core es independiente de especificar el runtime al que está destinado el
proyecto. La versión del SDK de .NET Core indica qué versiones de las herramientas de la CLI de .NET Core se
usan. En general, le interesa usar la versión más reciente de las herramientas, por lo que no es necesario ningún
archivo global.json.
Para obtener más información sobre cómo especificar el runtime en su lugar, vea Plataformas de destino.
El SDK de .NET Core busca un archivo global.json en el directorio de trabajo actual (que no es necesariamente el
mismo que el directorio del proyecto) o en uno de sus directorios principales.

Esquema de global.JSON
sdk
Tipo: Object
Especifica información sobre el SDK de .NET Core que se va a seleccionar.
version
Tipo: String
La versión del SDK de .NET Core que se va a usar.
Tenga en cuenta que este campo:
No admite comodines, es decir, se debe especificar el número de versión completo.
No admite intervalos de versiones.
En el ejemplo siguiente se muestra el contenido de un archivo global.json:

{
"sdk": {
"version": "2.2.100"
}
}

global.json y la CLI de .NET Core


Resulta útil saber qué versiones están disponibles con el fin de establecer una en el archivo global.json. Puede
encontrar la lista completa de los SDK disponibles admitidos en la página de descargas de .NET Core. A partir del
SDK de .NET Core SDK 2.1, puede ejecutar el comando siguiente para comprobar qué versiones del SDK ya están
instaladas en el equipo:

dotnet --list-sdks

Para instalar otras versiones del SDK de .NET Core en el equipo, visite la página de descargas de .NET Core.
Puede crear un archivo global.json en el directorio actual mediante la ejecución del comando dotnet new, similar
al ejemplo siguiente:

dotnet new globaljson --sdk-version 2.2.100

Reglas de coincidencia
NOTE
Las reglas de coincidencia se rigen por el host de aplicaciones, que forma parte del runtime de .NET Core. Cuando hay varios
runtimes instalados en paralelo, se usa la versión más reciente del host.

A partir de .NET Core 2.0, se aplican las reglas siguientes al determinar qué versión del SDK se va a usar:
Si no se encuentra ningún archivo global.json o en global.json no se especifica una versión del SDK, se usa la
versión instalada del SDK más reciente. La versión del SDK más reciente puede ser la versión o la versión
preliminar: prevalece el número de versión más alto.
Si global.json especifica una versión del SDK:
Si la versión del SDK especificada se encuentra en el equipo, se usa esa versión exacta.
Si la versión del SDK especificada no se encuentra en el equipo, se usa la versión de revisión del SDK
instalada más reciente de esa versión. La versión de revisión del SDK instalada más reciente puede ser
la versión o la versión preliminar: prevalece el número de versión más alto. En .NET Core 2.1 y
versiones posteriores, las versiones de revisión inferiores a la versión de revisión especificada se
omiten en la selección del SDK.
Si no se encuentra la versión del SDK especificada y una versión de revisión adecuada del SDK, se
produce un error.
Actualmente, la versión del SDK se compone de los elementos siguientes:
[.NET Core major version].[.NET Core minor version].[xyz][-optional preview name]

La versión de características del SDK de .NET Core se representa por medio del primer dígito ( x ) de la última
parte del número ( xyz ) para las versiones 2.1.100 del SDK y posteriores. En general, el SDK de .NET Core tiene
un ciclo de versiones más rápido que .NET Core.
La versión de revisión se define mediante los dos últimos dígitos ( yz ) de la última parte del número ( xyz )
para las versiones 2.1.100 del SDK y posteriores. Por ejemplo, si especifica 2.1.300 como la versión del SDK, la
selección del SDK busca hasta 2.1.399 pero 2.1.400 no se considera una versión de revisión para 2.1.300 .
Las versiones del SDK de .NET Core de 2.1.100 a 2.1.201 se publicaron durante la transición entre las
combinaciones de número de versión y no procesan correctamente la notación xyz . Si estas versiones se
especifican en el archivo global.json, se recomienda encarecidamente asegurarse de que las versiones
especificadas están en los equipos de destino.
Con el SDK 1.x de .NET Core, si se especificaba una versión y no se encontraba ninguna coincidencia exacta, se
usaba la versión del SDK instalada más reciente. La versión del SDK más reciente puede ser la versión o la versión
preliminar: prevalece el número de versión más alto.

Solución de problemas de advertencias de compilación


WARNING
Trabaja con una versión preliminar del SDK de .NET Core. Puede definir la versión del SDK a través de un archivo global.json
en el proyecto actual. Más información en https://go.microsoft.com/fwlink/?linkid=869452.

Esta advertencia indica que el proyecto se está compilando con una versión preliminar del SDK de .NET Core,
como se explica en la sección Reglas de coincidencia. Las versiones del SDK de .NET Core tienen un historial y el
compromiso de ser de alta calidad. Pero si no quiere usar una versión preliminar, agregue un archivo global.json a
la estructura de jerarquía del proyecto para especificar qué versión del SDK se va a utilizar, y use
dotnet --list-sdks para confirmar que la versión está instalada en el equipo. Cuando se publica una versión
nueva, para usarla, quite el archivo global.json o actualícelo para usar la versión más reciente.

WARNING
El proyecto de inicio "{proyectoDeInicio}" está destinado a la versión "{versiónPlataformaDeDestino}" de ".NETCoreApp". Esta
versión de las herramientas de línea de comandos de Entity Framework Core .NET solo admite la versión 2.0 o superior. Para
obtener información sobre el uso de las versiones anteriores de las herramientas, vea https://go.microsoft.com/fwlink/?
linkid=871254

A partir del SDK de .NET Core 2.1 (versión 2.1.300), el comando dotnet ef se incluye en el SDK. Esta advertencia
indica que el proyecto tiene como destino EF Core 1.0 ó 1.1, que no es compatible con el SDK de .NET Core 2.1 y
versiones posteriores. Para compilar el proyecto, instale el SDK de .NET Core 2.0 (versión 2.1.201) y versiones
anteriores en el equipo y defina la versión del SDK deseada mediante el archivo global.json. Para obtener más
información sobre el comando dotnet ef , vea EF Core .NET Command-line Tools (Herramientas de línea de
comandos de EF Core .NET).

Vea también
Resolución de los SDK de proyecto
comando dotnet
23/10/2019 • 21 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet : herramienta para administrar archivos binarios y código fuente de .NET.

Sinopsis
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet [command] [arguments] [--additional-deps] [--additionalprobingpath] [--depsfile]


[-d|--diagnostics] [--fx-version] [-h|--help] [--info] [--list-runtimes] [--list-sdks] [--roll-forward-
on-no-candidate-fx] [--runtimeconfig] [-v|--verbosity] [--version]

DESCRIPCIÓN
dotnet es una herramienta para administrar archivos binarios y código fuente de .NET. Expone los comandos
que realizan tareas específicas, como dotnet build y dotnet run . Cada comando define sus propios
argumentos. Escriba --help después de cada comando para acceder a una breve documentación de ayuda.
dotnet puede usarse para ejecutar aplicaciones si se especifica un archivo DLL de aplicación, como
dotnet myapp.dll . Vea Implementación de aplicaciones .NET Core para obtener información sobre las opciones
de implementación.

Opciones
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
--additional-deps <PATH>

Ruta de acceso a un archivo .deps.json adicional.


--additionalprobingpath <PATH>

Ruta de acceso que contiene directivas de sondeo y ensamblados para sondear.


--depsfile

Ruta de acceso a un archivo deps.json.


Un archivo deps.json contiene una lista de dependencias, dependencias de compilación e información de versión
que se usa para resolver conflictos de ensamblado. Para más información sobre este archivo, vea Runtime
Configuration Files (Archivos de configuración en tiempo de ejecución) en GitHub.
-d|--diagnostics
Habilita la salida de diagnóstico.
--fx-version <VERSION>

Versión del runtime de .NET Core que se va a usar para ejecutar la aplicación.
-h|--help

Imprime la documentación de un comando determinado, como dotnet build --help . dotnet --help imprime
una lista de los comandos disponibles.
--info

Imprime información detallada sobre una instalación de .NET Core y el entorno informático, por ejemplo, el
sistema operativo actual y el SHA de confirmación de la versión de .NET Core.
--list-runtimes

Muestra los tiempos de ejecución de .NET Core instalados.


--list-sdks

Muestra los SDK de .NET Core instalados.


--roll-forward-on-no-candidate-fx <N>

Define el comportamiento cuando el marco de trabajo compartido necesario no está disponible. N puede ser:
0 : se deshabilita la puesta al día incluso de las versiones secundarias.
1 : puesta al día de la versión secundaria, pero no de la versión principal. Éste es el comportamiento
predeterminado.
2 : puesta al día de las versiones principales y secundarias.

Para obtener más información, vea Roll forward (Puesta al día).


--runtimeconfig

Ruta de acceso a un archivo runtimeconfig.json.


Un archivo runtimeconfig.json es un archivo de configuración que contiene los valores de configuración en
tiempo de ejecución. Para más información, vea Runtime Configuration Files (Archivos de configuración en
tiempo de ejecución) en GitHub.
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] . Estos no se admiten en todos los comandos; consulte la página específica de cada
comando para asegurarse de que la opción está disponible.
--version

Imprime la versión del SDK de .NET Core en uso.

comandos de dotnet
General
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
COMANDO FUNCIÓN

dotnet build Compila una aplicación .NET Core.

dotnet build-server Interactúa con servidores iniciados por una compilación.

dotnet clean Limpia las salidas de la compilación.

dotnet help Muestra documentación más detallada en línea sobre el


comando.

dotnet migrate Migra un proyecto de Preview 2 válido a un proyecto del


SDK 1.0 de .NET Core.

dotnet msbuild Proporciona acceso a la línea de comandos de MSBuild.

dotnet new Inicializa un proyecto de C# o F# para una plantilla


determinada.

dotnet pack Crea un paquete de NuGet de su código.

dotnet publish Publica una aplicación dependiente del maco .NET o


autocontenida.

dotnet restore Restaura las dependencias de una aplicación determinada.

dotnet run Ejecuta la aplicación desde el origen.

dotnet sln Opciones para agregar, quitar y mostrar proyectos en un


archivo de solución.

dotnet store Almacena ensamblados en el almacenamiento de paquetes


en tiempo de ejecución.

dotnet test Ejecuta pruebas usando un ejecutor de pruebas.

Referencias de proyecto
COMANDO FUNCIÓN

dotnet add reference Agrega una referencia de proyecto.

dotnet list reference Enumera referencias de proyecto.

dotnet remove reference Quita una referencia de proyecto.

Paquetes NuGet
COMANDO FUNCIÓN

dotnet add package Agrega un paquete NuGet.

dotnet remove package Quita un paquete NuGet.


Comandos NuGet
COMANDO FUNCIÓN

dotnet nuget delete Elimina o quita de la lista un paquete del servidor.

dotnet nuget locals Borra o muestra los recursos de NuGet locales, como la caché
de solicitudes http, la caché temporal o la carpeta de
paquetes global de toda la máquina.

dotnet nuget push Inserta un paquete en el servidor y lo publica.

Comandos de herramientas globales


Las herramientas globales de .NET Core están disponibles a partir del SDK de .NET Core 2.1.300:

COMANDO FUNCIÓN

dotnet tool install Instala una herramienta global en su equipo.

dotnet tool list Enumera todas las herramientas globales instaladas


actualmente en el directorio predeterminado de la máquina o
en la ruta especificada.

dotnet tool uninstall Desinstala una herramienta global de su equipo.

dotnet tool update Actualiza una herramienta global en su equipo.

Herramientas adicionales
A partir del SDK de .NET Core 2.1.300, una serie de herramientas que estaban disponibles solo en función del
proyecto mediante DotnetCliToolReference ahora están disponibles como parte del SDK de .NET Core. Estas
herramientas se muestran en la tabla siguiente:

HERRAMIENTA FUNCIÓN

dev-certs Crea y administra certificados de desarrollo.

ef Herramientas de línea de comandos de Entity Framework


Core.

sql-cache Herramientas de línea de comandos de la caché de SQL


Server.

user-secrets Administra los secretos del usuario de desarrollo.

watch Inicia un monitor de archivos que ejecuta un comando


cuando cambian los archivos.

Para obtener más información sobre cada herramienta, escriba dotnet <tool-name> --help .

Ejemplos
Crea una aplicación de consola de .NET Core:
dotnet new console
Restauración de dependencias de una aplicación determinada:
dotnet restore

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

Compilación de un proyecto y sus dependencias en un directorio determinado:


dotnet build

Ejecutar un archivo DLL de aplicación como myapp.dll :


dotnet myapp.dll

Variables de entorno
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
DOTNET_PACKAGES

La carpeta de paquetes globales. Si no se establece, el valor predeterminado es ~/.nuget/packages en Unix o


%userprofile%\.nuget\packages en Windows.

DOTNET_SERVICING

Especifica la ubicación del índice de mantenimiento que usará el host compartido al cargar el entorno de tiempo
de ejecución.
DOTNET_CLI_TELEMETRY_OPTOUT

Especifica si se recopilan datos sobre el uso de herramientas de .NET Core y se envían a Microsoft. Establézcalo
en true para no participar de la característica de la telemetría (se aceptan los valores true , 1 o yes ). De lo
contrario, establézcalo en false para participar de la característica de la telemetría (se aceptan los valores
false , 0 o no ). Si no se establece, el valor predeterminado es false , y la característica de telemetría está
activa.
DOTNET_MULTILEVEL_LOOKUP

Especifica si desde la ubicación global se resuelve .NET Core Runtime, el marco de trabajo compartido o el SDK.
Si no se establece, el valor predeterminado es true . Se establece en false para no resolverse desde la
ubicación global y tener instalaciones de .NET Core aisladas (se aceptan los valores 0 o false ). Para más
información sobre las búsquedas de varios niveles, vea Multi-level SharedFX Lookup (Búsqueda SharedFX de
varios niveles).
DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX

Deshabilita la puesta al día de versiones secundarias, si está establecido en 0 . Para obtener más información,
vea Roll forward (Puesta al día).
Vea también
Runtime Configuration Files (Archivos de configuración en tiempo de ejecución)
dotnet build
04/11/2019 • 10 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet build : compila un proyecto y todas sus dependencias.

Sinopsis
dotnet build [<PROJECT>|<SOLUTION>] [-c|--configuration] [-f|--framework] [--force]
[--interactive] [--no-dependencies] [--no-incremental] [--no-restore] [--nologo]
[-o|--output] [-r|--runtime] [-v|--verbosity] [--version-suffix]

dotnet build [-h|--help]

DESCRIPCIÓN
El comando dotnet build crea el proyecto y sus dependencias en un conjunto de archivos binarios. Los
archivos binarios incluyen el código del proyecto en archivos de lenguaje intermedio (IL ) con una extensión
.dll. Según el tipo de proyecto y la configuración, se pueden incluir otros archivos, como los siguientes:
Un archivo ejecutable que se pueda usar para ejecutar la aplicación, si el tipo de proyecto es un archivo
ejecutable que tiene como destino .NET Core 3.0 o versiones posteriores.
Archivos de símbolos usados para la depuración con una extensión .pdb.
Un archivo .deps.json, que muestra las dependencias de la aplicación o la biblioteca.
Un archivo .runtimeconfig.json, que especifica el runtime compartido y su versión de una aplicación.
Otras bibliotecas de las que depende el proyecto (a través de referencias de proyecto o referencias de
paquetes NuGet).
En el caso de los proyectos ejecutables que tienen como destino versiones anteriores a .NET Core 3.0, las
dependencias de biblioteca de NuGet normalmente no se copian en la carpeta de salida. Se resuelven desde
la carpeta de paquetes globales NuGet en tiempo de ejecución. Teniendo eso en cuenta, el producto de
dotnet build no está listo para transferirse a otra máquina para ejecutarse. Para crear una versión de la
aplicación que se pueda implementar, se debe publicar (por ejemplo, con el comando dotnet publish). Para
obtener más información, consulte el tema Implementación de aplicaciones .NET Core.
En el caso de los proyectos ejecutables que tienen como destino .NET Core 3.0 y versiones posteriores, las
dependencias de biblioteca se copian en la carpeta de salida. Esto significa que, si no hay ninguna otra lógica
específica de la publicación (como los proyectos web), se debería poder implementar la salida de la
compilación.
La compilación requiere el archivo project.assets.json, que muestra las dependencias de la aplicación. El
archivo se crea cuando se ejecuta dotnet restore . Sin el archivo de recursos en su lugar, las herramientas
no pueden resolver los ensamblados de referencia, lo que se traduce en errores. Con el SDK de .NET Core
1.x, era necesario ejecutar de forma explícita dotnet restore antes de ejecutar dotnet build . A partir del
SDK de .NET Core 2.0, dotnet restore se ejecuta implícitamente al ejecutar dotnet build . Si quiere
deshabilitar la restauración implícita cuando se ejecuta el comando de compilación, puede usar la opción
--no-restore .

NOTE
A partir de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet build y dotnet run . Sigue siendo un
comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las compilaciones
de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Este comando también admite las opciones dotnet restore cuando se pasan con el formato largo (por ejemplo,
--source ). No se admiten las opciones de formato corto, como -s .

Si el proyecto es ejecutable o no viene determinado por la propiedad <OutputType> en el archivo del


proyecto. En el ejemplo siguiente se muestra un proyecto en el que se genera código ejecutable:

<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

Para generar una biblioteca, omita la propiedad <OutputType> o cambie su valor a Library . La DLL de IL
para una biblioteca no contiene puntos de entrada y no se puede ejecutar.
MSBuild
dotnet build usa MSBuild para compilar el proyecto, por lo que admite las compilaciones en paralelo e
incrementales. Para obtener más información, consulte Compilaciones incrementales.
Además de sus opciones, el comando dotnet build acepta opciones de MSBuild, como -p para establecer
propiedades o -l para definir un registrador. Para obtener más información sobre estas opciones, vea la
Referencia de la línea de comandos de MSBuild. O también puede usar el comando dotnet msbuild.
Ejecutar dotnet build es equivalente a ejecutar dotnet msbuild -restore ; sin embargo, el nivel de detalle
predeterminado de la salida es distinto.

Argumentos
PROJECT | SOLUTION

El archivo de proyecto o solución para compilar. Si no se especifica un archivo de proyecto o solución,


MSBuild busca en el directorio de trabajo actual un archivo que tiene una extensión de archivo que termina
por proj o sln y usa ese archivo.

Opciones
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado para la mayoría de los proyectos es


Debug , pero puede invalidar los valores de configuración de compilación en el proyecto.

-f|--framework <FRAMEWORK>

Compila para un marco de trabajo específico. El marco se debe definir en el archivo de proyecto.
--force

Fuerza la resolución de todas las dependencias, incluso si la última restauración se realizó


correctamente. Especificar esta marca es lo mismo que eliminar el archivo project.assets.json.
Disponible a partir del SDK de .NET Core 2.0.
-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se detenga y espere una entrada o una acción del usuario. Por ejemplo, para
completar la autenticación. Disponible desde el SDK de .NET Core 3.0.
--no-dependencies

Omite las referencias de proyecto a proyecto (P2P ) y solo compila el proyecto raíz especificado.
--no-incremental

Marca la compilación como no segura para la compilación incremental. Esta marca desactiva la
compilación incremental y fuerza una recompilación limpia del gráfico de dependencias del proyecto.
--no-restore

No ejecuta una restauración implícita durante la compilación. Disponible a partir del SDK de
.NET Core 2.0.
--nologo

No se muestra la pancarta de inicio ni el mensaje de copyright. Disponible desde el SDK de


.NET Core 3.0.
-o|--output <OUTPUT_DIRECTORY>

Directorio donde se colocan los archivos binarios compilados. Si no se especifica la ruta de acceso
predeterminada es ./bin/<configuration>/<framework>/ . En el caso de los proyectos con varias
plataformas de destino (a través de la propiedad TargetFrameworks ), también debe definir
--framework al especificar esta opción.

-r|--runtime <RUNTIME_IDENTIFIER>

Especifica el tiempo de ejecución de destino. Para obtener una lista de identificadores de tiempo de
ejecución (RID ), consulte el catálogo de RID.
-v|--verbosity <LEVEL>

Establece el nivel de detalle de MSBuild. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] . De manera predeterminada, es minimal .

--version-suffix <VERSION_SUFFIX>

Establece el valor de la propiedad $(VersionSuffix) que se va a usar al compilar el proyecto. Solo


funciona si no se establece la propiedad $(Version) . A continuación, $(Version) se establece en
$(VersionPrefix) combinada con $(VersionSuffix) , separadas por un guion.

Ejemplos
Creación de un proyecto y sus dependencias:

dotnet build
Creación de un proyecto y sus dependencias mediante la configuración de lanzamiento:

dotnet build --configuration Release

Compilación de un proyecto y sus dependencias para un tiempo de ejecución concreto (en este
ejemplo, Ubuntu 18.04):

dotnet build --runtime ubuntu.18.04-x64

Compile el proyecto y use origen del paquete NuGet especificado durante la operación de
restauración (SDK de .NET Core 2.0 y versiones posteriores):

dotnet build --source c:\packages\mypackages

Compile el proyecto y establezca la versión 1.2.3.4 como un parámetro de compilación mediante la


-p opción de MSBuild:

dotnet build -p:Version=1.2.3.4


dotnet build-server
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1.x y versiones posteriores

Name
dotnet build-server : interactúa con servidores iniciados por una compilación.

Sinopsis
dotnet build-server shutdown [--msbuild] [--razor] [--vbcscompiler]
dotnet build-server shutdown [-h|--help]
dotnet build-server [-h|--help]

Comandos
shutdown

Cierra los servidores de la compilación que se inician desde dotnet. De forma predeterminada, se cierran
todos los servidores.

Opciones
-h|--help

Imprime una corta ayuda para el comando.


--msbuild

Cierra el servidor de compilación de MSBuild.


--razor

Cierra el servidor de compilación de Razor.


--vbcscompiler

Cierra el servidor de compilación del compilador de VB/C#.


dotnet clean
23/10/2019 • 3 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet clean : limpia la salida de un proyecto.

Sinopsis
dotnet clean [<PROJECT>|<SOLUTION>] [-c|--configuration] [-f|--framework] [--interactive]
[--nologo] [-o|--output] [-r|--runtime] [-v|--verbosity]
dotnet clean [-h|--help]

DESCRIPCIÓN
El comando dotnet clean limpia la salida de la compilación anterior. Se implementa como un destino MSBuild,
por lo que el proyecto se evalúa cuando se ejecuta el comando. Solo se limpian las salidas que se crearon durante
la compilación. Se limpian las carpetas intermedias (obj) y de la salida final (bin).

Argumentos
PROJECT | SOLUTION

Proyecto o solución de MSBuild que se va a limpiar. Si no se especifica un archivo de proyecto o solución,


MSBuild busca en el directorio de trabajo actual un archivo que tenga una extensión de archivo que termine en
proj o sln y lo usa.

Opciones
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado es Debug . Esta opción solo es necesaria al
realizar la limpieza si la especificó durante el tiempo de compilación.
-f|--framework <FRAMEWORK>

El marco que se especificó en tiempo de compilación. El marco se debe definir en el archivo de proyecto. Si
especificó el marco en tiempo de compilación, debe especificar el marco al realizar la limpieza.
-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se detenga y espere una entrada o una acción del usuario. Por ejemplo, para
completar la autenticación. Disponible desde el SDK de .NET Core 3.0.
--nologo

No se muestra la pancarta de inicio ni el mensaje de copyright. Disponible desde el SDK de .NET Core 3.0.
-o|--output <OUTPUT_DIRECTORY>

Directorio que contiene los artefactos compilados que se van a limpiar. Especifique el modificador
-f|--framework <FRAMEWORK> con el modificador del directorio de salida si especificó el marco cuando se
compiló el proyecto.
-r|--runtime <RUNTIME_IDENTIFIER>

Limpia la carpeta de salida del tiempo de ejecución especificado. Esto se usa si se ha creado una
implementación autocontenida. Opción disponible desde el SDK de .NET Core 2.0.
-v|--verbosity <LEVEL>

Establece el nivel de detalle de MSBuild. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] . De manera predeterminada, es normal .

Ejemplos
Limpie una compilación predeterminada del proyecto:

dotnet clean

Limpie un proyecto creado con la configuración de lanzamiento:

dotnet clean --configuration Release


Referencia de dotnet help
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.0.x y versiones posteriores

Name
dotnet help : muestra documentación más detallada en línea para el comando especificado.

Sinopsis
dotnet help <COMMAND_NAME> [-h|--help]

Descripción
El comando dotnet help abre la página de referencia para obtener información más detallada sobre el comando
especificado en docs.microsoft.com.

Argumentos
COMMAND_NAME

Nombre del comando de la CLI de .NET Core. Para obtener una lista de los comandos de la CLI válidos,
vea Comandos de la CLI.

Opciones
-h|--help

Imprime una corta ayuda para el comando.

Ejemplos
Se abre la página de documentación del comando dotnet new:

dotnet help new


dotnet migrate
20/01/2020 • 5 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

NOMBRE
dotnet migrate : migra un proyecto .NET Core de la versión preliminar 2 a un proyecto del estilo de SDK de
.NET Core.

Sinopsis
dotnet migrate [<SOLUTION_FILE|PROJECT_DIR>] [--format-report-file-json] [-r|--report-file] [-s|--skip-
project-references] [--skip-backup] [-t|--template-file] [-v|--sdk-package-version] [-x|--xproj-file]
dotnet migrate [-h|--help]

Descripción
Este comando está en desuso. El comando dotnet migrate ya no está disponible a partir del SDK de
.NET Core 3.0. Solo puede migrar un proyecto de .NET Core de la versión preliminar 2 a un proyecto de .NET
Core 1.x, para el que no hay soporte técnico.
De forma predeterminada, el comando migra el proyecto raíz y todas las referencias de proyecto que contiene.
Este comportamiento se deshabilita mediante la opción --skip-project-references en tiempo de ejecución.
La migración se puede realizar en los recursos siguientes:
Un único proyecto mediante la especificación del archivo project.json que quiere migrar.
Todos los directorios especificados en el archivo global.json pasando una ruta al archivo global.json.
Un archivo solution.sln, donde se migran los proyectos a los que se hace referencia en la solución.
Todos los subdirectorios del directorio dado de manera recursiva.
El comando dotnet migrate mantiene el archivo project.json migrado dentro de un directorio backup , que se
crea en caso de que no exista. Este comportamiento se invalida con la opción --skip-backup .
De forma predeterminada, la operación de migración genera el estado del proceso de migración a la salida
estándar (STDOUT). Si usa la opción --report-file <REPORT_FILE> , la salida se guarda en el archivo
especificado.
El comando dotnet migrate solo admite proyectos válidos basados en project.json de la versión preliminar 2.
Esto significa que no se puede usar para migrar DNX o los proyectos basados en project.json de la versión
preliminar 1 directamente a proyectos de MSBuild/csproj. Primero debe migrar manualmente el proyecto a un
proyecto basado en project.json de la versión preliminar 2 y luego usar el comando dotnet migrate para migrar
el proyecto.

Argumentos
PROJECT_JSON/GLOBAL_JSON/SOLUTION_FILE/PROJECT_DIR

La ruta de acceso a uno de los siguientes elementos:


Un archivo project.json para migrar.
Un archivo global.json: se migran las carpetas especificadas en global.json.
Un archivo solution.sln: se migran los proyectos a los que se hace referencia en la solución.
Un directorio para migrar: se buscan de forma recursiva los archivos project.json que se van a migrar dentro
del directorio especificado.
Si no se especifica nada, se toma como valor predeterminado el directorio actual.

Opciones
--format-report-file-json <REPORT_FILE>

Salida del archivo de informe de migración como JSON en lugar de mensajes de usuario.
-h|--help

Imprime una corta ayuda para el comando.


-r|--report-file <REPORT_FILE>

Salida del informe de migración a un archivo además de a la consola.


-s|--skip-project-references [Debug|Release]

Omite la migración de referencias de proyecto. De forma predeterminada, las referencias de proyecto se migran
de forma recursiva.
--skip-backup

Omite el traslado de project.json, global.json y *.xproj a un directorio backup tras la realización correcta de la
migración.
-t|--template-file <TEMPLATE_FILE>

Archivo csproj de plantilla que se utilizará para la migración. De forma predeterminada, se usa la misma plantilla
que la descartada por dotnet new console .
-v|--sdk-package-version <VERSION>

La versión del paquete sdk a la que se hace referencia en la aplicación migrada. El valor predeterminado es la
versión del SDK en dotnet new .
-x|--xproj-file <FILE>

La ruta de acceso al archivo xproj que se usará. Necesario cuando hay más de un archivo xproj en un directorio
de proyecto.

Ejemplos
Migrar un proyecto del directorio actual y todas sus dependencias de proyecto a proyecto:
dotnet migrate

Migrar todos los proyectos que incluyen el archivo global.json:


dotnet migrate path/to/global.json

Migrar solo el proyecto actual y ninguna dependencia de proyecto a proyecto (P2P ). Además, usar una versión
específica de SDK:
dotnet migrate -s -v 1.0.0-preview4
dotnet msbuild
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet msbuild : compila un proyecto y todas sus dependencias.

Sinopsis
dotnet msbuild <msbuild_arguments> [-h]

DESCRIPCIÓN
El comando dotnet msbuild permite el acceso a una instancia de MSBuild completamente funcional.
El comando tiene exactamente las mismas funcionalidades que el cliente de línea de comandos de MSBuild
existente solo para proyectos de tipo SDK. Las opciones son las mismas. Para obtener más información sobre
las opciones disponibles, vea la Referencia de la línea de comandos de MSBuild.
El comando dotnet build es equivalente al comando dotnet msbuild -restore -target:Build . dotnet build
suele utilizase para compilar proyectos, pero dotnet msbuild le aporta mayor control. Por ejemplo, si hay un
destino concreto que quiere ejecutar (sin ejecutar el destino de compilación), probablemente prefiera usar
dotnet msbuild .

Ejemplos
Creación de un proyecto y sus dependencias:

dotnet msbuild

Creación de un proyecto y sus dependencias mediante la configuración de lanzamiento:

dotnet msbuild -p:Configuration=Release

Ejecuta el destino de publicación y publica para el RID osx.10.11-x64 :

dotnet msbuild -t:Publish -p:RuntimeIdentifiers=osx.10.11-x64

Visualización del proyecto completo con todos los destinos incluidos en el SDK:

dotnet msbuild -pp


dotnet new
04/11/2019 • 48 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet new : crea un nuevo proyecto, archivo de configuración o solución según la plantilla
especificada.

Sinopsis
.NET Core 2.2
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet new <TEMPLATE> [--dry-run] [--force] [-i|--install] [-lang|--language] [-n|--name] [--


nuget-source] [-o|--output] [-u|--uninstall] [Template options]
dotnet new <TEMPLATE> [-l|--list] [--type]
dotnet new [-h|--help]

DESCRIPCIÓN
El comando dotnet new proporciona una manera cómoda de inicializar un proyecto .NET Core
válido.
El comando llama al motor de plantillas para crear los artefactos en el disco basándose en las
opciones y la plantilla especificadas.

Argumentos
TEMPLATE

La plantilla de la que se va a crear una instancia cuando se invoca el comando. Cada plantilla puede
tener opciones específicas que puede pasar. Para obtener más información, vea Opciones de
plantilla.
Si el valor TEMPLATE no es una coincidencia exacta con el texto de la columna Plantillas o Nombre
corto, se realiza una coincidencia de subcadena con esas dos columnas.
.NET Core 2.2
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
El comando contiene una lista predeterminada de plantillas. Use dotnet new -l para obtener una
lista de las plantillas disponibles. En la tabla siguiente se muestran las plantillas que vienen
preinstaladas en el SDK de .NET Core 2.2.100. El lenguaje predeterminado de la plantilla se muestra
entre corchetes.
PLANTILLAS NOMBRE CORTO LENGUAJE ETIQUETAS

Aplicación de consola console [C#], F#, VB Común/Consola

Biblioteca de clases classlib [C#], F#, VB Común/Biblioteca

Proyecto de prueba mstest [C#], F#, VB Prueba/MSTest


unitaria

Proyecto de prueba de nunit [C#], F#, VB Prueba/NUnit


NUnit 3

Elemento de prueba de nunit-test [C#], F#, VB Prueba/NUnit


NUnit 3

Proyecto de prueba de xunit [C#], F#, VB Prueba/xUnit


xUnit

Página de Razor page [C#] Web/ASP.NET

MVC ViewImports viewimports [C#] Web/ASP.NET

MVC ViewStart viewstart [C#] Web/ASP.NET

Vacío de ASP.NET Core web [C#], F# Web/Vacío

Aplicación web de mvc [C#], F# Web/MVC


ASP.NET Core (Model-
View-Controller)

Aplicación web de webapp , razor [C#] Web/MVC/Razor Pages


ASP.NET Core

ASP.NET Core con angular [C#] Web/MVC/SPA


Angular

ASP.NET Core con react [C#] Web/MVC/SPA


React.js

ASP.NET Core con reactredux [C#] Web/MVC/SPA


React.js y Redux

Biblioteca de clases de razorclasslib [C#] Web/Razor/Biblioteca/Bi


Razor blioteca de clases de
Razor

API web de ASP.NET webapi [C#], F# Web/WebAPI


Core

archivo global.json globaljson Configuración

Configuración de NuGet nugetconfig Configuración

Configuración web webconfig Configuración


PLANTILLAS NOMBRE CORTO LENGUAJE ETIQUETAS

Archivo de solución sln Soluciones

Opciones
.NET Core 2.2
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
--dry-run

Muestra un resumen de lo que sucedería si se ejecutara el comando determinado y el resultado


fuera la creación de una plantilla.
--force

Fuerza la generación de contenido incluso aunque se vayan a cambiar los archivos existentes. Esto es
necesario cuando el directorio de salida ya contiene un proyecto.
-h|--help

Imprime la ayuda para el comando. Puede invocarse para el propio comando dotnet new o para
cualquier plantilla, como dotnet new mvc --help .
-i|--install <PATH|NUGET_ID>

Instala un paquete de plantillas u origen desde los parámetros PATH o NUGET_ID proporcionados. Si
quiere instalar una versión preliminar de un paquete de plantilla, tendrá que especificar la versión en
el formato de <package-name>::<package-version> . De manera predeterminada, dotnet new pasa *
para la versión, que representa la última versión estable del paquete. Vea un ejemplo en la sección
Ejemplos.
Para obtener información sobre cómo crear plantillas personalizadas, consulte Custom templates for
dotnet new (Plantillas personalizadas para dotnet new ).
-l|--list

Muestra las plantillas que contienen el nombre especificado. Si se invoca para el comando
dotnet new , muestra las plantillas posibles disponibles para un directorio determinado. Por ejemplo,
si el directorio ya contiene un proyecto, no mostrará todas las plantillas del proyecto.
-lang|--language {C#|F#|VB}

El lenguaje de la plantilla que se va a crear. El lenguaje aceptado cambia según la plantilla (vea los
valores predeterminados en la sección argumentos). No es válido para algunas plantillas.

NOTE
Algunos shells interpretan # como un carácter especial. En esos casos, debe incluir el valor del parámetro de
lenguaje, como dotnet new console -lang "F#" .

-n|--name <OUTPUT_NAME>

El nombre de la salida creada. Si no se especifica ningún nombre, se usa el nombre del directorio
actual.
--nuget-source

Especifica un origen de NuGet para usarlo durante la instalación.


-o|--output <OUTPUT_DIRECTORY>

La ubicación para colocar la salida generada. El valor predeterminado es el directorio actual.


--type

Filtra plantillas en función de los tipos disponibles. Los valores predefinidos son "project", "item" u
"other".
-u|--uninstall <PATH|NUGET_ID>

Desinstala un paquete de plantillas u origen en los parámetros PATH o NUGET_ID proporcionados. Al


excluir el valor <PATH|NUGET_ID> , se muestran todos los paquetes de plantillas instalados actualmente
y sus plantillas asociadas.

NOTE
Para desinstalar una plantilla mediante PATH , debe usar el nombre completo de la ruta de acceso. Por
ejemplo, C:/Users/<USER>/Documents/Templates/GarciaSoftware.ConsoleTemplate.CSharp funcionará,
pero ./GarciaSoftware.ConsoleTemplate.CSharp desde la carpeta contenedora no lo hará. Además, no debe
incluir una barra diagonal para finalizar el directorio en la ruta de acceso a la plantilla.

Opciones de plantilla
Cada plantilla de proyecto puede tener opciones adicionales disponibles. Las plantillas principales
tienen las siguientes opciones adicionales:
.NET Core 2.2
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
console
--langVersion <VERSION_NUMBER> : establece la propiedad LangVersion en el archivo de proyecto
creado. Por ejemplo, use --langVersion 7.3 para emplear C# 7.3. No es compatible con F#.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
angular, react, reactredux
--exclude-launch-settings : excluye launchSettings.json de la plantilla generada.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
--no-https : el proyecto no requiere HTTPS. Esta opción solo se aplica si no se usan IndividualAuth
u OrganizationalAuth .
razorclasslib
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
classlib
-f|--framework <FRAMEWORK> : especifica el marco de trabajo de destino. Valores: netcoreapp2.2 para
crear una biblioteca de clases de .NET Core o netstandard2.0 para crear una biblioteca de clases de
.NET Standard. El valor predeterminado es netstandard2.0 .
--langVersion <VERSION_NUMBER> : establece la propiedad LangVersion en el archivo de proyecto
creado. Por ejemplo, use --langVersion 7.3 para emplear C# 7.3. No es compatible con F#.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
mstest, xunit
-p|--enable-pack : habilita el empaquetado para el proyecto mediante dotnet pack.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
nunit
-f|--framework <FRAMEWORK> : especifica el marco de trabajo de destino. El valor predeterminado es
netcoreapp2.1 .
-p|--enable-pack : habilita el empaquetado para el proyecto mediante dotnet pack.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
page
-na|--namespace <NAMESPACE_NAME>: espacio de nombres del código generado. El valor
predeterminado es MyApp.Namespace .
-np|--no-pagemodel : crea la página sin PageModel.
viewimports
-na|--namespace <NAMESPACE_NAME>: espacio de nombres del código generado. El valor
predeterminado es MyApp.Namespace .
web
--exclude-launch-settings : excluye launchSettings.json de la plantilla generada.
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
--no-https : el proyecto no requiere HTTPS. Esta opción solo se aplica si no se usan IndividualAuth
u OrganizationalAuth .
mvc, webapp
-au|--auth <AUTHENTICATION_TYPE> : el tipo de autenticación que se va a usar. Los valores posibles son:
None : sin autenticación (valor predeterminado).
Individual : autenticación individual.
IndividualB2C : autenticación individual con Azure AD B2C.
SingleOrg : autenticación organizativa para un solo inquilino.
MultiOrg : autenticación organizativa para varios inquilinos.
Windows : autenticación de Windows.

--aad-b2c-instance <INSTANCE> : la instancia de Azure Active Directory B2C con la que se realiza la
conexión. Úsela con la autenticación IndividualB2C . El valor predeterminado es
https://login.microsoftonline.com/tfp/ .
-ssp|--susi-policy-id <ID> : el id. de inicio de sesión y de directiva de registro de este proyecto.
Úsela con la autenticación IndividualB2C .
-rp|--reset-password-policy-id <ID> : el id. de la directiva de restablecimiento de contraseñas para
este proyecto. Úsela con la autenticación IndividualB2C .
-ep|--edit-profile-policy-id <ID> : el id. de directiva de edición de perfiles para este proyecto. Úsela
con la autenticación IndividualB2C .
--aad-instance <INSTANCE> : la instancia de Azure Active Directory con la que se realiza la conexión.
Úsela con las autenticaciones SingleOrg o MultiOrg . El valor predeterminado es
https://login.microsoftonline.com/ .

--client-id <ID> : el id. de cliente para este proyecto. Úsela con las autenticaciones IndividualB2C ,
SingleOrg o MultiOrg . El valor predeterminado es 11111111-1111-1111-11111111111111111 .
--domain <DOMAIN> : el dominio para el inquilino del directorio. Úsela con las autenticaciones
SingleOrg o IndividualB2C . El valor predeterminado es qualified.domain.name .
--tenant-id <ID> : el id. de inquilino del directorio con el que se realiza la conexión. Úsela con la
autenticación SingleOrg . El valor predeterminado es 22222222-2222-2222-2222-222222222222 .
--callback-path <PATH> : la ruta de acceso de solicitud de la ruta de acceso de la base de la aplicación
del URI de redirección. Úsela con las autenticaciones SingleOrg o IndividualB2C . El valor
predeterminado es /signin-oidc .
-r|--org-read-access : concede a esta aplicación acceso de lectura al directorio. Solo se aplica a las
autenticaciones SingleOrg y MultiOrg .
--exclude-launch-settings : excluye launchSettings.json de la plantilla generada.
--no-https : el proyecto no requiere HTTPS. app.UseHsts y app.UseHttpsRedirection no se agregan
a Startup.Configure . Esta opción solo se aplica si no se usan Individual , IndividualB2C , SingleOrg
o MultiOrg .
-uld|--use-local-db : especifica que se debería usar LocalDB en vez de SQLite. Solo se aplica a las
autenticaciones Individual y IndividualB2C .
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
webapi
-au|--auth <AUTHENTICATION_TYPE> : el tipo de autenticación que se va a usar. Los valores posibles son:
None : sin autenticación (valor predeterminado).
IndividualB2C : autenticación individual con Azure AD B2C.
SingleOrg : autenticación organizativa para un solo inquilino.
Windows : autenticación de Windows.

--aad-b2c-instance <INSTANCE> : la instancia de Azure Active Directory B2C con la que se realiza la
conexión. Úsela con la autenticación IndividualB2C . El valor predeterminado es
https://login.microsoftonline.com/tfp/ .

-ssp|--susi-policy-id <ID> : el id. de inicio de sesión y de directiva de registro de este proyecto.


Úsela con la autenticación IndividualB2C .
--aad-instance <INSTANCE> : la instancia de Azure Active Directory con la que se realiza la conexión.
Úsela con la autenticación SingleOrg . El valor predeterminado es
https://login.microsoftonline.com/ .
--client-id <ID> : el id. de cliente para este proyecto. Úsela con las autenticaciones IndividualB2C o
SingleOrg . El valor predeterminado es 11111111-1111-1111-11111111111111111 .

--domain <DOMAIN> : el dominio para el inquilino del directorio. Úsela con las autenticaciones
SingleOrg o IndividualB2C . El valor predeterminado es qualified.domain.name .
--tenant-id <ID> : el id. de inquilino del directorio con el que se realiza la conexión. Úsela con la
autenticación SingleOrg . El valor predeterminado es 22222222-2222-2222-2222-222222222222 .
-r|--org-read-access : concede a esta aplicación acceso de lectura al directorio. Solo se aplica a las
autenticaciones SingleOrg y MultiOrg .
--exclude-launch-settings : excluye launchSettings.json de la plantilla generada.
--no-https : el proyecto no requiere HTTPS. app.UseHsts y app.UseHttpsRedirection no se agregan
a Startup.Configure . Esta opción solo se aplica si no se usan Individual , IndividualB2C , SingleOrg
o MultiOrg .
-uld|--use-local-db : especifica que se debería usar LocalDB en vez de SQLite. Solo se aplica a las
autenticaciones Individual y IndividualB2C .
--no-restore : no se ejecuta una restauración implícita durante la creación del proyecto.
globaljson
--sdk-version <VERSION_NUMBER> : especifica la versión del SDK de .NET Core que se usará con el
archivo global.json.

Ejemplos
Creación de un proyecto de aplicación de consola de C# mediante la especificación del nombre de
plantilla:
dotnet new "Console Application"

Creación de un proyecto de aplicación de consola con F# en el directorio actual:


dotnet new console -lang F#

Creación de un proyecto de biblioteca de clases de .NET Standard en el directorio especificado


(disponible solo con el SDK de .NET Core 2.0 o versiones posteriores):
dotnet new classlib -lang VB -o MyLibrary

Creación de un proyecto MVC de ASP.NET Core C# en el directorio actual sin autenticación:


dotnet new mvc -au None

Creación de un proyecto de xUnit:


dotnet new xunit

Enumere todas las plantillas disponibles para MVC:


dotnet new mvc -l

Enumeración de todas las plantillas que coinciden con la subcadena we. No se encuentra ninguna
coincidencia exacta, por lo que se ejecuta la coincidencia de subcadena con las columnas de nombre
corto y de nombre.
dotnet new we -l

Intento de invocar a la plantilla que coincide con ng. Si no se puede determinar una única
coincidencia, se enumeran las plantillas que son coincidencias parciales.
dotnet new ng

Instalación de la versión 2.0 de las plantillas Aplicación de página única para ASP.NET Core (opción
de comando solo disponible para .NET Core SDK 1.1 y versiones posteriores):
dotnet new -i Microsoft.DotNet.Web.Spa.ProjectTemplates::2.0.0

Creación de un archivo global.json en el directorio actual que establezca la versión del SDK en 2.0.0
(solo disponible en el SDK de .NET Core 2.0 o versiones posteriores):
dotnet new globaljson --sdk-version 2.0.0

Vea también
Custom templates for dotnet new (Plantillas personalizadas para dotnet new )
Creación de una plantilla personalizada para dotnet new
Repositorio de GitHub dotnet/dotnet-template-samples
Available templates for dotnet new (Plantillas disponibles para dotnet new )
dotnet nuget delete
23/10/2019 • 2 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet nuget delete : elimina o quita de la lista un paquete del servidor.

Sinopsis
dotnet nuget delete [<PACKAGE_NAME> <PACKAGE_VERSION>] [--force-english-output] [--interactive] [-k|--api-key]
[--no-service-endpoint]
[--non-interactive] [-s|--source]
dotnet nuget delete [-h|--help]

DESCRIPCIÓN
El comando dotnet nuget delete elimina o quita de la lista un paquete del servidor. Para nuget.org, la acción es
quitar de la lista el paquete.

Argumentos
PACKAGE_NAME

Nombre o id. del paquete que se va a eliminar.


PACKAGE_VERSION

Versión del paquete que se va a eliminar.

Opciones
--force-english-output

Fuerza la ejecución de la aplicación mediante una referencia cultural en inglés invariable.


-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se bloquee y requiere una acción manual para operaciones tales como la
autenticación. Opción disponible a partir del SDK de .NET Core 2.2.
-k|--api-key <API_KEY>

La clave de API para el servidor.


--no-service-endpoint

No agrega "api/v2/paquete" a la dirección URL de origen. Opción disponible a partir del SDK de .NET Core
2.1.
--non-interactive

No pide confirmaciones o entradas de usuario.


-s|--source <SOURCE>

Especifica la dirección URL del servidor. Las direcciones URL admitidas para nuget.org incluyen
https://www.nuget.org , https://www.nuget.org/api/v3 y https://www.nuget.org/api/v2/package . Para
fuentes privadas, reemplace el nombre de host (por ejemplo, %hostname%/api/v3 ).

Ejemplos
Elimina la versión 1.0 del paquete Microsoft.AspNetCore.Mvc :

dotnet nuget delete Microsoft.AspNetCore.Mvc 1.0

Elimina la versión 1.0 del paquete Microsoft.AspNetCore.Mvc , sin pedir al usuario credenciales u otra
información:

dotnet nuget delete Microsoft.AspNetCore.Mvc 1.0 --non-interactive


dotnet nuget locals
25/11/2019 • 3 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

NOMBRE
dotnet nuget locals : borra o enumera recursos locales de NuGet.

Sinopsis
dotnet nuget locals <CACHE_LOCATION> [(-c|--clear)|(-l|--list)] [--force-english-output]
dotnet nuget locals [-h|--help]

Descripción
El comando dotnet nuget locals borra o enumera los recursos locales de NuGet en la caché de solicitudes http, la
caché temporal o la carpeta de paquetes globales de toda la máquina.

Argumentos
CACHE_LOCATION

La ubicación de caché que se va a mostrar o borrar. Acepta uno de los valores siguientes:
all : indica que la operación especificada se debe aplicar a todos los tipos de caché: caché de solicitudes
http, caché de paquetes globales y caché temporal.
http-cache : indica que la operación especificada se aplica solo a la caché de solicitudes http. Las otras
ubicaciones de caché no se ven afectadas.
global-packages : indica que la operación especificada se aplica solo a la caché de paquetes globales. Las
otras ubicaciones de caché no se ven afectadas.
temp : indica que la operación especificada se aplica solo a la caché temporal. Las otras ubicaciones de
caché no se ven afectadas.

Opciones
--force-english-output

Fuerza la ejecución de la aplicación mediante una referencia cultural en inglés invariable.


-h|--help

Imprime una corta ayuda para el comando.


-c|--clear

La opción de borrado ejecuta una operación de borrado sobre el tipo de caché especificado. El contenido de
los directorios de caché se elimina de forma recursiva. El usuario o grupo de ejecución deben tener permiso
para los archivos en los directorios de la caché. En caso contrario, se muestra un error para indicar los
archivos o las carpetas que no se han borrado.
-l|--list

La opción de lista se usa para mostrar la ubicación del tipo de caché especificado.

Ejemplos
Muestra las rutas de acceso de todos los directorios de caché locales (el directorio de caché http, el
directorio de caché de paquetes globales y el directorio de caché temporal):

dotnet nuget locals all –l

Muestra la ruta de acceso del directorio de la caché de solicitudes http:

dotnet nuget locals http-cache --list

Borra todos los archivos de todos los directorios de caché locales (directorio de caché http, directorio de
caché de paquetes globales y directorio de caché temporal):

dotnet nuget locals all --clear

Borra todos los archivos del directorio local de la caché de paquetes globales:

dotnet nuget locals global-packages -c

Borra todos los archivos del directorio local de la caché temporal:

dotnet nuget locals temp -c

Solución de problemas
Para más información sobre problemas y errores comunes encontrados al usar el comando dotnet nuget locals ,
consulte Managing the NuGet cache (Administración de la caché de NuGet).
dotnet nuget push
12/12/2019 • 4 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet nuget push : inserta un paquete en el servidor y lo publica.

Sinopsis
dotnet nuget push [<ROOT>] [-d|--disable-buffering] [--force-english-output] [--interactive] [-k|--api-key] [-
n|--no-symbols]
[--no-service-endpoint] [-s|--source] [--skip-duplicate] [-sk|--symbol-api-key] [-ss|--symbol-source] [-
t|--timeout]
dotnet nuget push [-h|--help]

DESCRIPCIÓN
El comando dotnet nuget push inserta un paquete en el servidor y lo publica. El comando push usa los detalles
del servidor y de las credenciales encontrados en el archivo de configuración NuGet del sistema o en la cadena de
archivos de configuración. Para más información sobre los archivos de configuración, consulte Configuring NuGet
Behavior (Configuración del comportamiento de NuGet). La configuración predeterminada de NuGet se obtiene
mediante la carga de %AppData%\NuGet\NuGet.config (Windows) o $HOME/.local/share (Linux/macOS ), y
luego la carga de cualquier archivo nuget.config o .nuget\nuget.config comenzando desde la raíz de la unidad y
finalizando en el directorio actual.

Argumentos
ROOT

Especifica la ruta de acceso al archivo en la que se debe insertar el paquete.

Opciones
-d|--disable-buffering

Deshabilita el almacenamiento en búfer al realizar inserciones en un servidor HTTP (S ) para reducir el uso
de memoria.
--force-english-output

Fuerza la ejecución de la aplicación mediante una referencia cultural en inglés invariable.


-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se bloquee y requiere una acción manual para operaciones tales como la
autenticación. Opción disponible a partir del SDK de .NET Core 2.2.
-k|--api-key <API_KEY>

La clave de API para el servidor.


-n|--no-symbols

No inserta símbolos (incluso si está presente).


--no-service-endpoint

No agrega "api/v2/paquete" a la dirección URL de origen. Opción disponible desde el SDK de .NET Core
2.1.
-s|--source <SOURCE>

Especifica la dirección URL del servidor. Esta opción es necesaria a menos que el valor de configuración
DefaultPushSource esté establecido en el archivo de configuración de NuGet.

--skip-duplicate

Al insertar varios paquetes en un servidor HTTP (S ), trata cualquier respuesta de conflicto 409 como una
advertencia para que la inserción pueda continuar. Disponible a partir del SDK de .NET Core 3.1.
-sk|--symbol-api-key <API_KEY>

La clave de API para el servidor de símbolos.


-ss|--symbol-source <SOURCE>

Especifica la dirección URL del servidor de símbolos.


-t|--timeout <TIMEOUT>

Especifica el tiempo de espera para la inserción en un servidor en segundos. El valor predeterminado es


300 segundos (5 minutos). Si se especifica 0 (cero segundos), se aplica el valor predeterminado.

Ejemplos
Inserta foo.nupkg en el origen de inserción predeterminado, y especifica una clave de API:

dotnet nuget push foo.nupkg -k 4003d786-cc37-4004-bfdf-c4f3e8ef9b3a

Inserta foo.nupkg en el origen de inserción personalizado https://customsource , y especifica una clave de


API:

dotnet nuget push foo.nupkg -k 4003d786-cc37-4004-bfdf-c4f3e8ef9b3a -s https://customsource/

Inserta foo.nupkg en el origen de inserción predeterminado:

dotnet nuget push foo.nupkg

Inserta foo.symbols.nupkp en el origen de símbolos predeterminado:

dotnet nuget push foo.symbols.nupkg

Inserta foo.nupkg en el origen de inserción predeterminado, y especifica un tiempo de espera de 360


segundos:
dotnet nuget push foo.nupkg --timeout 360

Inserta todos los archivos .nupkg del directorio actual en el origen de inserción predeterminado:

dotnet nuget push *.nupkg

NOTE
Si este comando no funciona, es posible que se deba a un error presente en versiones anteriores del SDK (SDK de
.NET Core 2.1 y versiones anteriores). Para solucionar este problema, actualice la versión de su SDK o ejecute el
siguiente comando en su lugar: dotnet nuget push **/*.nupkg

Envía todos los archivos .nupkg aunque un servidor HTTP (S ) devuelva una respuesta de conflicto 409:

dotnet nuget push *.nupkg --skip-duplicate


dotnet pack
23/10/2019 • 8 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet pack : empaqueta el código en un paquete de NuGet.

Sinopsis
dotnet pack [<PROJECT>|<SOLUTION>] [-c|--configuration] [--force] [--include-source] [--include-symbols]
[--interactive]
[--no-build] [--no-dependencies] [--no-restore] [--nologo] [-o|--output] [--runtime] [-s|--
serviceable]
[-v|--verbosity] [--version-suffix]
dotnet pack [-h|--help]

DESCRIPCIÓN
El comando dotnet pack compila el proyecto y crea paquetes de NuGet. El resultado de este comando es un
paquete de NuGet (es decir, un archivo .nupkg).
Si quiere generar un paquete que contenga los símbolos de depuración, tiene dos opciones a su disposición:
--include-symbols : crea el paquete de símbolos.
--include-source : crea el paquete de símbolos con una carpeta src dentro que contiene los archivos de
origen.
Las dependencias de NuGet del proyecto empaquetado se agregan al archivo .nuspec, por lo que se pueden
resolver adecuadamente cuando se instala el paquete. Las referencias de proyecto a proyecto no se
empaquetan dentro del proyecto. Actualmente, debe disponer de un paquete por proyecto si tiene
dependencias de proyecto a proyecto.
De forma predeterminada, dotnet pack compila primero el proyecto. Si desea evitar este comportamiento,
pase la opción --no-build . Esta opción a menudo resulta útil en escenarios de compilación de integración
continua (CI) donde se conoce el código que se compiló anteriormente.
Puede proporcionar propiedades de MSBuild en el comando dotnet pack para el proceso de empaquetado.
Para obtener más información, vea Propiedades de metadatos de NuGet y la Referencia de la línea de
comandos de MSBuild. La sección Ejemplos muestra cómo utilizar el modificador -p de MSBuild en un par
de escenarios diferentes.
Los proyectos web no están empaquetados de forma predeterminada. Para invalidar el comportamiento
predeterminado, agregue la siguiente propiedad a su archivo .csproj:

<PropertyGroup>
<IsPackable>true</IsPackable>
</PropertyGroup>
NOTE
A partir de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet build y dotnet run . Sigue siendo un
comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las compilaciones
de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Este comando también admite las opciones dotnet restore cuando se pasan con el formato largo (por ejemplo,
--source ). No se admiten las opciones de formato corto, como -s .

Argumentos
PROJECT | SOLUTION

El archivo de proyecto o solución para empaquetar. Es una ruta de acceso a un archivo csproj, a un archivo de
solución o a un directorio. Si no se especifica, el comando busca un archivo del proyecto o de la solución en
el directorio actual.

Opciones
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado es Debug .


--force

Fuerza la resolución de todas las dependencias, incluso si la última restauración se realizó


correctamente. Especificar esta marca es lo mismo que eliminar el archivo project.assets.json. Opción
disponible desde el SDK de .NET Core 2.0.
-h|--help

Imprime una corta ayuda para el comando.


--include-source

Incluye los paquetes NuGet de símbolos de depuración, además de los paquetes NuGet normales en
el directorio de salida. Los archivos de origen se incluyen en la carpeta src dentro del paquete de
símbolos.
--include-symbols

Incluye los paquetes NuGet de símbolos de depuración, además de los paquetes NuGet normales en
el directorio de salida.
--interactive

Permite que el comando se detenga y espere la entrada o acción del usuario (por ejemplo, completar
la autenticación). Disponible desde el SDK de .NET Core 3.0.
--no-build

No compila el proyecto antes de empaquetarlo. También establece la marca --no-restore de forma


implícita.
--no-dependencies

Omite las referencias de proyecto a proyecto y solo restaura el proyecto raíz. Opción disponible desde
el SDK de .NET Core 2.0.
--no-restore

No ejecuta una restauración implícita al ejecutar el comando. Opción disponible desde el SDK de .NET
Core 2.0.
--nologo

No se muestra la pancarta de inicio ni el mensaje de copyright. Disponible desde el SDK de


.NET Core 3.0.
-o|--output <OUTPUT_DIRECTORY>

Coloca los paquetes compilados en el directorio especificado.


--runtime <RUNTIME_IDENTIFIER>

Especifica el tiempo de ejecución de destino para el que restaurar los paquetes. Para obtener una lista
de identificadores de tiempo de ejecución (RID ), consulte el catálogo de RID. Opción disponible desde
el SDK de .NET Core 2.0.
-s|--serviceable

Establece la marca de servicio en el paquete. Para más información, consulte .NET Blog: .NET 4.5.1
Supports Microsoft Security Updates for .NET NuGet Libraries (Blog de .NET: .NET 4.5.1 admite
actualizaciones de seguridad de Microsoft para bibliotecas NuGet de .NET).
--version-suffix <VERSION_SUFFIX>

Define el valor de la propiedad de $(VersionSuffix) en el proyecto.


-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

Ejemplos
Empaquetado del proyecto en el directorio actual:

dotnet pack

Empaquetar el proyecto app1 :

dotnet pack ~/projects/app1/project.csproj

Empaquetar el proyecto en el directorio actual y colocar los paquetes resultantes en la carpeta nupkgs :

dotnet pack --output nupkgs

Empaquetar el proyecto en el directorio actual en la carpeta nupkgs y omitir del paso de compilación:

dotnet pack --no-build --output nupkgs

Con el sufijo de la versión del proyecto configurado como


<VersionSuffix>$(VersionSuffix)</VersionSuffix> en el archivo .csproj, empaquetar el proyecto actual
y actualizar la versión del paquete resultante con el sufijo dado:

dotnet pack --version-suffix "ci-1234"

Establecer la versión del paquete en 2.1.0 con la propiedad de MSBuild PackageVersion :

dotnet pack -p:PackageVersion=2.1.0

Empaquete el proyecto para un determinado marco de destino:

dotnet pack -p:TargetFrameworks=net45

Empaquete el proyecto y use un tiempo de ejecución específico (Windows 10) para la operación de
restauración (SDK de .NET Core 2.0 y versiones superiores):

dotnet pack --runtime win10-x64

Empaquete el proyecto mediante un archivo .nuspec:

dotnet pack ~/projects/app1/project.csproj -p:NuspecFile=~/projects/app1/project.nuspec -


p:NuspecBasePath=~/projects/app1/nuget
dotnet publish
23/10/2019 • 14 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet publish : empaqueta la aplicación y sus dependencias en una carpeta para su implementación en un
sistema de hospedaje.

Sinopsis
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet publish [<PROJECT>] [-c|--configuration] [-f|--framework] [--force] [--manifest] [--no-build] [-


-no-dependencies]
[--no-restore] [-o|--output] [-r|--runtime] [--self-contained] [-v|--verbosity] [--version-suffix]
dotnet publish [-h|--help]

DESCRIPCIÓN
dotnet publish : compila la aplicación, lee sus dependencias especificadas en el archivo de proyecto y
publica el conjunto resultante de archivos en un directorio. La salida incluye los recursos siguientes:
Código de lenguaje intermedio (IL ) en un ensamblado con una extensión dll.
Archivo .deps.json que incluye todas las dependencias del proyecto.
Archivo .runtime.config.json en el que se especifica el entorno de tiempo de ejecución compartido que
espera la aplicación, así como otras opciones de configuración para el tiempo de ejecución (por ejemplo,
el tipo de recolección de elementos no utilizados).
Las dependencias de la aplicación, que se copian de la caché de NuGet a la carpeta de salida.
La salida del comando dotnet publish está lista para la implementación en un sistema de hospedaje (por
ejemplo, un servidor, un equipo PC o Mac, un portátil) para la ejecución. Es la única manera admitida
oficialmente para preparar la aplicación para la implementación. Dependiendo del tipo de implementación
que especifique el proyecto, el sistema de hospedaje puede o no tener instalado el entorno de tiempo de
ejecución compartido de .NET Core. Para obtener más información, consulte el tema Implementación de
aplicaciones .NET Core. Para la estructura de directorios de una aplicación publicada, consulte Directory
structure (Estructura de directorios).
NOTE
A partir de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet build y dotnet run . Sigue siendo un
comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las compilaciones
de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Este comando también admite las opciones dotnet restore cuando se pasan con el formato largo (por ejemplo,
--source ). No se admiten las opciones de formato corto, como -s .

Argumentos
PROJECT

El proyecto que se va a publicar. Es la ruta de acceso y el nombre de archivo de un archivo de proyecto C#,
F# o Visual Basic, o la ruta de acceso a un directorio que contiene un archivo de proyecto C#, F# o Visual
Basic. Si no se especifica, se toma como predeterminado el directorio actual.

Opciones
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado es Debug .


-f|--framework <FRAMEWORK>

Publica la aplicación para el marco de trabajo de destino especificado. Debe especificar el marco de trabajo
de destino en el archivo de proyecto.
--force

Fuerza la resolución de todas las dependencias, incluso si la última restauración se realizó correctamente.
Especificar esta marca es lo mismo que eliminar el archivo project.assets.json.
-h|--help

Imprime una corta ayuda para el comando.


--manifest <PATH_TO_MANIFEST_FILE>

Especifica uno o varios manifiestos de destino que se usarán para recortar el conjunto de paquetes
publicados con la aplicación. El archivo de manifiesto es parte de la salida del comando dotnet store . Para
especificar varios manifiestos, agregue la opción --manifest para cada manifiesto. Esta opción está
disponible a partir del SDK de .NET Core 2.0.
--no-build

No compila el proyecto antes de publicarlo. También establece la marca --no-restore de forma implícita.
--no-dependencies

Omite las referencias de proyecto a proyecto y solo restaura el proyecto raíz.


--no-restore

No ejecuta una restauración implícita al ejecutar el comando.


-o|--output <OUTPUT_DIRECTORY>

Especifica la ruta de acceso del directorio de salida. Si no se especifica, el valor predeterminado es


./bin/[configuration]/[framework]/publish/ para una implementación dependiente del marco de trabajo o
./bin/[configuration]/[framework]/[runtime]/publish/ para una implementación independiente. Si la ruta de
acceso es relativa, el directorio de salida generado es relativo a la ubicación del archivo de proyecto, no al
directorio de trabajo actual.
--self-contained

Publica el tiempo de ejecución de .NET Core con la aplicación para que no sea necesario tener instalado el
tiempo de ejecución en la máquina de destino. Si se especifica un identificador de tiempo de ejecución, su
valor predeterminado es true . Para más información sobre los diferentes tipos de implementación, vea
Implementación de aplicaciones .NET Core.
-r|--runtime <RUNTIME_IDENTIFIER>

Publica la aplicación para un determinado entorno de tiempo de ejecución. Esto se usa al crear una
implementación autocontenida (SCD ). Para obtener una lista de identificadores de tiempo de ejecución
(RID ), consulte el catálogo de RID. El valor predeterminado es publicar una aplicación dependiente del
marco de trabajo (FDD ).
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

--version-suffix <VERSION_SUFFIX>

Define el sufijo de versión para reemplazar el asterisco ( * ) en el campo de versión del archivo de proyecto.

Ejemplos
Publica el proyecto en el directorio actual:
dotnet publish

Publicar la aplicación con el archivo del proyecto especificado:


dotnet publish ~/projects/app1/app1.csproj

Publica el proyecto en el directorio actual mediante el marco de trabajo netcoreapp1.1 :


dotnet publish --framework netcoreapp1.1

Publica la aplicación actual mediante el marco de trabajo netcoreapp1.1 y el entorno de tiempo de


ejecución para OS X 10.10 (este RID tiene que existir en el archivo de proyecto):
dotnet publish --framework netcoreapp1.1 --runtime osx.10.11-x64

Publica la aplicación actual pero no restaura las referencias de proyecto a proyecto (P2P ), solo el proyecto
raíz, durante la operación de restauración (SDK de .NET Core 2.0 y versiones superiores):
dotnet publish --no-dependencies

Vea también
Marcos de trabajo de destino
Catálogo de identificadores de tiempo de ejecución (RID )
dotnet restore
20/01/2020 • 11 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

NOMBRE
dotnet restore : restaura las dependencias y las herramientas de un proyecto.

Sinopsis
.NET Core 2.x
.NET Core 1.x

dotnet restore [<ROOT>] [--configfile] [--disable-parallel] [--force] [--ignore-failed-sources]


[--no-cache]
[--no-dependencies] [--packages] [-r|--runtime] [-s|--source] [-v|--verbosity] [--
interactive]
dotnet restore [-h|--help]

Descripción
El comando dotnet restore usa NuGet para restaurar las dependencias, así como las herramientas
específicas del proyecto que se especifican en el archivo project.json. De forma predeterminada, la
restauración de dependencias y herramientas se ejecuta en paralelo.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan
implícitamente todos los comandos que requieren que se produzca una restauración, como dotnet new ,
dotnet build y dotnet run . Sigue siendo un comando válido en algunos escenarios donde tiene sentido
realizar una restauración explícita, como las compilaciones de integración continua en Azure DevOps Services
o en los sistemas de compilación que necesitan controlar explícitamente la hora a la que se produce la
restauración.

Para restaurar las dependencias, NuGet necesita las fuentes donde se encuentran los paquetes. Las
fuente se proporcionan normalmente mediante el archivo de configuración nuget.config. Cuando se
instalan las herramientas de la CLI, se proporciona un archivo de configuración predeterminado.
Puede especificar más fuentes creando su propio archivo nuget.config en el directorio del proyecto.
Puede invalidar las fuentes nuget.config con la opción -s .
Para las dependencias, puede especificar dónde se colocan los paquetes restaurados durante la
operación de restauración mediante el argumento --packages . Si no se especifica, se usa la caché
de paquetes NuGet predeterminada, que se encuentra en el directorio .nuget/packages del
directorio de inicio del usuario en todos los sistemas operativos. Por ejemplo, /home/usuario1 en
Linux o C:\Usuarios\usuario1 en Windows.
Para herramientas específicas del proyecto, dotnet restore restaura primero el paquete en el que
se empaqueta la herramienta y, a continuación, continúa con la restauración de las dependencias de
la herramienta especificadas en su project.json.
Diferencias de nuget.config
El comportamiento del comando dotnet restore depende de las opciones de configuración del
archivo nuget.config, si existe. Por ejemplo, establecer globalPackagesFolder en nuget.config coloca
los paquetes NuGet restaurados en la carpeta especificada. Esta es una alternativa para especificar la
opción --packages en el comando dotnet restore . Para más información, consulte la referencia de
nuget.config.
Hay tres configuraciones específicas que dotnet restore omite:
bindingRedirects
Los redireccionamientos de enlace no funcionan con elementos de <PackageReference> y
.NET Core solo admite elementos de <PackageReference> para los paquetes NuGet.
solution
Esta configuración es específica para Visual Studio y no se aplica a .NET Core. .NET Core no
usa un archivo packages.config y, en su lugar, usa elementos de <PackageReference> para los
paquetes NuGet.
trustedSigners
Esta configuración no es aplicable porque NuGet ya no admite la comprobación
multiplataforma de los paquetes de confianza.

dotnet restore implícito


A partir de .NET Core 2.0, dotnet restore se ejecuta de forma implícita si es necesario al emitir los
siguientes comandos:
dotnet new
dotnet build
dotnet build-server
dotnet run
dotnet test
dotnet publish
dotnet pack

En la mayoría de los casos, ya no necesita utilizar explícitamente el comando dotnet restore .


En ocasiones, es posible que no sea conveniente ejecutar dotnet restore de forma implícita. Por
ejemplo, algunos sistemas automatizados, como los sistemas de compilación, deben llamar a
dotnet restore explícitamente para controlar cuándo se produce la restauración a fin de controlar
el uso de la red. Para evitar que dotnet restore se ejecute de forma implícita, se puede usar la
marca --no-restore con cualquiera de estos comandos para deshabilitar la restauración implícita.

Argumentos
ROOT

Ruta de acceso opcional del archivo de proyecto para restaurar.

Opciones
.NET Core 2.x
.NET Core 1.x
--configfile <FILE>

El archivo de configuración de NuGet (nuget.config) que se usa para la operación de restauración.


--disable-parallel

Deshabilita la restauración de varios proyectos en paralelo.


--force

Fuerza la resolución de todas las dependencias, incluso si la última restauración se realizó


correctamente. Especificar esta marca es lo mismo que eliminar el archivo project.assets.json.
-h|--help

Imprime una corta ayuda para el comando.


--ignore-failed-sources

Solo se advierte sobre los orígenes con error si hay paquetes que satisfagan el requisito de versión.
--no-cache

Especifica que no se almacenen en caché los paquetes y las solicitudes HTTP.


--no-dependencies

Al restaurar un proyecto con referencias de proyecto a proyecto (P2P ), se restaura el proyecto raíz y
no las referencias.
--packages <PACKAGES_DIRECTORY>

Especifica el directorio de los paquetes restaurados.


-r|--runtime <RUNTIME_IDENTIFIER>

Especifica un tiempo de ejecución para la restauración del paquete. Se usa para restaurar los
paquetes con tiempos de ejecución que no se enumeran explícitamente en la etiqueta
<RuntimeIdentifiers> del archivo .csproj. Para obtener una lista de identificadores de tiempo de
ejecución (RID ), consulte el catálogo de RID. Para proporcionar varios RID; especifique esta opción
varias veces.
-s|--source <SOURCE>

Especifica un origen de paquetes de NuGet que se usará durante la operación de restauración. Este
valor invalida todos los orígenes especificados en los archivos nuget.config. Al especificar esta
opción varias veces, se pueden proporcionar varios orígenes.
--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] ,
n[ormal] , d[etailed] y diag[nostic] . El valor predeterminado es minimal .

--interactive

Permite que el comando se detenga y espere la entrada o acción del usuario (por ejemplo,
completar la autenticación). Desde .NET Core 2.1.400.

Ejemplos
Restauración de dependencias y herramientas para el proyecto en el directorio actual:
dotnet restore

Restauración de dependencias y herramientas para el proyecto app1 encontrado en la ruta de


acceso dada:
dotnet restore ~/projects/app1/app1.csproj

Restaurar las dependencias y las herramientas para el proyecto en el directorio actual con la ruta de
acceso de archivo proporcionada como origen:
dotnet restore -s c:\packages\mypackages

Restaurar las dependencias y las herramientas para el proyecto en el directorio actual mediante las
dos rutas de acceso de archivo proporcionadas como orígenes:
dotnet restore -s c:\packages\mypackages -s c:\packages\myotherpackages

Restauración de dependencias y herramientas para el proyecto en el directorio actual que muestra


una salida detallada:
dotnet restore --verbosity detailed
dotnet run
25/11/2019 • 14 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet run : ejecuta el código fuente sin comandos explícitos de compilación o inicio.

Sinopsis
.NET Core 3.0
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet run [-c|--configuration] [-f|--framework] [--force] [--interactive] [--launch-profile] [--no-


build] [--no-dependencies]
[--no-launch-profile] [--no-restore] [-p|--project] [-r|--runtime] [-v|--verbosity] [[--]
[application arguments]]
dotnet run [-h|--help]

DESCRIPCIÓN
El comando dotnet run proporciona una opción conveniente para ejecutar la aplicación desde el código
fuente con un comando. Es útil para un desarrollo iterativo rápido desde la línea de comandos. El comando
depende del comando dotnet build para compilar el código. Los requisitos para la compilación, como que
el cliente se deba restaurar primero, también se aplican a dotnet run .
Los archivos de salida se escriben en la ubicación predeterminada, que es bin/<configuration>/<target> . Por
ejemplo, si tiene una aplicación netcoreapp2.1 y ejecuta dotnet run , la salida se colocará en
bin/Debug/netcoreapp2.1 . Los archivos se sobrescriben según sea necesario. Los archivos temporales se
colocan en el directorio obj .
Si el proyecto especifica varios marcos, al ejecutar dotnet run se produce un error a menos que se use la
opción -f|--framework <FRAMEWORK> para especificar el marco.
El comando dotnet run debe usarse en el contexto de proyectos, no de ensamblados compilados. Si, por el
contrario, está intentando ejecutar una DLL de aplicación dependiente del marco de trabajo, debe usar
dotnet sin un comando. Por ejemplo, para ejecutar myapp.dll , use:

dotnet myapp.dll

Para más información sobre el controlador dotnet , consulte el tema Herramientas de la interfaz de la línea
de comandos (CLI) de .NET Core .
Para ejecutar la aplicación, el comando dotnet run resuelve las dependencias de la aplicación que se
encuentran fuera del entorno de tiempo de ejecución compartido desde la caché de NuGet. Dado que se
usan dependencias almacenadas en caché, no se recomienda utilizar dotnet run para ejecutar aplicaciones
en producción. En su lugar, cree una implementación mediante el comando dotnet publish e implemente la
salida publicada.

NOTE
A partir de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet build y dotnet run . Sigue siendo un
comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las compilaciones
de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.
Este comando también admite las opciones dotnet restore cuando se pasan con el formato largo (por ejemplo,
--source ). No se admiten las opciones de formato corto, como -s .

Opciones
.NET Core 3.0
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
--

Delimita los argumentos a dotnet run a partir de argumentos de la aplicación que se va a ejecutar. Todos los
argumentos después de este delimitador se pasan a la aplicación que se ejecuta.
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado de la mayoría de los proyectos es Debug .


-f|--framework <FRAMEWORK>

Compila y ejecuta la aplicación con el marco especificado. El marco debe especificarse en el archivo de
proyecto.
--force

Fuerza la resolución de todas las dependencias, incluso si la última restauración se realizó correctamente.
Especificar esta marca es lo mismo que eliminar el archivo project.assets.json.
-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se detenga y espere la entrada o acción del usuario (por ejemplo, completar la
autenticación).
--launch-profile <NAME>

El nombre del perfil de inicio (si lo hay) que se usará al iniciar la aplicación. Los perfiles de inicio se definen
en el archivo launchSettings.json y se suelen denominar Development , Staging y Production . Para obtener
más información, consulte Working with multiple environments (Trabajo con varios entornos).
--no-build

No compila el proyecto antes de ejecutarlo. También establece la marca --no-restore de forma implícita.
--no-dependencies

Al restaurar un proyecto con referencias de proyecto a proyecto (P2P ), se restaura el proyecto raíz y no las
referencias.
--no-launch-profile

No intenta usar launchSettings.json para configurar la aplicación.


--no-restore

No ejecuta una restauración implícita al ejecutar el comando.


-p|--project <PATH>

Especifica la ruta de acceso del archivo del proyecto que se va a ejecutar (nombre de la carpeta o ruta de
acceso completa). Si no se especifica, se toma como predeterminado el directorio actual.
--runtime <RUNTIME_IDENTIFIER>

Especifica el tiempo de ejecución de destino para el que restaurar los paquetes. Para obtener una lista de
identificadores de tiempo de ejecución (RID ), consulte el catálogo de RID.
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

Ejemplos
Ejecución del proyecto en el directorio actual:
dotnet run

Ejecución del proyecto especificado:


dotnet run --project ./projects/proj1/proj1.csproj

Ejecute el proyecto en el directorio actual (el argumento --help en este ejemplo se pasa a la aplicación,
dado que se usa la opción -- en blanco):
dotnet run --configuration Release -- --help

Restaure las dependencias y herramientas del proyecto en el directorio actual mostrando solo la salida
mínima y, después, ejecute el proyecto: (SDK de .NET Core 2.0 y versiones superiores):
dotnet run --verbosity m
dotnet sln
19/01/2020 • 4 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

NOMBRE
dotnet sln : modifica un archivo de solución de .NET Core.

Sinopsis
dotnet sln [<SOLUTION_FILE>] [command] [-h|--help]

Descripción
El comando dotnet sln proporciona una opción conveniente para agregar, quitar y enumerar los proyectos
en un archivo de solución.
Para usar el comando dotnet sln , debe existir el archivo de solución. Si necesita crear uno, use el comando
dotnet new, como en el ejemplo siguiente:

dotnet new sln

Argumentos
SOLUTION_FILE

El archivo de solución que se va a usar. Si no se especifica, el comando busca uno en el directorio


actual. Si hay varios archivos de solución en el directorio, se debe especificar uno.

Opciones
-h|--help

Imprime una corta ayuda para el comando.

Comandos
add

Agrega un proyecto o varios proyectos al archivo de solución.


Sinopsis

dotnet sln [<SOLUTION_FILE>] add [--in-root] [-s|--solution-folder] <PROJECT_PATH>


dotnet sln add [-h|--help]

Argumentos
SOLUTION_FILE
El archivo de solución que se va a usar. Si no se especifica, el comando busca uno en el directorio
actual. Si hay varios archivos de solución en el directorio, se debe especificar uno.
PROJECT_PATH

La ruta de acceso al proyecto que se va a agregar a la solución. Para agregar varios proyectos, agregue
uno detrás de otro separados por espacios. Las expansiones del patrón comodines de shell de Unix y
Linux se procesan correctamente mediante el comando dotnet sln .
Opciones
-h|--help

Imprime una corta ayuda para el comando.


--in-root

Coloca el proyecto en la raíz de la solución, en lugar de crear una carpeta de la solución. Disponible
desde el SDK de .NET Core 3.0.
-s|--solution-folder

La ruta de acceso de la carpeta de la solución de destino a la que se van a agregar los proyectos.
Disponible desde el SDK de .NET Core 3.0.
remove

Quita un proyecto o varios proyectos del archivo de solución.


Sinopsis

dotnet sln [<SOLUTION_FILE>] remove <PROJECT_PATH>


dotnet sln [<SOLUTION_FILE>] remove [-h|--help]

Argumentos
SOLUTION_FILE

El archivo de solución que se va a usar. Si no se especifica, el comando busca uno en el directorio


actual. Si hay varios archivos de solución en el directorio, se debe especificar uno.
PROJECT_PATH

La ruta de acceso al proyecto que se va a quitar de la solución. Para quitar varios proyectos, agregue
uno detrás de otro separados por espacios. Las expansiones del patrón comodines de shell de Unix y
Linux se procesan correctamente mediante el comando dotnet sln .
Opciones
-h|--help

Imprime una corta ayuda para el comando.


list

Enumera todos los proyectos en un archivo de solución.


Sinopsis

dotnet sln list [-h|--help]

Argumentos
SOLUTION_FILE
El archivo de solución que se va a usar. Si no se especifica, el comando busca uno en el directorio
actual. Si hay varios archivos de solución en el directorio, se debe especificar uno.
Opciones
-h|--help

Imprime una corta ayuda para el comando.

Ejemplos
Agregue un proyecto de C# a una solución:

dotnet sln todo.sln add todo-app/todo-app.csproj

Quite un proyecto de C# de una solución:

dotnet sln todo.sln remove todo-app/todo-app.csproj

Agregue varios proyectos de C# a una solución:

dotnet sln todo.sln add todo-app/todo-app.csproj back-end/back-end.csproj

Quite varios proyectos de C# de una solución:

dotnet sln todo.sln remove todo-app/todo-app.csproj back-end/back-end.csproj

Agregue varios proyectos de C# a una solución mediante un patrón de comodines (solo para Unix y
Linux):

dotnet sln todo.sln add **/*.csproj

Quite varios proyectos de C# de una solución mediante un patrón de comodines (solo para Unix y
Linux):

dotnet sln todo.sln remove **/*.csproj


dotnet store
12/01/2020 • 3 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.x

NOMBRE
dotnet store : almacena los ensamblados especificados en el almacenamiento de paquetes en tiempo de
ejecución.

Sinopsis
dotnet store -m|--manifest -f|--framework -r|--runtime [--framework-version] [-h|--help] [--output] [--skip-
optimization] [--skip-symbols] [-v|--verbosity] [--working-dir]

Descripción
dotnet store almacena los ensamblados especificados en el almacenamiento de paquetes en tiempo de
ejecución. De forma predeterminada, los ensamblados están optimizados para el tiempo de ejecución y el
marco de trabajo de destino. Para obtener más información, consulte el tema runtime package store
(almacenamiento de paquetes en tiempo de ejecución).

Opciones necesarias
-f|--framework <FRAMEWORK>

Especifica la plataforma de destino.


-m|--manifest <PATH_TO_MANIFEST_FILE>

El archivo de manifiesto de almacenamiento de paquetes es un archivo XML que contiene la lista de paquetes
que se va a almacenar. El formato del archivo de manifiesto es compatible con el formato de proyecto de estilo
de SDK. Por tanto, se puede usar un archivo de proyecto que haga referencia a los paquetes deseados con la
opción -m|--manifest para almacenar los ensamblados en el almacenamiento de paquetes en tiempo de
ejecución. Para especificar varios archivos de manifiesto, repita la opción y la ruta de acceso para cada archivo.
Por ejemplo: --manifest packages1.csproj --manifest packages2.csproj .
-r|--runtime <RUNTIME_IDENTIFIER>

El identificador en tiempo de ejecución de destino.

Opciones no necesarias
--framework-version <FRAMEWORK_VERSION>

Especifica la versión del SDK de .NET Core. Esta opción le permite seleccionar una versión de un marco
concreto más allá del marco de trabajo especificado en la opción -f|--framework .
-h|--help

Muestra información de ayuda.


-o|--output <OUTPUT_DIRECTORY>
Especifica la ruta de acceso al almacenamiento de paquetes en tiempo de ejecución. Si no se especifica, el valor
predeterminado es el subdirectorio store del directorio de instalación de .NET Core de perfil de usuario.
--skip-optimization

Omite la fase de optimización.


--skip-symbols

Omite la generación de símbolos. Actualmente, solo se pueden generar símbolos en Windows y Linux.
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

-w|--working-dir <INTERMEDIATE_WORKING_DIRECTORY>

El directorio de trabajo que usa el comando. Si no se especifica, usa el subdirectorio obj del directorio actual.

Ejemplos
Almacenamiento de los paquetes especificados en el archivo de proyecto packages.csproj para .NET Core 2.0.0:
dotnet store --manifest packages.csproj --framework-version 2.0.0

Almacenamiento de los paquetes especificados en packages.csproj sin optimización:


dotnet store --manifest packages.csproj --skip-optimization

Vea también
Runtime package store (Almacenamiento de paquetes en tiempo de ejecución)
dotnet test
23/10/2019 • 12 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet test : controlador de prueba de .NET usado para ejecutar pruebas unitarias.

Sinopsis
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet test [<PROJECT>] [-a|--test-adapter-path] [--blame] [-c|--configuration] [--collect] [-d|--diag]


[-f|--framework] [--filter]
[-l|--logger] [--no-build] [--no-restore] [-o|--output] [-r|--results-directory] [-s|--settings] [-
t|--list-tests]
[-v|--verbosity] [-- <RunSettings arguments>]

dotnet test [-h|--help]

DESCRIPCIÓN
El comando dotnet test se usa para ejecutar pruebas unitarias en un proyecto determinado. El comando
dotnet test inicia la aplicación de la consola de ejecutor de pruebas especificada para un proyecto. El
ejecutor de pruebas ejecuta las pruebas que se definen para un marco de pruebas unitarias (por ejemplo,
MSTest, NUnit o xUnit) y notifica el éxito o fracaso de cada prueba. Si todas las pruebas son correctas, el
ejecutor de pruebas devuelve 0 como un código de salida; en caso contrario, si se produce algún error en una
prueba, devuelve 1. El ejecutor de pruebas y la biblioteca de pruebas unitarias se empaquetan como
paquetes de NuGet y se restauran como dependencias ordinarias para el proyecto.
Los proyectos de prueba especifican el ejecutor de pruebas usando un elemento <PackageReference>
ordinario, como se puede ver en este archivo de proyecto de ejemplo:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>

</Project>

Argumentos
PROJECT

Ruta de acceso al proyecto de prueba. Si no se especifica, se toma como predeterminado el directorio actual.

Opciones
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
-a|--test-adapter-path <PATH_TO_ADAPTER>

Use los adaptadores de prueba personalizados en la ruta especificada de esta ejecución de pruebas.
--blame

Ejecuta las pruebas en el modo de culpabilidad. Esta opción es útil para aislar las pruebas problemáticas que
hacen que el host de prueba se bloquee. Crea un archivo de salida en el directorio actual como Sequence.xml
que captura el orden de ejecución de pruebas antes del bloqueo.
-c|--configuration {Debug|Release}

Define la configuración de compilación. El valor predeterminado es Debug , pero la configuración del


proyecto podría invalidar esta configuración predeterminada del SDK.
--collect <DATA_COLLECTOR_FRIENDLY_NAME>

Habilita el recopilador de datos para la ejecución de pruebas. Para obtener más información, consulte
Monitor and analyze test run (Supervisar y analizar ejecuciones de pruebas).
-d|--diag <PATH_TO_DIAGNOSTICS_FILE>

Habilita el modo de diagnóstico para la plataforma de prueba y escribe mensajes de diagnóstico en el


archivo especificado.
-f|--framework <FRAMEWORK>

Busca archivos binarios de prueba para un marco específico.


--filter <EXPRESSION>

Filtra las pruebas del proyecto actual con la expresión dada. Para más información, consulte la sección
Detalles de la opción de filtro. Para obtener más información y ejemplos sobre cómo usar el filtrado de
pruebas unitarias selectivas, vea Ejecución de pruebas unitarias selectivas.
-h|--help

Imprime una corta ayuda para el comando.


-l|--logger <LoggerUri/FriendlyName>

Especifica un registrador para los resultados de pruebas.


--no-build

No compila el proyecto de prueba antes de ejecutarlo. También establece la marca --no-restore de forma
implícita.
--no-restore

No ejecuta una restauración implícita al ejecutar el comando.


-o|--output <OUTPUT_DIRECTORY>

Directorio donde se encuentran los archivos binarios que se ejecutarán.


-r|--results-directory <PATH>

El directorio donde se guardarán los resultados de pruebas. Si el directorio especificado no existe, se crea.
-s|--settings <SETTINGS_FILE>

El archivo .runsettings que se usará para ejecutar las pruebas. Configuración de pruebas unitarias con un
archivo .runsettings .
-t|--list-tests

Enumera todas las pruebas detectadas en el proyecto actual.


-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

RunSettings arguments

Argumentos pasados como configuraciones de RunSettings para la prueba. Los argumentos se especifican
como [name]=[value] pares después de "-- " (tenga en cuenta el espacio después de --). Se usa un espacio
para separar varios pares de [name]=[value] .
Ejemplo: dotnet test -- MSTest.DeploymentEnabled=false MSTest.MapInconclusiveToFailed=True

Para obtener más información sobre RunSettings, vea vstest.console.exe: Passing RunSettings args
(vstest.console.exe: paso de argumentos RunSettings).

Ejemplos
Ejecución de las pruebas en el proyecto en el directorio actual:
dotnet test

Ejecute las pruebas en el proyecto test1 :


dotnet test ~/projects/test1/test1.csproj

Ejecute las pruebas en el proyecto en el directorio actual y genere un archivo de resultados de prueba en
formato trx:
dotnet test --logger trx

Detalles de la opción de filtro


--filter <EXPRESSION>

<Expression> tiene el formato <property><operator><value>[|&<Expression>] .


<property> es un atributo del tipo Test Case . Las siguientes son las propiedades admitidas por los marcos
de pruebas unitarias populares:

MARCO DE PRUEBA PROPIEDADES ADMITIDAS


MARCO DE PRUEBA PROPIEDADES ADMITIDAS

MSTest FullyQualifiedName
Name
ClassName
Prioridad
TestCategory

xUnit FullyQualifiedName
DisplayName
Rasgos

<operator> describe la relación entre la propiedad y el valor:

OPERADOR FUNCIÓN

= Coincidencia exacta

!= Coincidencia no exacta

~ Contiene

<value> es una cadena. Todas las búsquedas distinguen mayúsculas de minúsculas.


Una expresión sin <operator> automáticamente se considera un contains en la propiedad
FullyQualifiedName (por ejemplo, dotnet test --filter xyz es lo mismo que
dotnet test --filter FullyQualifiedName~xyz ).

Las expresiones se pueden combinar con operadores condicionales:

OPERADOR FUNCIÓN

| O

& AND

Si usa operadores condicionales (por ejemplo, (Name~TestMethod1) | (Name~TestMethod2) ), puede incluir las
expresiones entre paréntesis.
Para obtener más información y ejemplos sobre cómo usar el filtrado de pruebas unitarias selectivas, vea
Ejecución de pruebas unitarias selectivas.

Vea también
Marcos y destinos
Catálogo de identificadores de entorno de ejecución (RID ) de .NET Core
dotnet tool install
23/10/2019 • 3 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1

Name
dotnet tool install : instala la herramienta global de .NET Core especificada en el equipo.

Sinopsis
dotnet tool install <PACKAGE_NAME> <-g|--global> [--add-source] [--configfile] [--framework] [-v|--
verbosity] [--version]
dotnet tool install <PACKAGE_NAME> <--tool-path> [--add-source] [--configfile] [--framework] [-v|--
verbosity] [--version]
dotnet tool install <-h|--help>

DESCRIPCIÓN
El comando dotnet tool install permite instalar en el equipo herramientas globales de .NET Core. Para
utilizar el comando, especifique que quiere una instalación en todos los usuarios con la opción --global , o
bien especifique una ruta para instalarla usando para ello la opción --tool-path .
Las herramientas globales se instalan en los siguientes directorios de forma predeterminada cuando se
especifica la opción -g (o --global ):

SO RUTA DE ACCESO

Linux/macOS $HOME/.dotnet/tools

Windows %USERPROFILE%\.dotnet\tools

Argumentos
PACKAGE_NAME

Nombre o identificador del paquete de NuGet que contiene la herramienta global de .NET Core que se quiere
instalar.

Opciones
--add-source <SOURCE>

Agrega un origen de paquete NuGet adicional que se usará durante la instalación.


--configfile <FILE>

El archivo de configuración de NuGet (nuget.config) que se usará.


--framework <FRAMEWORK>
Especifica el marco de destino para instalar la herramienta. De forma predeterminada, el SDK de .NET Core
intenta elegir la plataforma de destino más apropiada.
-g|--global

Especifica que la instalación se realiza en todos los usuarios. No se puede combinar con la opción --tool-path
. Si no especifica esta opción, debe especificar la opción --tool-path .
-h|--help

Imprime una corta ayuda para el comando.


--tool-path <PATH>

Especifica la ubicación de donde se tiene que instalar la herramienta global. PATH puede ser una ruta absoluta
o relativa. Si la ruta no existe, el comando intenta crearla. No se puede combinar con la opción --global . Si no
especifica esta opción, debe especificar la opción --global .
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] ,
d[etailed] y diag[nostic] .

--version <VERSION_NUMBER>

La versión de la herramienta que se va instalar. De forma predeterminada, se instala la versión estable más
reciente del paquete. Utilice esta opción para instalar la versión preliminar o versiones anteriores de la
herramienta.

Ejemplos
Instala la herramienta global dotnetsay en la ubicación predeterminada:
dotnet tool install -g dotnetsay

Instala la herramienta global dotnetsay en una carpeta específica de Windows:


dotnet tool install dotnetsay --tool-path c:\global-tools

Instala la herramienta global dotnetsay en una carpeta específica de Linux/macOS:


dotnet tool install dotnetsay --tool-path ~/bin

Instala la versión 2.0.0 de la herramienta global dotnetsay:


dotnet tool install -g dotnetsay --version 2.0.0

Vea también
Herramientas globales de .NET Core
dotnet tool list
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1

Name
dotnet tool list : enumera todas las herramientas globales de .NET Core instaladas actualmente en el
directorio predeterminado de la máquina o en la ruta especificada.

Sinopsis
dotnet tool list <-g|--global>
dotnet tool list <--tool-path>
dotnet tool list <-h|--help>

DESCRIPCIÓN
El comando dotnet tool list muestra todas las herramientas globales de .NET Core instaladas para los
usuarios en el equipo (perfil de usuario actual) o en la ruta de acceso especificada. El comando enumera el
nombre del paquete, la versión instalada y el comando de la herramienta global. Para utilizar el comando list,
especifique que quiere ver las herramientas de los usuarios con la opción --global , o bien especifique una ruta
de acceso personalizada con la opción --tool-path .

Opciones
-g|--global

Enumera las herramientas globales de los usuarios. No se puede combinar con la opción --tool-path . Si no
especifica esta opción, debe especificar la opción --tool-path .
-h|--help

Imprime una corta ayuda para el comando.


--tool-path <PATH>

Especifica una ubicación personalizada para las herramientas globales. PATH puede ser una ruta absoluta o
relativa. No se puede combinar con la opción --global . Si no especifica esta opción, debe especificar la opción
--global .

Ejemplos
Enumera todas las herramientas globales instaladas para todos los usuarios en su equipo (perfil de usuario
actual):
dotnet tool list -g

Enumera las herramientas globales de una carpeta específica de Windows:


dotnet tool list --tool-path c:\global-tools
Enumera las herramientas globales de una carpeta específica de Linux/macOS:
dotnet tool list --tool-path ~/bin

Vea también
Herramientas globales de .NET Core
dotnet tool uninstall
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1

Name
dotnet tool uninstall : desinstala la herramienta global de .NET Core especificada del equipo.

Sinopsis
dotnet tool uninstall <PACKAGE_NAME> <-g|--global>
dotnet tool uninstall <PACKAGE_NAME> <--tool-path>
dotnet tool uninstall <-h|--help>

DESCRIPCIÓN
El comando dotnet tool uninstall permite desinstalar del equipo herramientas globales de .NET Core. Para
utilizar el comando, especifique que quiere quitar una herramienta de los usuarios con la opción --global o
especifique una ruta de acceso en la que está instalada la herramienta usando para ello la opción --tool-path .

Argumentos
PACKAGE_NAME

Nombre o identificador del paquete de NuGet que contiene la herramienta global de .NET Core que se quiere
desinstalar. Para conocer el nombre el paquete, use el comando dotnet tool list.

Opciones
-g|--global

Especifica que la herramienta que se va a quitar es de una instalación en el ámbito de los usuarios. No se puede
combinar con la opción --tool-path . Si no especifica esta opción, debe especificar la opción --tool-path .
-h|--help

Imprime una corta ayuda para el comando.


--tool-path <PATH>

Especifica la ubicación de donde se tiene que desinstalar la herramienta global. PATH puede ser una ruta absoluta
o relativa. No se puede combinar con la opción --global . Si no especifica esta opción, debe especificar la opción
--global .

Ejemplos
Desinstala la herramienta global dotnetsay:
dotnet tool uninstall -g dotnetsay

Desinstala la herramienta global dotnetsay de una carpeta específica de Windows:


dotnet tool uninstall dotnetsay --tool-path c:\global-tools

Desinstala la herramienta global dotnetsay de una carpeta específica de Linux/macOS:


dotnet tool uninstall dotnetsay --tool-path ~/bin

Vea también
Herramientas globales de .NET Core
dotnet tool update
23/10/2019 • 3 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.1

Name
dotnet tool update : actualiza la herramienta global de .NET Core especificada en el equipo.

Sinopsis
dotnet tool update <PACKAGE_NAME> <-g|--global> [--configfile] [--framework] [-v|--verbosity]
dotnet tool update <PACKAGE_NAME> <--tool-path> [--configfile] [--framework] [-v|--verbosity]
dotnet tool update <-h|--help>

DESCRIPCIÓN
El comando dotnet tool update permite actualizar las herramientas globales de .NET Core en su equipo a la
versión estable más reciente del paquete. El comando desinstala y vuelve a instalar una herramienta,
actualizándola de facto. Para utilizar el comando, especifique que quiere actualizar una herramienta de una
instalación en el ámbito de los usuarios con la opción --global , o bien especifique una ruta de acceso en la que
instalar la herramienta usando para ello la opción --tool-path .

Argumentos
PACKAGE_NAME

Nombre o identificador del paquete de NuGet que contiene la herramienta global de .NET Core que se quiere
actualizar. Para conocer el nombre el paquete, use el comando dotnet tool list.

Opciones
--add-source <SOURCE>

Agrega un origen de paquete NuGet adicional que se usará durante la instalación.


--configfile <FILE>

El archivo de configuración de NuGet (nuget.config) que se usará.


--framework <FRAMEWORK>

Especifica la plataforma de destino para la que se actualiza la herramienta.


-g|--global

Especifica que la actualización es para una herramienta del ámbito de los usuarios. No se puede combinar con la
opción --tool-path . Si no especifica esta opción, debe especificar la opción --tool-path .
-h|--help

Imprime una corta ayuda para el comando.


--tool-path <PATH>

Especifica la ubicación en la que está instalada la herramienta global. PATH puede ser una ruta absoluta o relativa.
No se puede combinar con la opción --global . Si no especifica esta opción, debe especificar la opción --global .
-v|--verbosity <LEVEL>

Establece el nivel de detalle del comando. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] , d[etailed]
y diag[nostic] .

Ejemplos
Actualiza la herramienta global dotnetsay:
dotnet tool update -g dotnetsay

Actualiza la herramienta global dotnetsay ubicada en una carpeta específica de Windows:


dotnet tool update dotnetsay --tool-path c:\global-tools

Actualiza la herramienta global dotnetsay ubicada en una carpeta específica de Linux/macOS:


dotnet tool update dotnetsay --tool-path ~/bin

Vea también
Herramientas globales de .NET Core
dotnet vstest
23/10/2019 • 12 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

Name
dotnet-vstest : ejecuta pruebas desde los archivos especificados.

Sinopsis
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x

dotnet vstest [<TEST_FILE_NAMES>] [--Settings|/Settings] [--Tests|/Tests] [--TestAdapterPath|/TestAdapterPath]


[--Platform|/Platform] [--Framework|/Framework] [--Parallel|/Parallel] [--TestCaseFilter|/TestCaseFilter]
[--logger|/logger]
[-lt|--ListTests|/lt|/ListTests] [--ParentProcessId|/ParentProcessId] [--Port|/Port] [--Diag|/Diag] [--
Blame|/Blame] [--InIsolation|/InIsolation]
[[--] <args>...]] [-?|--Help|/?|/Help]

DESCRIPCIÓN
El comando dotnet-vstest ejecuta la aplicación de línea de comandos VSTest.Console para ejecutar pruebas
unitarias automatizadas.

Argumentos
TEST_FILE_NAMES

Ejecutar pruebas desde los ensamblados especificados. Separar varios nombres de ensamblado de prueba con
espacios.

Opciones
.NET Core 2.1
.NET Core 2.0
.NET Core 1.x
--Settings|/Settings:<Settings File>

Configuración que se usará al ejecutar las pruebas.


--Tests|/Tests:<Test Names>

Ejecuta las pruebas con nombres que coinciden con los Separar varios valores con comas.
--TestAdapterPath|/TestAdapterPath

Usar adaptadores de prueba personalizados desde una ruta de acceso especificada (si existe) en la serie de
pruebas.
--Platform|/Platform:<Platform type>

Identificar la arquitectura de la plataforma usada en la ejecución de pruebas. Valores válidos son x86 , x64 y ARM .
--Framework|/Framework:<Framework Version>

Identificar la versión de .NET Framework usada en la ejecución de pruebas. Ejemplos de valores válidos son
.NETFramework,Version=v4.6 o .NETCoreApp,Version=v1.0 . Otros valores admitidos son Framework40 , Framework45 ,
FrameworkCore10 y FrameworkUap10 .

--Parallel|/Parallel

Ejecutar pruebas en paralelo. De forma predeterminada, todos los núcleos disponibles en el equipo están
disponibles para su uso. Especifique un número explícito de núcleos mediante la configuración de la propiedad
MaxCpuCount en el nodo RunConfiguration del archivo runsettings.
--TestCaseFilter|/TestCaseFilter:<Expression>

Ejecuta pruebas que coinciden con la expresión dada. <Expression> tiene el formato
<property>Operator<value>[|&<Expression>] , donde Operator es = , != o ~ . El operador ~ tiene semántica
"contains" y se aplica a las propiedades de cadena como DisplayName . Los paréntesis () se usan para agrupar
expresiones secundarias.
-?|--Help|/?|/Help

Imprime una corta ayuda para el comando.


--logger|/logger:<Logger Uri/FriendlyName>

Especifica un registrador para resultados de pruebas.


Para publicar resultados de pruebas en Team Foundation Server, use el proveedor de registrador
TfsPublisher :

/logger:TfsPublisher;
Collection=<team project collection url>;
BuildName=<build name>;
TeamProject=<team project name>
[;Platform=<Defaults to "Any CPU">]
[;Flavor=<Defaults to "Debug">]
[;RunTitle=<title>]

Para registrar los resultados en un archivo de resultados de pruebas (TRX) de Visual Studio, use el
proveedor de registrador trx . Este modificador, crea un archivo en el directorio de resultados de pruebas
con un nombre de archivo de registro dado. Si no se proporciona LogFileName , se crea un nombre de
archivo único para contener los resultados de las pruebas.

/logger:trx [;LogFileName=<Defaults to unique file name>]

-lt|--ListTests|/lt|/ListTests:<File Name>

Muestra todas las pruebas detectadas del contenedor de pruebas especificado.


--ParentProcessId|/ParentProcessId:<ParentProcessId>

Id. de proceso del proceso principal responsable de iniciar el proceso actual.


--Port|/Port:<Port>
Especifica el puerto para la conexión de socket y la recepción de mensajes de eventos.
--Diag|/Diag:<Path to log file>

Permite registros detallados para la plataforma de prueba. Los registros se escriben en el archivo proporcionado.
--Blame|/Blame

Ejecuta las pruebas en el modo de culpabilidad. Esta opción es útil para aislar las pruebas problemáticas que hacen
que el host de prueba se bloquee. Crea un archivo de salida en el directorio actual como Sequence.xml que captura
el orden de ejecución de pruebas antes del bloqueo.
--InIsolation|/InIsolation

Ejecuta las pruebas en un proceso aislado. De este modo, es menos probable que el proceso vstest.console.exe se
detenga por un error de las pruebas, pero es posible que las pruebas se ejecuten más despacio.
@<file>

Lee el archivo de respuesta para ver más opciones.


args

Especifica argumentos adicionales para pasar al adaptador. Los argumentos se especifican como pares de nombre-
valor en el formato <n>=<v> , donde <n> es el nombre del argumento y <v> es el valor del argumento. Use un
espacio para separar varios argumentos.

Ejemplos
Ejecutar pruebas en mytestproject.dll :
dotnet vstest mytestproject.dll

Ejecutar pruebas en mytestproject.dll , exportando a carpeta personalizada con nombre personalizado:


dotnet vstest mytestproject.dll --logger:"trx;LogFileName=custom_file_name.trx" --
ResultsDirectory:custom/file/path

Ejecutar pruebas en mytestproject.dll y myothertestproject.exe :


dotnet vstest mytestproject.dll myothertestproject.exe

Ejecutar pruebas TestMethod1 :


dotnet vstest /Tests:TestMethod1

Ejecutar pruebas TestMethod1 y TestMethod2 :


dotnet vstest /Tests:TestMethod1,TestMethod2
referencia de scripts de dotnet-install
19/01/2020 • 9 minutes to read • Edit Online

NOMBRE
dotnet-install.ps1 | dotnet-install.sh : script usado para instalar las herramientas de la CLI de .NET Core
y el entorno de tiempo de ejecución compartido.

Sinopsis
Windows:
dotnet-install.ps1 [-Channel] [-Version] [-InstallDir] [-Architecture] [-SharedRuntime] [-Runtime] [-
DryRun] [-NoPath] [-Verbose] [-AzureFeed] [-UncachedFeed] [-NoCdn] [-FeedCredential] [-ProxyAddress] [-
ProxyUseDefaultCredentials] [-SkipNonVersionedFiles] [-Help]

macOS y Linux:
dotnet-install.sh [--channel] [--version] [--install-dir] [--architecture] [--runtime] [--dry-run] [--no-
path] [--verbose] [--azure-feed] [--uncached-feed] [--no-cdn] [--feed-credential] [--runtime-id] [--skip-
non-versioned-files] [--help]

Descripción
Los scripts dotnet-install se usan para realizar una instalación sin derechos administrativos del SDK de
.NET Core, que incluye las herramientas de la CLI de .NET Core y el entorno de tiempo de ejecución
compartido.
Le recomendamos que use la versión estable que se hospeda en el sitio web principal de .NET Core. Las
rutas de acceso directas a los scripts son las siguientes:
https://dot.net/v1/dotnet-install.sh (bash, UNIX)
https://dot.net/v1/dotnet-install.ps1 (Powershell, Windows)
La utilidad principal de estos scripts está en los escenarios de automatización y las instalaciones sin derechos
administrativos. Existen dos scripts: uno es un script de PowerShell que funciona en Windows y el otro es un
script de Bash que funciona en Linux y macOS. Ambos scripts tienen el mismo comportamiento. El script de
bash también lee modificadores de PowerShell, por lo que puede usar modificadores de PowerShell con el
script en sistemas Linux y macOS.
Los scripts de instalación descargan el archivo ZIP o tarball desde las entregas de compilación de la CLI y
proceden a instalarlo en la ubicación predeterminada o en una ubicación especificada por
-InstallDir|--install-dir . De forma predeterminada, los scripts de instalación descargan el SDK y lo
instalan. Si desea obtener solo el tiempo de ejecución compartido, especifique el argumento --runtime .
De forma predeterminada, el script agrega la ubicación de instalación a $PATH para la sesión actual. Para
invalidar este comportamiento, especifique el argumento --no-path .
Antes de ejecutar el script, instale las dependencias necesarias.
Puede instalar una versión específica mediante el argumento --version . La versión debe especificarse como
una versión de tres partes (por ejemplo, 1.0.0-13232). Si no se proporciona, usa la versión latest .

Opciones
-Channel <CHANNEL>

Especifica el canal de origen para la instalación. Los valores posibles son:


Current : versión más actual.
LTS : canal de soporte técnico a largo plazo (versión compatible más actual).
Versión de dos partes en formato X.Y que representa una versión específica (por ejemplo, 2.0 o
1.0 ).
Nombre de rama. Por ejemplo, release/2.0.0 , release/2.0.0-preview2 o master (para versiones
nocturnas).
El valor predeterminado es LTS . Para más información sobre los canales de soporte técnico de .NET,
vea la página .NET Support Policy (Directiva de soporte técnico de .NET Core).
-Version <VERSION>

Representa una versión de compilación concreta. Los valores posibles son:


latest : compilación más reciente en el canal (utilizado con la opción -Channel ).
coherent : compilación coherente más reciente en el canal; usa la última combinación de paquetes
estables (usados con las opciones -Channel del nombre de la rama).
Versión de tres partes en formato X.Y.Z que representa una determinada versión de compilación;
reemplaza a la opción -Channel . Por ejemplo: 2.0.0-preview2-006120 .
Si no se especifica, el valor predeterminado de -Version es latest .
-InstallDir <DIRECTORY>

Especifica la ruta de instalación. Si no existe el directorio, se crea. El valor predeterminado es


%LocalAppData%\Microsoft\dotnet. Los archivos binarios se colocan directamente en el directorio.
-Architecture <ARCHITECTURE>

Arquitectura de los archivos binarios de .NET Core para instalar. Los valores posibles son <auto> ,
amd64 , x64 , x86 , arm64 y arm . El valor predeterminado es <auto> , que representa la arquitectura
de SO que se ejecuta en ese momento.
-SharedRuntime

NOTE
Este parámetro está obsoleto y puede quitarse en una versión futura del script. La alternativa recomendada es
la opción Runtime .

Se instalan simplemente los bits del entorno de tiempo de ejecución compartido, no el SDK completo.
Es equivalente a especificar -Runtime dotnet .
-Runtime <RUNTIME>

Se instala simplemente el entorno de tiempo de ejecución compartido, no el SDK completo. Los


valores posibles son:
dotnet : el entorno de tiempo de ejecución compartido Microsoft.NETCore.App .
aspnetcore : el entorno de tiempo de ejecución compartido Microsoft.AspNetCore.App .
-DryRun

Si se establece, el script no realizará la instalación. En su lugar, mostrará qué línea de comandos se va


a usar para instalar de manera coherente la versión solicitada actualmente de la CLI de .NET Core. Por
ejemplo, si especifica la versión latest , se muestra un vínculo con la versión específica, de manera
que este comando puede usarse de manera determinista en un script de compilación. También se
muestra la ubicación de los archivos binarios si prefiere instalarla o descargarla por su cuenta.
-NoPath

Si se establece, la carpeta de instalación no se exporta a la ruta de acceso para la sesión actual. De


manera predeterminada, el script modifica la ruta de acceso, que hace que las herramientas de la CLI
estén disponibles inmediatamente después de la instalación.
-Verbose

Muestra la información de diagnóstico.


-AzureFeed

Especifica la dirección URL de la fuente de Azure al instalador. Le recomendamos que no cambie este
valor. El valor predeterminado es https://dotnetcli.azureedge.net/dotnet .
-UncachedFeed

Permite cambiar la dirección URL de la fuente no almacenada en caché que este instalador utiliza. Le
recomendamos que no cambie este valor.
-NoCdn

Deshabilita la descarga desde Azure Content Delivery Network (CDN ) y usa la fuente no almacenada
en caché directamente.
-FeedCredential

Se utiliza como una cadena de consulta para anexar a la fuente de Azure. Permite cambiar la dirección
URL para usar cuentas de almacenamiento de blobs no público.
-ProxyAddress

Si se establece, el instalador usa el proxy al realizar solicitudes web. (Solo es válido para Windows)
ProxyUseDefaultCredentials

Si se establece, el instalador usa las credenciales del usuario actual cuando se usa la dirección del
proxy. (Solo es válido para Windows)
-SkipNonVersionedFiles

Omite la instalación de archivos sin control de versiones, como dotnet.exe, si ya existen.


-Help

Imprime la ayuda para el script.

Ejemplos
Instale la versión compatible a largo plazo más reciente en la ubicación predeterminada:
Windows:

./dotnet-install.ps1 -Channel LTS

macOS y Linux:
./dotnet-install.sh --channel LTS

Instale la versión más reciente del canal 2.0 en la ubicación especificada:


Windows:

./dotnet-install.ps1 -Channel 2.0 -InstallDir C:\cli

macOS y Linux:

./dotnet-install.sh --channel 2.0 --install-dir ~/cli

Instale la versión 1.1.0 del entorno de tiempo de ejecución compartido:


Windows:

./dotnet-install.ps1 -Runtime dotnet -Version 1.1.0

macOS y Linux:

./dotnet-install.sh --runtime dotnet --version 1.1.0

Obtenga el script e instale la versión 2.1.2 detrás de un proxy corporativo (solo Windows):

Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -Proxy $env:HTTP_PROXY -


ProxyUseDefaultCredentials -OutFile 'dotnet-install.ps1';
./dotnet-install.ps1 -InstallDir '~/.dotnet' -Version '2.1.2' -ProxyAddress $env:HTTP_PROXY -
ProxyUseDefaultCredentials;

Obtenga el script e instale ejemplos de una línea para la CLI de .NET Core:
Windows:

# Run a separate PowerShell process because the script calls exit, so it will end the current
PowerShell session.
&powershell -NoProfile -ExecutionPolicy unrestricted -Command "
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &
([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-
install.ps1'))) <additional install-script args>"

macOS y Linux:

curl -ssl https://dot.net/v1/dotnet-install.sh | bash /dev/stdin <additional install-script args>

Vea también
Versiones de .NET Core
Archivo de descarga del SDK y .NET Core Runtime
dotnet add reference
25/11/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet add reference Agrega referencias entre proyectos (P2P ) .

Sinopsis
dotnet add [<PROJECT>] reference [-f|--framework] <PROJECT_REFERENCES> [-h|--help] [--interactive]

Descripción
El comando dotnet add reference constituye una opción práctica para agregar referencias de proyecto a un
proyecto. Después de ejecutar el comando, los elementos <ProjectReference> se agregan al archivo del
proyecto.

<ItemGroup>
<ProjectReference Include="app.csproj" />
<ProjectReference Include="..\lib2\lib2.csproj" />
<ProjectReference Include="..\lib1\lib1.csproj" />
</ItemGroup>

Argumentos
PROJECT

Especifica el archivo del proyecto. Si no se especifica, el comando busca uno en el directorio actual.
PROJECT_REFERENCES

Referencias entre proyectos (P2P ) que se van a agregar. Especifique uno o más proyectos. El patrón
glob se admite en sistemas basados en Unix/Linux.

Opciones
-h|--help

Imprime una corta ayuda para el comando.


-f|--framework <FRAMEWORK>

Agrega referencias de proyecto solo cuando apunta a unmarco específico.


--interactive

Permite que el comando se detenga y espere la entrada o acción del usuario (por ejemplo, completar la
autenticación). Disponible desde el SDK de .NET Core 3.0.

Ejemplos
Agregar una referencia de proyecto:

dotnet add app/app.csproj reference lib/lib.csproj

Agregar varias referencias de proyecto al proyecto en el directorio actual:

dotnet add reference lib1/lib1.csproj lib2/lib2.csproj

Agregar varias referencias de proyecto usando el patrón global en Linux/Unix:

dotnet add app/app.csproj reference **/*.csproj


dotnet list reference
23/10/2019 • 2 minutes to read • Edit Online

Este tema se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet list reference : enumera las referencias entre proyectos.

Sinopsis
dotnet list [<PROJECT>|<SOLUTION>] reference [-h|--help]

DESCRIPCIÓN
El comando dotnet list reference constituye una opción práctica para enumerar las referencias de proyecto de
un proyecto o solución concreta.

Argumentos
PROJECT | SOLUTION

Especifica el archivo de solución o proyecto que se usará para enumerar las referencias. Si no se especifica,
el comando busca un archivo del proyecto en el directorio actual.

Opciones
-h|--help

Imprime una corta ayuda para el comando.

Ejemplos
Enumerar las referencias del proyecto para el proyecto especificado:

dotnet list app/app.csproj reference

Enumerar las referencias del proyecto para el proyecto en el directorio actual:

dotnet list reference


dotnet remove reference
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

nombre
dotnet remove reference : quita las referencias de proyecto a proyecto.

Sinopsis
dotnet remove [<PROJECT>] reference [-f|--framework] <PROJECT_REFERENCES> [-h|--help]

Descripción
El comando dotnet remove reference constituye una opción práctica para quitar referencias de proyecto de un
proyecto.

Argumentos
PROJECT

Archivo de proyecto de destino. Si no se especifica, el comando busca uno en el directorio actual.


PROJECT_REFERENCES

Referencias de proyecto a proyecto (P2P ) que se van a quitar. Puede especificar uno o varios proyectos. Se
admiten patrones globales en terminales basados en Unix o Linux.

Opciones
-h|--help

Imprime una corta ayuda para el comando.


-f|--framework <FRAMEWORK>

Quita la referencia solo cuando el destino es un marco de trabajo específico.

Ejemplos
Quitar una referencia de proyecto del proyecto especificado:
dotnet remove app/app.csproj reference lib/lib.csproj

Quitar varias referencias de proyecto del proyecto en el directorio actual:


dotnet remove reference lib1/lib1.csproj lib2/lib2.csproj

Quitar varias referencias de proyecto con un patrón global en Unix/Linux:


dotnet remove app/app.csproj reference **/*.csproj
dotnet add package
23/10/2019 • 4 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x y versiones posteriores

Name
dotnet add package : agrega una referencia de paquete a un archivo del proyecto.

Sinopsis
dotnet add [<PROJECT>] package <PACKAGE_NAME> [-h|--help] [-f|--framework] [--interactive] [-n|--no-restore]
[--package-directory] [-s|--source] [-v|--version]

DESCRIPCIÓN
El comando dotnet add package constituye una opción práctica para agregar una referencia de paquete a un
archivo del proyecto. Después de ejecutar el comando, existe una comprobación de compatibilidad para
garantizar que el paquete es compatible con los marcos del proyecto. Si se pasa la comprobación, un elemento
<PackageReference> se agrega al archivo del proyecto y dotnet restore se ejecuta.

NOTE
A partir del SDK de .NET Core 2.0, no es necesario ejecutar dotnet restore porque lo ejecutan implícitamente todos los
comandos que requieren que se produzca una restauración, como dotnet new , dotnet build y dotnet run . Sigue
siendo un comando válido en algunos escenarios donde tiene sentido realizar una restauración explícita, como las
compilaciones de integración continua en Azure DevOps Services o en los sistemas de compilación que necesitan controlar
explícitamente la hora a la que se produce la restauración.

Por ejemplo, si agrega Newtonsoft.Json a ToDo.csproj se producirá un resultado similar al del siguiente ejemplo:

Writing C:\Users\mairaw\AppData\Local\Temp\tmp95A8.tmp
info : Adding PackageReference for package 'Newtonsoft.Json' into project 'C:\projects\ToDo\ToDo.csproj'.
log : Restoring packages for C:\Temp\projects\consoleproj\consoleproj.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json 79ms
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/12.0.1/newtonsoft.json.12.0.1.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/12.0.1/newtonsoft.json.12.0.1.nupkg 232ms
log : Installing Newtonsoft.Json 12.0.1.
info : Package 'Newtonsoft.Json' is compatible with all the specified frameworks in project
'C:\projects\ToDo\ToDo.csproj'.
info : PackageReference for package 'Newtonsoft.Json' version '12.0.1' added to file
'C:\projects\ToDo\ToDo.csproj'.

El archivo ToDo.csproj contiene ahora un elemento <PackageReference> para el paquete al que hace referencia.

<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />

Argumentos
PROJECT
Especifica el archivo del proyecto. Si no se especifica, el comando busca uno en el directorio actual.
PACKAGE_NAME

La referencia de paquete que se va a agregar.

Opciones
-f|--framework <FRAMEWORK>

Agrega una referencia de paquete solo cuando se destina a un marco específico.


-h|--help

Imprime una corta ayuda para el comando.


--interactive

Permite que el comando se detenga y espere la entrada o acción del usuario (por ejemplo, completar la
autenticación). Disponible desde el SDK de .NET Core 2.1, versión 2.1.400 o posterior.
-n|--no-restore

Agrega una referencia de paquete sin realizar una vista previa de restauración y una comprobación de
compatibilidad.
--package-directory <PACKAGE_DIRECTORY>

Directorio donde quiere restaurar los paquetes. La ubicación predeterminada de restauración de paquetes
es %userprofile%\.nuget\packages en Windows y ~/.nuget/packages en macOS y Linux. Para obtener más
información, vea Administración de las carpetas de paquetes globales, de caché y temporales in NuGet.
-s|--source <SOURCE>

Origen del paquete NuGet que se usará durante la operación de restauración.


-v|--version <VERSION>

Versión del paquete. Consulte NuGet package versioning (Control de versiones de paquetes NuGet).

Ejemplos
Agregar un paquete de NuGet Newtonsoft.Json a un proyecto:

dotnet add package Newtonsoft.Json

Agregar una versión específica de un paquete a un proyecto:

dotnet add ToDo.csproj package Microsoft.Azure.DocumentDB.Core -v 1.0.0

Agregar un paquete con un origen de NuGet específico:

dotnet add package Microsoft.AspNetCore.StaticFiles -s https://dotnet.myget.org/F/dotnet-


core/api/v3/index.json

Vea también
Administración de las carpetas de paquetes globales, de caché y temporales en NuGet
Control de versiones de paquetes NuGet
dotnet list package
23/10/2019 • 6 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 2.2.x y versiones posteriores

Name
dotnet list package : muestra las referencias de paquete de un proyecto o una solución.

Sinopsis
dotnet list [<PROJECT>|<SOLUTION>] package [--config] [--framework] [--highest-minor] [--highest-patch]
[--include-prerelease] [--include-transitive] [--interactive] [--outdated] [--source]
dotnet list package [-h|--help]

DESCRIPCIÓN
El comando dotnet list package ofrece una opción práctica para mostrar todas las referencias de paquete de
NuGet de una solución o un proyecto específico. Primero deberá crear el proyecto para tener los recursos
necesarios para que este comando se procese. En el ejemplo siguiente se muestra la salida del comando
dotnet list package para el proyecto SentimentAnalysis:

Project 'SentimentAnalysis' has the following package references


[netcoreapp2.1]:
Top-level Package Requested Resolved
> Microsoft.ML 0.11.0 0.11.0
> Microsoft.NETCore.App (A) [2.1.0, ) 2.1.0

(A) : Auto-referenced package.

La columna Requested hace referencia a la versión de paquete especificada en el archivo del proyecto y puede ser
un intervalo. La columna Resolved muestra la versión que el proyecto usa actualmente y siempre se trata de un
valor único. Los paquetes que tienen (A) junto al nombre representan referencias implícitas de paquete que se
deducen de la configuración del proyecto (tipo de Sdk , propiedad <TargetFramework> o <TargetFrameworks> , etc.).
Use la opción --outdated para averiguar si hay disponibles más recientes de los paquetes que usa en los
proyectos. De manera predeterminada, --outdated muestra los paquetes estables más recientes, a menos que la
versión resuelta también sea una versión preliminar. Para incluir versiones preliminares cuando se muestren
versiones más recientes, especifique también la opción --include-prerelease . En los ejemplos siguientes se
muestra la salida del comando dotnet list package --outdated --include-prerelease para el mismo proyecto, tal
como en el ejemplo anterior:

The following sources were used:


https://api.nuget.org/v3/index.json

Project `SentimentAnalysis` has the following updates to its packages


[netcoreapp2.1]:
Top-level Package Requested Resolved Latest
> Microsoft.ML 0.11.0 0.11.0 1.0.0-preview
Si tiene que averiguar si el proyecto tiene dependencias transitivas, use la opción --include-transitive . Las
dependencias transitivas se producen cuando se agrega un paquete al proyecto que, a su vez, se basa en otro
paquete. En el ejemplo siguiente se muestra la salida de la ejecución del comando
dotnet list package --include-transitive en el proyecto HelloPlugin, que muestra paquetes de nivel superior y los
paquetes de los que dependen:

Project 'HelloPlugin' has the following package references


[netcoreapp3.0]:
Top-level Package Requested Resolved
> Microsoft.NETCore.Platforms (A) [3.0.0-preview3.19128.7, ) 3.0.0-preview3.19128.7
> Microsoft.WindowsDesktop.App (A) [3.0.0-preview3-27504-2, ) 3.0.0-preview3-27504-2

Transitive Package Resolved


> Microsoft.NETCore.Targets 2.0.0
> PluginBase 1.0.0

(A) : Auto-referenced package.

Argumentos
PROJECT | SOLUTION

El archivo de proyecto o solución donde se operará. Si no se especifica, el comando busca uno en el directorio
actual. Si se encuentra más de una solución o proyecto, se genera un error.

Opciones
--config <SOURCE>

Los orígenes de NuGet que se usarán al buscar paquetes más recientes. Requiere la opción --outdated .
--framework <FRAMEWORK>

Muestra solo los paquetes aplicables al marco de destino especificado. Para especificar varios marcos, repita
la opción varias veces. Por ejemplo: --framework netcoreapp2.2 --framework netstandard2.0 .
-h|--help

Imprime una corta ayuda para el comando.


--highest-minor

Considere solo los paquetes con un número de versión principal coincidente al buscar paquetes más
recientes. Requiere la opción --outdated .
--highest-patch

Considere solo los paquetes con número de versión principal y secundario coincidente al buscar paquetes
más recientes. Requiere la opción --outdated .
--include-prerelease

Considere los paquetes con versiones preliminares al buscar paquetes más recientes. Requiere la opción
--outdated .

--include-transitive

Enumera los paquetes transitivos, además de los paquetes de nivel superior. Al especificar esta opción,
recibe una lista de paquetes de los que dependen los paquetes de nivel superior.
--interactive

Permite que el comando se detenga y espere una entrada o una acción del usuario. Por ejemplo, para
completar la autenticación. Disponible desde el SDK de .NET Core 3.0.
--outdated

Enumera los paquetes con versiones más recientes disponibles.


-s|--source <SOURCE>

Los orígenes de NuGet que se usarán al buscar paquetes más recientes. Requiere la opción --outdated .

Ejemplos
Muestre las referencias de paquete de un proyecto específico:

dotnet list SentimentAnalysis.csproj package

Muestre las referencias de paquete que tienen versiones más recientes disponibles, incluidas versiones
preliminares:

dotnet list package --outdated --include-prerelease

Muestre las referencias de paquete para un marco de destino específico:

dotnet list package --framework netcoreapp3.0


dotnet remove package
23/10/2019 • 2 minutes to read • Edit Online

Este artículo se aplica a: ✓ SDK de .NET Core 1.x ✓ SDK de .NET Core 2.x

nombre
dotnet remove package : quita la referencia de paquete de un archivo de proyecto.

Sinopsis
dotnet remove [<PROJECT>] package <PACKAGE_NAME> [-h|--help]

Descripción
El comando dotnet remove package constituye una opción práctica para quitar una referencia de paquete NuGet
de un proyecto.

Argumentos
PROJECT

Especifica el archivo del proyecto. Si no se especifica, el comando busca uno en el directorio actual.
PACKAGE_NAME

La referencia de paquete que hay que quitar.

Opciones
-h|--help

Imprime una corta ayuda para el comando.

Ejemplos
Quita el paquete NuGet Newtonsoft.Json de un proyecto en el directorio actual:
dotnet remove package Newtonsoft.Json
Herramientas adicionales de .NET Core
08/01/2020 • 4 minutes to read • Edit Online

En esta sección se recopila una lista de herramientas compatibles con las funcionalidades de .NET Core y que las
amplían, además de las herramientas de la interfaz de la línea de comandos (CLI) de .NET Core.

Herramienta de desinstalación de .NET Core


La herramienta de desinstalación de .NET Core ( dotnet-core-uninstall ) permite limpiar los SDK y los entornos de
ejecución de .NET Core en un sistema, de modo que solo queden las versiones especificadas. Hay una colección de
opciones disponible para especificar las versiones que se van a desinstalar.

Herramienta WCF Web Service Reference


WCF (Windows Communication Foundation) Web Services Reference es un proveedor de servicios conectados de
Visual Studio que se estrenó en la versión 15.5 de Visual Studio 2017. Esta herramienta recupera metadatos de un
servicio web en la solución actual, en una ubicación de red o desde un archivo WSDL. Genera un archivo de código
fuente compatible con .NET Core, que define una clase de proxy de WCF con métodos que se pueden usar para
acceder a las operaciones del servicio web.

Herramienta dotnet-svcutil de WCF


La herramienta dotnet-svcutil de WCF (Windows Communication Foundation) es una herramienta de la CLI de
.NET Core que recupera los metadatos de un servicio web en una ubicación de red o en un archivo WSDL. Genera
un archivo de código fuente compatible con .NET Core, que define una clase de proxy de WCF con métodos que se
pueden usar para acceder a las operaciones del servicio web.
La herramienta dotnet-svcutil es una alternativa al proveedor de servicios conectados de Visual Studio
WCF Web Service Reference que se distribuyó por primera vez en la versión 15.5 de Visual Studio 2017. La
herramienta multiplataforma dotnet-svcutil, como herramienta de la CLI de .NET Core, está disponible en Linux,
macOS y Windows.

Herramienta dotnet-svcutil.xmlserializer de WCF


En .NET Framework, puede generar previamente un ensamblado de serialización con la herramienta svcutil. El
paquete NuGet dotnet-svcutil.xmlserializer proporciona una funcionalidad parecida en .NET Core. Genera
previamente código de serialización de C# para los tipos de la aplicación cliente que usa el contrato de servicio de
WCF y que puede serializar XmlSerializer. Esto mejora el rendimiento de inicio de la serialización de XML al
serializar o deserializar objetos de esos tipos.

Generador de serializador XML


Tal y como sucede con el generador serializador de XML (sgen.exe) para .NET Framework, el paquete NuGet
Microsoft.XmlSerializer.Generator es la solución para las bibliotecas .NET Core y .NET Standard. Crea un
ensamblado de serialización de XML para los tipos contenidos en un ensamblado para mejorar el rendimiento de
inicio de la serialización XML al serializar o deserializar objetos de esos tipos con XmlSerializer.
Herramienta de desinstalación de .NET Core
20/01/2020 • 24 minutes to read • Edit Online

La herramienta de desinstalación de .NET Core ( dotnet-core-uninstall ) permite quitar los SDK y los entornos en
tiempo de ejecución de .NET Core de un sistema. Hay una colección de opciones disponible para especificar las
versiones que desea desinstalar.
La herramienta es compatible con Windows y macOS. Linux no se admite actualmente.
En Windows, la herramienta solo puede desinstalar los SDK y entornos en tiempo de ejecución que se instalaron
mediante uno de los siguientes instaladores:
El instalador del SDK y del entorno en tiempo de ejecución de .NET Core.
El instalador de Visual Studio en versiones anteriores a Visual Studio 2019, versión 16.3.
En macOS, la herramienta solo puede desinstalar los SDK y entornos en tiempo de ejecución ubicados en la
carpeta /usr/local/share/dotnet.
Debido a estas limitaciones, es posible que la herramienta no pueda desinstalar todos los SDK y los entornos en
tiempo de ejecución de .NET Core de la máquina. Puede usar el comando dotnet --info para buscar todos los
SDK y los entornos en tiempo de ejecución de .NET Core instalados, incluidos los entornos en tiempo de ejecución
y SDK que esta herramienta no puede quitar. El comando dotnet-core-uninstall list muestra qué SDK se
pueden desinstalar con la herramienta.

Instalación de la herramienta
Puede descargar la herramienta de desinstalación de .NET Core del repositorio de GitHub dotnet/cli-lab.

NOTE
La herramienta requiere elevación para desinstalar los SDK y los entornos en tiempo de ejecución de .NET Core. Por lo tanto,
debe instalarse en un directorio protegido contra escritura, como C:\Archivos de programa en Windows o /usr/local/bin en
macOS. Consulte también Acceso con privilegios elevados para comandos de dotnet. Puede encontrar instrucciones de
instalación detalladas en la página de versiones de GitHub.

Ejecución de la herramienta
En los pasos siguientes se muestra el enfoque recomendado para ejecutar la herramienta de desinstalación:
Paso 1: Mostrar los SDK y los entornos en tiempo de ejecución de .NET Core instalados
Paso 2: Realizar un simulacro
Paso 3: Desinstalar los SDK y los entornos en tiempo de ejecución de .NET Core
Paso 4: Eliminar la carpeta de reserva de NuGet (opcional)
Paso 1: Mostrar los SDK y los entornos en tiempo de ejecución de .NET Core instalados
El comando dotnet-core-uninstall list enumera los SDK y los entornos en tiempo de ejecución de .NET Core
instalados que se pueden quitar con esta herramienta. Visual Studio puede necesitar algunos SDK y entornos en
tiempo de ejecución, que se muestran con una nota de por qué no se recomienda desinstalarlos.
dotnet-core-uninstall list
Sinopsis
dotnet-core-uninstall list [options]

Opciones
Windows
macOS
--aspnet-runtime

Enumera todos los entornos en tiempo de ejecución de ASP.NET Core que se pueden desinstalar con esta
herramienta.
--hosting-bundle

Enumera todos los entornos en tiempo de ejecución de .NET Core y conjuntos de hospedaje que se pueden
desinstalar con esta herramienta.
--runtime

Enumera todos los entornos en tiempo de ejecución de .NET Core que se pueden desinstalar con esta
herramienta.
--sdk

Enumera todos los SDK de .NET Core que se pueden desinstalar con esta herramienta.
-v, --verbosity <LEVEL>

Establece el nivel de detalle. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] , d[etailed] y
diag[nostic] . El valor predeterminado es normal .

--x64

Enumera todos los SDK y entornos en tiempo de ejecución de .NET Core x64 que se pueden desinstalar
con esta herramienta.
--x86

Enumera todos los SDK y entornos en tiempo de ejecución de .NET Core x86 que se pueden desinstalar
con esta herramienta.
Ejemplos
Enumerar todos los SDK y entornos en tiempo de ejecución de .NET Core que se pueden quitar con esta
herramienta:

dotnet-core-uninstall list

Enumerar todos los SDK y entornos en tiempo de ejecución de .NET Core x64:

dotnet-core-uninstall list --x64

Enumerar todos los SDK de .NET Core x86:

dotnet-core-uninstall list --sdk --x86

Paso 2: Realizar un simulacro


Los comandos dotnet-core-uninstall dry-run y dotnet-core-uninstall whatif muestran los SDK y los entornos
en tiempo de ejecución de .NET Core que se quitarán en función de las opciones proporcionadas sin realizar la
desinstalación. Estos comandos son sinónimos.
dotnet-core-uninstall dry-run y dotnet-core-uninstall whatif
Sinopsis

dotnet-core-uninstall dry-run [options] [<VERSION>...]

dotnet-core-uninstall whatif [options] [<VERSION>...]

Argumentos
VERSION

La versión especificada que se va a desinstalar. Puede enumerar varias versiones una detrás de la otra,
separadas por espacios. También se admiten los archivos de respuesta.

TIP
Los archivos de respuesta son una alternativa a la colocación de todas las versiones en la línea de comandos. Son
archivos de texto, normalmente con una extensión *.rsp y cada versión aparece en una línea independiente. Para
especificar un archivo de respuesta para el argumento VERSION , use el carácter @ seguido inmediatamente del
nombre del archivo de respuesta.

Opciones
Windows
macOS
--all

Quita todos los SDK y entornos en tiempo de ejecución de .NET Core.


--all-below <VERSION>

Quita solo los SDK y los entornos en tiempo de ejecución de .NET Core que tienen una versión menor que
la versión especificada. La versión especificada permanece instalada.
--all-but <VERSIONS>

Quita todos los SDK y entornos en tiempo de ejecución de .NET Core, excepto las versiones especificadas.
--all-but-latest

Quita los SDK y los entornos en tiempo de ejecución de .NET Core, excepto la versión más alta.
--all-lower-patches

Quita los SDK y los entornos en tiempo de ejecución de .NET Core reemplazados por revisiones superiores.
Esta opción protege el archivo global.json.
--all-previews

Quita los SDK y los entornos en tiempo de ejecución de .NET Core marcados como versiones preliminares.
--all-previews-but-latest

Quita los SDK y los entornos en tiempo de ejecución de .NET Core marcados como versiones preliminares,
excepto la versión preliminar más alta.
--aspnet-runtime
Solo quita los entornos en tiempos de ejecución de ASP.NET Core.
--hosting-bundle

Quita el entorno en tiempo de ejecución de .NET Core y los conjuntos de hospedaje.


--major-minor <MAJOR_MINOR>

Quita los SDK y los entornos en tiempo de ejecución de .NET Core que coinciden con la versión
major.minor especificada.

--runtime

Solo quita los entornos en tiempo de ejecución de .NET Core.


--sdk

Solo quita los SDK de .NET Core.


-v, --verbosity <LEVEL>

Establece el nivel de detalle. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] , d[etailed] y
diag[nostic] . El valor predeterminado es normal .

--x64

Se debe usar con --sdk , --runtime y --aspnet-runtime para quitar los SDK o los entornos en tiempo de
ejecución x64.
--x86

Se debe usar con --sdk , --runtime y --aspnet-runtime para quitar los SDK o los entornos en tiempo de
ejecución x86.
--force Fuerza la eliminación de las versiones que Visual Studio puede usar.

Notas:
1. Se requiere exactamente uno de los valores --sdk , --runtime , --aspnet-runtime y --hosting-bundle .
2. --all , --all-below , --all-but , --all-but-latest , --all-lower-patches , --all-previews ,
--all-previews-but-latest , --major-minor y [<VERSION>...] son valores exclusivos.
3. Si no se especifica --x64 o --x86 , se quitarán tanto x64 como x86.
Ejemplos

NOTE
De forma predeterminada, los SDK y los entornos en tiempo de ejecución de .NET Core que puede necesitar Visual Studio u
otros SDK no se incluyen en la salida de dotnet-core-uninstall dry-run . En los siguientes ejemplos, es posible que
algunos de los SDK y entornos en tiempo de ejecución especificados no se incluyan en la salida, según el estado de la
máquina. Para incluir todos los SDK y entornos en tiempo de ejecución, agréguelos explícitamente como argumentos o use la
opción --force .

Realizar un simulacro de la eliminación de todos entornos en tiempo de ejecución de .NET Core que se han
reemplazado por revisiones superiores:

dotnet-core-uninstall dry-run --all-lower-patches --runtime

Realizar un simulacro de la eliminación de todos los SDK de .NET Core inferiores a la versión 2.2.301 :
dotnet-core-uninstall whatif --all-below 2.2.301 --sdk

Paso 3: Desinstalar los SDK y los entornos en tiempo de ejecución de .NET Core
dotnet-core-uninstall remove desinstala los SDK y los entornos en tiempo de ejecución de .NET Core
especificados por una colección de opciones. La herramienta no se puede usar para desinstalar los SDK y entornos
en tiempo de ejecución con la versión 5.0 o posterior.
Dado que esta herramienta tiene un comportamiento destructivo, es altamente recomendable que realice un
simulacro antes de ejecutar el comando remove. El simulacro le mostrará qué SDK y entornos en tiempo de
ejecución de .NET Core se quitarán cuando use el comando remove . Consulte ¿Puedo quitar una versión? para
saber qué SDK y entornos en tiempo de ejecución se pueden quitar de forma segura.
Cau t i on

Tenga en cuenta las siguientes advertencias:


Esta herramienta puede desinstalar las versiones del SDK de .NET Core que necesitan los archivos
global.json de la máquina. Puede volver a instalar los SDK de .NET Core desde la página Descarga de .NET
Core.
Esta herramienta puede desinstalar las versiones del entorno en tiempo de ejecución de .NET Core que
necesitan las aplicaciones que dependen del marco de trabajo de la máquina. Puede volver a instalar los
entornos en tiempo de ejecución de .NET Core desde la página Descarga de .NET Core.
Esta herramienta puede desinstalar las versiones del SDK y del entorno en tiempo de ejecución de .NET Core
en las que se basa Visual Studio. Si interrumpe la instalación de Visual Studio, ejecute "Reparar" en el
instalador de Visual Studio para volver a un estado de funcionamiento.
De forma predeterminada, todos los comandos mantienen los SDK y los entornos en tiempo de ejecución de .NET
Core que puede necesitar Visual Studio u otros SDK. Estos SDK y entornos en tiempos de ejecución se pueden
desinstalar si se enumeran explícitamente como argumentos o mediante la opción --force .
La herramienta requiere elevación para desinstalar los SDK y los entornos en tiempo de ejecución de .NET Core.
Ejecute la herramienta en un símbolo del sistema de administrador en Windows y con sudo en macOS. Los
comandos dry-run y whatif no requieren elevación.
dotnet-core-uninstall remove
Sinopsis

dotnet-core-uninstall remove [options] [<VERSION>...]

Argumentos
VERSION

La versión especificada que se va a desinstalar. Puede enumerar varias versiones una detrás de la otra,
separadas por espacios. También se admiten los archivos de respuesta.

TIP
Los archivos de respuesta son una alternativa a la colocación de todas las versiones en la línea de comandos. Son
archivos de texto, normalmente con una extensión *.rsp y cada versión aparece en una línea independiente. Para
especificar un archivo de respuesta para el argumento VERSION , use el carácter @ seguido inmediatamente del
nombre del archivo de respuesta.

Opciones
Windows
macOS
--all

Quita todos los SDK y entornos en tiempo de ejecución de .NET Core.


--all-below <VERSION>

Quita solo los SDK y los entornos en tiempo de ejecución de .NET Core que tienen una versión menor que
la versión especificada. La versión especificada permanece instalada.
--all-but <VERSIONS>

Quita todos los SDK y entornos en tiempo de ejecución de .NET Core, excepto las versiones especificadas.
--all-but-latest

Quita los SDK y los entornos en tiempo de ejecución de .NET Core, excepto la versión más alta.
--all-lower-patches

Quita los SDK y los entornos en tiempo de ejecución de .NET Core reemplazados por revisiones superiores.
Esta opción protege el archivo global.json.
--all-previews

Quita los SDK y los entornos en tiempo de ejecución de .NET Core marcados como versiones preliminares.
--all-previews-but-latest

Quita los SDK y los entornos en tiempo de ejecución de .NET Core marcados como versiones preliminares,
excepto la versión preliminar más alta.
--aspnet-runtime

Solo quita los entornos en tiempos de ejecución de ASP.NET Core.


--hosting-bundle

Quita el entorno en tiempo de ejecución de .NET Core y los conjuntos de hospedaje.


--major-minor <MAJOR_MINOR>

Quita los SDK y los entornos en tiempo de ejecución de .NET Core que coinciden con la versión
major.minor especificada.

--runtime

Solo quita los entornos en tiempo de ejecución de .NET Core.


--sdk

Solo quita los SDK de .NET Core.


-v, --verbosity <LEVEL>

Establece el nivel de detalle. Los valores permitidos son q[uiet] , m[inimal] , n[ormal] , d[etailed] y
diag[nostic] . El valor predeterminado es normal .

--x64

Se debe usar con --sdk , --runtime y --aspnet-runtime para quitar los SDK o los entornos en tiempo de
ejecución x64.
--x86

Se debe usar con --sdk , --runtime y --aspnet-runtime para quitar los SDK o los entornos en tiempo de
ejecución x86.
-y, --yes Ejecuta el comando sin requerir una confirmación sí o no.
--force Fuerza la eliminación de las versiones que Visual Studio puede usar.

Notas:
1. Se requiere exactamente uno de los valores --sdk , --runtime , --aspnet-runtime y --hosting-bundle .
2. --all , --all-below , --all-but , --all-but-latest , --all-lower-patches , --all-previews ,
--all-previews-but-latest , --major-minor y [<VERSION>...] son valores exclusivos.
3. Si no se especifica --x64 o --x86 , se quitarán tanto x64 como x86.
Ejemplos

NOTE
De forma predeterminada, los SDK y los entornos en tiempo de ejecución de .NET Core que puede necesitar Visual Studio u
otros SDK se mantienen. En los siguientes ejemplos, es posible que algunos de los SDK y entornos en tiempo de ejecución
especificados se mantengan, según el estado de la máquina. Para quitar todos los SDK y entornos en tiempo de ejecución,
agréguelos explícitamente como argumentos o use la opción --force .

Quitar todos los entornos en tiempo de ejecución de .NET Core excepto la versión 3.0.0-preview6-27804-01
sin necesidad de la confirmación S/N:

dotnet-core-uninstall remove --all-but 3.0.0-preview6-27804-01 --runtime --yes

Quitar todos los SDK de .NET Core 1.1 sin necesidad de la confirmación de S/N:

dotnet-core-uninstall remove --sdk --major-minor 1.1 -y

Quitar el SDK de .NET Core 1.1.11 sin salida de consola:

dotnet-core-uninstall remove 1.1.11 --sdk --yes --verbosity q

Quitar todos los SDK de .NET Core que se puedan quitar con seguridad con esta herramienta:

dotnet-core-uninstall remove --all --sdk

Quitar todos los SDK de .NET Core que puede quitar esta herramienta, incluidos los SDK que puede
necesitar Visual Studio (no recomendado):

dotnet-core-uninstall remove --all --sdk --force

Quitar todos los SDK de .NET Core que se especifican en el archivo de respuesta versions.rsp

dotnet-core-uninstall remove --sdk @versions.rsp

El contenido de versions.rsp es el siguiente:


2.2.300
2.1.700

Paso 4: Eliminar la carpeta de reserva de NuGet (opcional)


En algunos casos, ya no necesita NuGetFallbackFolder y puede que desee eliminarlo. Para más información sobre
cómo eliminar esta carpeta, consulte Quitar NuGetFallbackFolder.

Desinstalación de la herramienta.
Windows
macOS
1. Abra Agregar o quitar programas.
2. Busque Microsoft .NET Core SDK Uninstall Tool .
3. Seleccione Desinstalar.
Uso de la herramienta WCF Web Service Reference
Provider
12/01/2020 • 6 minutes to read • Edit Online

Durante años, muchos desarrolladores de Visual Studio han disfrutado de la productividad que ofrecía la
herramienta Agregar referencia de servicio cuando sus proyectos de .NET Framework necesitaban acceder a
servicios web. La herramienta WCF Web Service Reference Provider es una extensión de servicio conectada de
Visual Studio que proporciona una experiencia similar a la función Agregar referencia de servicio para proyectos
de .NET Core y ASP.NET Core. Esta herramienta recupera metadatos de un servicio web en la solución actual, en
una ubicación de red o desde un archivo WSDL, y genera un archivo de origen compatible con .NET Core. El
archivo contiene el código de proxy de cliente e Windows Communication Foundation (WCF ) y podrá usarlo para
acceder al servicio web.

IMPORTANT
Solo debe hacer referencia a servicios desde un origen de confianza. Si agrega referencias desde un origen que no es de
confianza podría poner en peligro la seguridad.

Requisitos previos
Visual Studio 2017, versión 15.5 o versiones posteriores

Cómo utilizar la extensión


NOTE
La opción WCF Web Service Reference (Referencia de servicio web de WCF) se puede aplicar a proyectos creados
mediante las siguientes plantillas de proyecto:
Visual C# > .NET Core
Visual C# > .NET Standard
Visual C# > Web > Aplicación web de ASP.NET Core

En este artículo se usa la plantilla de proyecto Aplicación web de ASP.NET Core para explicar cómo agregar
una referencia de servicio web de WCF al proyecto:
1. En el Explorador de soluciones, haga doble clic en el nodo Servicios conectados del proyecto (para un
proyecto de .NET Core o .NET Standard, esta opción está disponible cuando hace clic con el botón derecho
en el nodo Dependencias del proyecto en el Explorador de soluciones).
Aparece la página Servicios conectados, como se muestra en esta imagen:
2. En la página Servicios conectados, haga clic en Microsoft WCF Web Service Reference Provider. Se
abrirá el asistente para Configurar referencia de servicio web de WCF:

3. Seleccione un servicio.
3a. Hay varias opciones de búsqueda de servicios disponibles en el asistente para Configurar referencia
de servicio web de WCF:
Para buscar servicios definidos en la solución actual, haga clic en el botón Detectar.
Para buscar servicios hospedados en una dirección específica, escriba la dirección URL del servicio en el
cuadro Dirección y haga clic en el botón Ir.
Para seleccionar un archivo WSDL que contiene la información de metadatos del servicio web, haga clic
en el botón Examinar.
3b. Seleccione el servicio de la lista de resultados de búsqueda en el cuadro Servicios. Si es necesario,
escriba el espacio de nombres para el código generado en el cuadro de texto Espacio de nombres
correspondiente.
3c. Haga clic en el botón Siguiente para abrir las páginas Opciones de tipo de datos y Opciones de
cliente. O bien, haga clic en el botón Finalizar para usar las opciones predeterminadas.
4. El formulario Opciones de tipo de datos permite ajustar los valores de configuración de la referencia de
servicio generada:

NOTE
La opción de la casilla Reutilizar tipos en los ensamblados a los que se hace referencia es útil cuando se
definen los tipos de datos necesarios para la generación de código de referencia de servicio en uno de los
ensamblados de referencia del proyecto. Es importante volver a usar esos tipos de datos existentes para evitar
problemas de tiempo de ejecución o conflictos de tipo de tiempo de compilación.

Puede haber un retraso mientras se carga la información de tipo, en función del número de dependencias
del proyecto y otros factores de rendimiento del sistema. El botón Finalizar está deshabilitado durante la
carga, a menos que la casilla Reutilizar tipos en los ensamblados a los que se hace referencia esté
desactivada.
5. Haga clic en Finalizar cuando haya terminado.
Mientras muestra el progreso, la herramienta:
Descarga los metadatos del servicio WCF.
Genera el código de referencia de servicio en un archivo con el nombre reference.cs y lo agrega al proyecto
bajo el nodo Servicios conectados.
Actualiza el archivo de proyecto (.csproj) con las referencias del paquete NuGet necesarias para compilarlo y
ejecutarlo en la plataforma de destino.
Cuando se completan estos procesos, puede crear una instancia del tipo de cliente WCF generado e invocar las
operaciones del servicio.

Vea también
Introducción a las aplicaciones de Windows Communication Foundation
Servicios de Windows Communication Foundation y servicios de datos WCF en Visual Studio
Características compatibles con WCF en .NET Core

Preguntas y comentarios
Si tiene alguna pregunta o comentario, notifíquelo en la Comunidad de desarrolladores mediante la herramienta
Notificar un problema.

Notas de la versión
Eche un vistazo a las notas de la versión para obtener información actualizada sobre la versión, incluidos los
problemas conocidos.
Herramienta dotnet-svcutil de WCF para .NET Core
12/01/2020 • 6 minutes to read • Edit Online

La herramienta dotnet-svcutil de Windows Communication Foundation (WCF ) es una herramienta de la CLI de


.NET Core que recupera metadatos de un servicio web en una ubicación de red o de un archivo WSDL, y genera
una clase de WCF que contiene métodos de proxy de cliente que acceden a las operaciones del servicio web.
Similar a la herramienta Service Model Metadata - svcutil para proyectos de .NET Framework, dotnet-svcutil
es una herramienta de línea de comandos para generar una referencia de servicio web compatible con proyectos
de .NET Core y .NET Standard.
La herramienta dotnet-svcutil es una alternativa al proveedor de servicios conectados de Visual Studio WCF
Web Service Reference que se distribuyó por primera vez en la versión 15.5 de Visual Studio 2017. La
herramienta dotnet-svcutil, como herramienta de la CLI de .NET Core, está disponible en las distintas
plataformas de Linux, Mac OS y Windows.

IMPORTANT
Solo debe hacer referencia a servicios desde un origen de confianza. Si agrega referencias desde un origen que no es de
confianza podría poner en peligro la seguridad.

Requisitos previos
dotnet-svcutil 2.x
dotnet-svcutil 1.x
SDK de .NET Core 2.1 o versiones posteriores
Su editor de código favorito

Introducción
En el ejemplo siguiente se le guía por los pasos necesarios para agregar una referencia de servicio web a un
proyecto web de .NET Core e invocar el servicio. Creará una aplicación web de .NET Core denominada
HelloSvcutil y agregará una referencia a un servicio web que implementa el siguiente contrato:

[ServiceContract]
public interface ISayHello
{
[OperationContract]
string Hello(string name);
}

En este ejemplo, se da por hecho que el servicio web se hospedará en la siguiente dirección:
http://contoso.com/SayHello.svc

Desde una ventana de comandos de Windows, Mac OS o Linux, siga estos pasos:
1. Cree un directorio denominado HelloSvcutil para el proyecto y hágalo su directorio actual, como en el
ejemplo siguiente:
mkdir HelloSvcutil
cd HelloSvcutil

2. Cree un nuevo proyecto web de C# en ese directorio mediante el comando dotnet new del modo siguiente:

dotnet new web

3. Instale el paquete NuGet dotnet-svcutil como herramienta CLI:


dotnet-svcutil 2.x
dotnet-svcutil 1.x

dotnet tool install --global dotnet-svcutil

4. Ejecute el comando dotnet-svcutil para generar el archivo de referencia del servicio web de la siguiente
manera:
dotnet-svcutil 2.x
dotnet-svcutil 1.x

dotnet-svcutil http://contoso.com/SayHello.svc

El archivo generado se guarda como HelloSvcutil/ServiceReference1/Reference.cs. La herramienta dotnet_svcutil


también agrega al proyecto los paquetes de WCF adecuados que necesita el código de proxy como referencias del
paquete.

Uso de la referencia de servicio


1. Restaure los paquetes de WCF mediante el comando dotnet restore como sigue:

dotnet restore

2. Busque el nombre de la clase de cliente y la operación que quiera usar. Reference.cs contendrá una clase
que se hereda de System.ServiceModel.ClientBase , con métodos que pueden usarse para llamar a las
operaciones del servicio. En este ejemplo, quiere llamar a la operación Hello del servicio SayHello.
ServiceReference.SayHelloClient es el nombre de la clase de cliente, y tiene un método llamado HelloAsync
que se puede usar para llamar a la operación.
3. Abra el archivo Startup.cs en el editor y agregue una instrucción using al espacio de nombres de la
referencia de servicio en la parte superior:

using ServiceReference;

4. Edite el método Configure para invocar el servicio web. Para ello, cree una instancia de la clase que se
hereda de ClientBase y llame al método en el objeto de cliente:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.Run(async (context) =>


{
var client = new SayHelloClient();
var response = await client.HelloAsync();
await context.Response.WriteAsync(response);
});
}

5. Ejecute la aplicación con el comando dotnet run como sigue:

dotnet run

6. Vaya a la dirección URL indicada en la consola (por ejemplo, http://localhost:5000 ) en el explorador web.

Debería ver los siguientes resultados: "Hello dotnet-svcutil!"


Para obtener una descripción detallada de los parámetros de la herramienta dotnet-svcutil , invoque la
herramienta pasando el parámetro de ayuda del siguiente modo:
dotnet-svcutil 2.x
dotnet-svcutil 1.x

dotnet-svcutil --help

Preguntas y comentarios
Si tiene preguntas o comentarios, abra un problema en GitHub. También puede revisar las preguntas o problemas
que ya se han planteado en el repositorio de WCF en GitHub.

Notas de la versión
Eche un vistazo a las notas de la versión para obtener información actualizada sobre la versión, incluidos los
problemas conocidos.

Información
Paquete NuGet svcutil dotnet
Uso de dotnet-svcutil.xmlserializer en .NET Core
20/01/2020 • 3 minutes to read • Edit Online

El paquete NuGet dotnet-svcutil.xmlserializer puede generar previamente un ensamblado de serialización para


los proyectos de .NET Core. Genera previamente código de serialización de C# para los tipos de la aplicación
cliente que usa el contrato de servicio de WCF y que puede serializar XmlSerializer. Esto mejora el rendimiento de
inicio de la serialización de XML al serializar o deserializar objetos de esos tipos.

Requisitos previos
SDK de .NET Core 2.1 o versiones posteriores
Su editor de código favorito
Puede usar el comando dotnet --info para comprobar qué versiones del SDK de .NET Core y del Runtime ya ha
instalado.

Introducción
Para usar dotnet-svcutil.xmlserializer en una aplicación de consola de .NET Core:
1. Crea un servicio WCF denominado "MyWCFService" mediante la plantilla predeterminada "Aplicación del
servicio WCF" en .NET Framework. Agregue el atributo [XmlSerializerFormat] al método de servicio
similar al siguiente:

[ServiceContract]
public interface IService1
{
[XmlSerializerFormat]
[OperationContract(Action = "http://tempuri.org/IService1/GetData", ReplyAction =
"http://tempuri.org/IService1/GetDataResponse")]
string GetData(int value);
}

2. Cree una aplicación de consola de .NET Core como aplicación cliente de WCF que tenga como destino .NET
Core 2.1 o versiones posteriores. Por ejemplo, cree una aplicación denominada "MyWCFClient" con el
comando siguiente:

dotnet new console --name MyWCFClient

Para asegurarse de que el proyecto está destinado a .NET Core 2.1 o una versión posterior, inspeccione el
elemento XML TargetFramework del archivo de proyecto:

<TargetFramework>netcoreapp2.1</TargetFramework>

3. Ejecute el comando siguiente para agregar una referencia de paquete a System.ServiceModel.Http :

dotnet add package System.ServiceModel.Http

4. Agregue el código del cliente WCF:


using System.ServiceModel;

class Program
{
static void Main(string[] args)
{
var myBinding = new BasicHttpBinding();
var myEndpoint = new EndpointAddress("http://localhost:2561/Service1.svc"); //Fill your
service url here
var myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint);
IService1 client = myChannelFactory.CreateChannel();
string s = client.GetData(1);
((ICommunicationObject)client).Close();
}
}

[ServiceContract]
public interface IService1
{
[XmlSerializerFormat]
[OperationContract(Action = "http://tempuri.org/IService1/GetData", ReplyAction =
"http://tempuri.org/IService1/GetDataResponse")]
string GetData(int value);
}

5. Agregue una referencia al paquete dotnet-svcutil.xmlserializer mediante la ejecución del comando


siguiente:

dotnet add package dotnet-svcutil.xmlserializer

Al ejecutar el comando se debería agregar una entrada al archivo de proyecto similar a la siguiente:

<ItemGroup>
<DotNetCliToolReference Include="dotnet-svcutil.xmlserializer" Version="1.0.0" />
</ItemGroup>

6. Compile la aplicación ejecutando dotnet build . Si todo se realiza correctamente, se genera un ensamblado
denominado MyWCFClient.XmlSerializers.dll en la carpeta de salida. Si la herramienta no pudo generar el
ensamblado, verá advertencias en la salida de la compilación.
7. Inicie el servicio WCF, por ejemplo, mediante la ejecución de http://localhost:2561/Service1.svc en el
explorador. Después, inicie la aplicación cliente, que se cargará automáticamente y utilizará los serializadores
generados previamente en tiempo de ejecución.
Usar el generador de serializador XML de Microsoft
en .NET Core
20/01/2020 • 5 minutes to read • Edit Online

Este tutorial muestra cómo usar el generador de serializador XML de Microsoft en una aplicación .NET Core de
C#. Este tutorial ayuda a:
Cómo crear una aplicación .NET Core
Cómo agregar una referencia al paquete Microsoft.XmlSerializer.Generator
Cómo editar MyApp.csproj para agregar dependencias
Cómo agregar una clase y un XmlSerializer
Cómo compilar y ejecutar la aplicación
Tal y como sucede con el generador de serializador de XML (sgen.exe) para .NET Framework, el paquete
Microsoft.XmlSerializer.Generator de NuGet es el equivalente para proyectos de .NET Core y .NET Standard. Crea
un ensamblado de serialización de XML para los tipos contenidos en un ensamblado para mejorar el rendimiento
de inicio de la serialización XML al serializar o deserializar objetos de esos tipos con XmlSerializer.

Requisitos previos
Para realizar este tutorial:
SDK de .NET Core 2.1 o versiones posteriores.
Su editor de código favorito.

TIP
¿Es necesario instalar un editor de código? Pruebe Visual Studio.

Usar el generador de serializador de XML de Microsoft en una


aplicación de consola .NET Core
Las instrucciones siguientes muestran cómo usar el generador de serializador XML en una aplicación de consola
.NET Core.
Creación de una aplicación de consola .NET Core
Abra un símbolo del sistema y cree una carpeta denominada MyApp. Vaya a la carpeta que creó y escriba estos
comandos:

dotnet new console

Agregue una referencia al paquete Microsoft.XmlSerializer.Generator en el proyecto de MyApp


Use el comando dotnet add package para agregar la referencia en el proyecto.
Tipo:

dotnet add package Microsoft.XmlSerializer.Generator -v 1.0.0


Comprobar los cambios en MyApp.csproj después de agregar el paquete
Abra el editor de código para empezar. Todavía estamos trabajando desde el directorio MyApp en el que hemos
compilado la aplicación.
Abra MyApp.csproj en el editor de texto.
Después de ejecutar el comando dotnet add package , se agregan estas líneas al archivo de proyecto MyApp.csproj:

<ItemGroup>
<PackageReference Include="Microsoft.XmlSerializer.Generator" Version="1.0.0" />
</ItemGroup>

Agregar otra sección ItemGroup para admitir la herramienta CLI de .NET Core
Agregue estas líneas después de la sección ItemGroup que hemos inspeccionado:

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="1.0.0" />
</ItemGroup>

Agregar una clase en la aplicación


Abra Program.cs en el editor de texto. Agregue la clase con el nombre MyClass en Program.cs.

public class MyClass


{
public int Value;
}

Crear un XmlSerializer para MyClass


Agregue esta línea dentro de Main para crear un XmlSerializer para MyClass:

var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyClass));

Compilar y ejecutar la aplicación


Seguimos en la carpeta MyApp, desde donde vamos a ejecutar la aplicación a través de dotnet run . Se carga
automáticamente y usa los serializadores generados previamente en tiempo de ejecución.
Escriba el siguiente comando en la ventana de consola:

dotnet run

NOTE
dotnet run llama a dotnet build para asegurarse de que los destinos de la compilación se han creado y, después, llama
a dotnet <assembly.dll> para ejecutar la aplicación de destino.

IMPORTANT
Los comandos y los pasos que se muestran en este tutorial para ejecutar la aplicación se usan solo durante el desarrollo. Una
vez que esté listo para implementar la aplicación, eche un vistazo a las diferentes estrategias de implementación para
aplicaciones .NET Core y al comando dotnet publish .
Si todo se realiza correctamente, se genera un ensamblado con el nombre .dll MyApp.XmlSerializers.dll en la
carpeta de salida.
¡ Enhorabuena! Acaba de:

Crear una aplicación .NET Core.


Agregar una referencia al paquete Microsoft.XmlSerializer.Generator.
Editar MyApp.csproj para agregar dependencias.
Agregue una clase y un XmlSerializer.
Compilar y ejecutar la aplicación.

Recursos relacionados
Introducción a la serialización XML
Serialización con XmlSerializer (C#)
Cómo: Serializar con XmlSerializer (Visual Basic)
Introducción a la portabilidad de .NET Framework a
.NET Core
15/01/2020 • 4 minutes to read • Edit Online

Es posible que tenga código que se ejecuta actualmente en .NET Framework que le interesa portar a .NET Core.
En este artículo se proporciona:
Una introducción al proceso de portabilidad.
Una lista de las herramientas que puede encontrar de utilidad al portar el código a .NET Core.

Introducción al proceso de portabilidad


Le recomendamos que use el siguiente proceso al portar un proyecto a .NET Core:
1. Redirija todos los proyectos que quiere portar a .NET Framework 4.7.2 o versiones superiores.
Este paso garantiza que puede usar alternativas de API para destinos específicos de .NET Framework en los
casos donde .NET Core no admite una API determinada.
2. Use el Analizador de portabilidad de .NET para analizar los ensamblados y ver si se pueden portar a .NET
Core.
La herramienta Analizador de portabilidad de API analiza los ensamblados compilados y genera un
informe. Este informe muestra un resumen de portabilidad de alto nivel y un desglose de cada API que está
usando y que no está disponible en NET Core.
3. Instale el analizador de API de .NET en los proyectos para identificar las API que inician
PlatformNotSupportedException en algunas plataformas y otros posibles problemas de compatibilidad.
Esta herramienta es similar al analizador de portabilidad, pero en lugar de analizar si el código se pueden
basar en .NET Core, analiza si se usa una API de forma que se inicie PlatformNotSupportedException en
tiempo de ejecución. Aunque esto no es habitual si va a realizar la portabilidad desde .NET Framework
4.7.2 o superior, es conveniente comprobarlo. Para obtener más información sobre las API que generan
excepciones en .NET Core, consulte el artículo.
4. Convierta todas las dependencias de packages.config en el formato de PackageReference con la
herramienta de conversión en Visual Studio.
Este paso implica convertir las dependencias del formato packages.config heredado. packages.config no
funciona en .NET Core, por lo que esta conversión es necesaria si tiene dependencias de paquete.
5. Cree nuevos proyectos para .NET Core y copie en los archivos de código fuente, o intente convertir el
archivo de proyecto existente con una herramienta.
.NET Core usa un formato de archivo de proyecto simplificado y diferente al de .NET Framework. Deberá
convertir los archivos de proyecto en este formato para continuar.
6. Porte el código de prueba.
Dado que portar a .NET Core es un cambio considerable para el código base, se recomienda
encarecidamente portar las proyectos de prueba de forma que se puedan ejecutar mientras porta el código.
MSTest, xUnit y NUnit funcionan en .NET Core.
Además, puede intentar portar soluciones más pequeñas o proyectos individuales en una operación en el formato
de archivo de proyecto de .NET Core con la herramienta dotnet try-convert. No hay ninguna garantía de que
dotnet try-convert funcione con todos los proyectos y puede provocar cambios sutiles de comportamiento de los
que dependa. Use esta herramienta como punto inicial que automatice los elementos básicos que se pueden
automatizar. No es una solución garantizada para migrar un proyecto.

Pasos siguientes
Análisis de dependencias
Análisis de las dependencias para trasladar código a
.NET Core
20/01/2020 • 10 minutes to read • Edit Online

Para trasladar el código a .NET Core o .NET Standard, debe comprender las dependencias. Las dependencias
externas son los paquetes NuGet o archivos .dll a los que hace referencia en el proyecto, pero que no compila
por su cuenta.

Migración de los paquetes NuGet a PackageReference


.NET core usa PackageReference para especificar las dependencias del paquete. Si usa packages.config para
especificar los paquetes en el proyecto, debe convertirlo al formato PackageReference porque packages.config no
es compatible con .NET Core.
Para obtener información sobre cómo migrar, consulte el artículo Migración de packages.config a
PackageReference.

Actualización de los paquetes NuGet


Después de migrar el proyecto al formato PackageReference , compruebe si los paquetes son compatibles con
.NET Core.
En primer lugar, actualice los paquetes a la versión más reciente posible. Esto se puede realizar con la interfaz de
usuario del administrador de paquetes NuGet en Visual Studio. Es probable que las versiones más recientes de las
dependencias del paquete ya sean compatibles con .NET Core.

Análisis de las dependencias de paquetes


Si aún no se ha comprobado que las dependencias de paquetes convertidas y actualizadas funcionan en .NET
Core, hay varias formas de lograrlo:
Analizar los paquetes NuGet mediante nuget.org
En la sección Dependencias de la página de un paquete de nuget.org puede ver los moniker de la plataforma de
destino (TFM ) que admite cada paquete.
Aunque el uso del sitio es un método más sencillo para comprobar la compatibilidad, la información de las
Dependencias no está disponible en el sitio para todos los paquetes.
Analizar los paquetes NuGet con NuGet Package Explorer
Los paquetes NuGet son un conjunto de carpetas que contienen ensamblados específicos de plataforma,
Compruebe si hay una carpeta que contenga un ensamblado compatible dentro del paquete.
La manera más fácil de inspeccionar las carpetas de paquetes NuGet consiste en usar la herramienta NuGet
Package Explorer. Después de instalarla, siga estos pasos para ver los nombres de las carpetas:
1. Abra NuGet Package Explorer.
2. Haga clic en Open package from online feed (Abrir paquete desde fuente en línea).
3. Busque el nombre del paquete.
4. Seleccione el nombre del paquete en los resultados de la búsqueda y haga clic en Open (Abrir).
5. Expanda la carpeta lib de la derecha y examine los nombres de las carpetas.
Busque una carpeta con nombres que usen uno de los patrones siguientes: netstandardX.Y o netcoreappX.Y .
Estos valores son los monikers de la plataforma de destino (TFM ) que se asignan a las versiones de los perfiles de
.NET Standard, .NET Core y de la Biblioteca de clases portable (PCL ) tradicional compatibles con .NET Core.

IMPORTANT
Cuando examine los TFM compatibles con un paquete, tenga en cuenta que netcoreapp* , aunque sea compatible, es solo
para los proyectos de .NET Core, y no para los proyectos de .NET Standard. Las bibliotecas que solo tienen como destino
netcoreapp* (y no netstandard* ) solo las pueden consumir otras aplicaciones de .NET Core.

Modo de compatibilidad de .NET Framework


Después de analizar los paquetes NuGet, puede que observe que solo tienen como destino .NET Framework.
A partir de .NET Standard 2.0 se ha introducido el modo de compatibilidad de .NET Framework. Este modo de
compatibilidad permite que los proyectos de .NET Standard y .NET Core hagan referencia a bibliotecas de .NET
Framework. La acción de hacer referencias a bibliotecas de .NET Framework no funciona para todos los proyectos;
por ejemplo, si la biblioteca usa API de Windows Presentation Foundation (WPF ) pero desbloquea muchos
escenarios de portabilidad.
Al hacer referencia a paquetes NuGet que tienen como destino .NET Framework en el proyecto, como
Huitian.PowerCollections, recibirá una advertencia de reserva de paquete ( NU1701) parecida al ejemplo siguiente:
NU1701: Package ‘Huitian.PowerCollections 1.0.0’ was restored using ‘.NETFramework,Version=v4.6.1’ instead of
the project target framework ‘.NETStandard,Version=v2.0’. This package may not be fully compatible with your
project.

Esta advertencia se muestra cuando agrega el paquete y cada vez que compila para asegurarse de que prueba ese
paquete con el proyecto. Si el proyecto funciona según lo previsto, puede suprimir la advertencia editando las
propiedades del paquete en Visual Studio o editando manualmente el archivo del proyecto en su editor de código
favorito.
Para suprimir la advertencia editando el archivo del proyecto, busque la entrada PackageReference del paquete del
que quiere suprimir la advertencia y agregue el atributo NoWarn . El atributo NoWarn acepta una lista separada por
comas de todos los identificadores de advertencia. En el ejemplo siguiente se muestra cómo suprimir la
advertencia NU1701 del paquete Huitian.PowerCollections editando manualmente el archivo del proyecto:

<ItemGroup>
<PackageReference Include="Huitian.PowerCollections" Version="1.0.0" NoWarn="NU1701" />
</ItemGroup>

Para más información sobre cómo suprimir advertencias del compilador en Visual Studio, vea Supresión de las
advertencias para paquetes NuGet.

Qué hacer cuando su dependencia del paquete NuGet no se ejecuta


en .NET Core
Si un paquete NuGet del que depende no se ejecuta en .NET Core, puede hacer lo siguiente:
Si el proyecto es de código abierto y está hospedado en algún lugar como GitHub, puede implicar
directamente a los desarrolladores.
Puede ponerse en contacto directamente con el autor en nuget.org. Busque el paquete y haga clic en Contact
Owners (Póngase en contacto con los propietarios) a la izquierda de la página del paquete.
Puede buscar otro paquete que se ejecute en .NET Core que efectúe la misma tarea que el paquete que estaba
usando.
Puede intentar volver a escribir el código de lo que hacía el paquete usted mismo.
Puede eliminar la dependencia en el paquete mediante el cambio de la funcionalidad de la aplicación, al menos
hasta que esté disponible una versión compatible del paquete.
No olvide que los mantenedores de los proyectos de código abierto y los publicadores de paquetes NuGet suelen
ser voluntarios. Colaboran porque les importa un dominio determinado, lo hacen de forma gratuita y en muchas
ocasiones tienen otro trabajo, Sea consciente de ello al ponerse en contacto con ellos para solicitar soporte técnico
de .NET Core.
Si no puede resolver el problema con ninguna de estas opciones, puede que deba efectuar la portabilidad a .NET
Core en otro momento.
Al equipo de .NET le gustaría saber qué bibliotecas son las más importantes para que sean compatibles con .NET
Core. Puede enviar un correo electrónico a dotnet@microsoft.com indicando las bibliotecas que le gustaría usar.

Analizar dependencias que no son paquetes NuGet


Puede que tenga una dependencia que no sea un paquete NuGet, como un archivo DLL, en el sistema de archivos.
La única manera de determinar la portabilidad de esa dependencia consiste en ejecutar la herramienta .NET
Portability Analyzer. La herramienta analiza ensamblados que tienen como destino .NET Framework e identifica
API que no se pueden portar a otras plataformas de .NET, como .NET Core. Puede ejecutar la herramienta como
una aplicación de consola o como extensión de Visual Studio.

Pasos siguientes
Portabilidad de las bibliotecas
Traslado de bibliotecas de .NET Framework a .NET
Core
20/01/2020 • 14 minutes to read • Edit Online

Obtenga información sobre cómo trasladar el código de biblioteca de .NET Framework a .NET Core para ejecutar
como multiplataforma y ampliar el ámbito de las aplicaciones que lo usan.

Requisitos previos
En este artículo se asume lo siguiente:
Se usa Visual Studio 2017 o posterior. .NET Core no es compatible con versiones anteriores de Visual Studio.
Se conoce el proceso de portabilidad recomendado.
Se han resuelto los problemas con las dependencias de terceros.
También debe estar familiarizado con el contenido de los artículos siguientes:
Estándar .NET
En este artículo se describe la especificación formal de las API de .NET que se prevé que estén disponibles en
todas las implementaciones de .NET.
Paquetes, metapaquetes y marcos de trabajo
En este artículo se trata cómo .NET Core define y usa paquetes y cómo los paquetes admiten el código que se
ejecuta en varias implementaciones de .NET.
Desarrollo de bibliotecas con herramientas multiplataforma
En este artículo se explica cómo escribir bibliotecas para .NET mediante el uso de herramientas multiplataforma de
la CLI.
Adiciones al formato csproj para .NET Core
En este artículo se describen los cambios que se han agregado al archivo de proyecto como parte del cambio a
csproj y MSBuild.
Migración a .NET Core - Análisis de las dependencias de terceros
En este artículo se trata la portabilidad de dependencias de terceros y qué hacer cuando una dependencia de
paquetes de NuGet no se ejecuta en .NET Core.

Redestinar a .NET Framework 4.7.2


Si el código no apunta a .NET Framework 4.7.2, se recomienda que lo redestine a esta plataforma. De esta forma,
se garantiza la disponibilidad de las últimas alternativas de API en los casos donde el estándar .NET no admite las
API existentes.
Haga lo siguiente para cada uno de los proyectos de Visual Studio que desea trasladar:
1. Haga clic con el botón derecho en el proyecto y seleccione Propiedades.
2. En la lista desplegable Plataforma de destino, seleccione .NET Framework 4.7.2.
3. Compile de nuevo el proyecto.
Debido a que sus proyectos ahora apuntan a .NET Framework 4.7.2, use esa versión de .NET Framework como la
base para portar el código.
Determinar la portabilidad
El paso siguiente es ejecutar API Portability Analyzer (ApiPort), a fin de generar un informe de portabilidad para
analizarlo.
Asegúrese de que comprende la herramienta API Portability (ApiPort) y de que puede generar informes de
portabilidad que apunten a .NET Core. La forma de hacer esto posiblemente variará en función de sus necesidades
y de sus preferencias personales. En las secciones siguientes se detallan algunos enfoques diferentes. Es probable
que tenga que combinar los pasos de estos enfoques en función de cómo esté estructurado el código.
Trabajar primero con el compilador
Este enfoque funciona bien con proyectos pequeños o proyectos que no usan muchas API de .NET Framework. El
enfoque es sencillo:
1. De manera opcional, ejecute ApiPort en el proyecto. Si ejecuta ApiPort, consulte el informe para obtener
información sobre los problemas que encontrará.
2. Copie todo el código a un nuevo proyecto de .NET Core.
3. Mientras consulta el informe de portabilidad (en caso de que se haya generado), solucione los errores del
compilador hasta que el proyecto esté totalmente compilado.
Aunque no está estructurado, este enfoque centrado en el código suele resolver problemas rápidamente. Un
proyecto que solo contiene modelos de datos puede ser un candidato ideal para este enfoque.
Permanecer en .NET Framework hasta solucionar los problemas de portabilidad
Este puede ser el mejor enfoque si prefiere que el código se compile durante todo el proceso. El enfoque es el
siguiente:
1. Ejecute ApiPort en un proyecto.
2. Use distintas API portátiles para solucionar los problemas.
3. Anote todas las áreas en las que no se permite usar una alternativa directa.
4. Repita los pasos anteriores para todos los proyectos que desea trasladar hasta tener la seguridad de haber
copiado cada uno de ellos a un proyecto nuevo de .NET Core.
5. Copie el código a un nuevo proyecto de .NET Core.
6. Solucione todos los problemas en los que se indica que no existe una alternativa directa.
Este enfoque prudente es más estructurado que simplemente solucionar los errores del compilador, pero de todos
modos está relativamente centrado en el código y tiene la ventaja de que siempre hay código que se puede
compilar. La manera en que puede solucionar ciertos problemas que no se podrían solucionar si solo se usa otra
API varía considerablemente. Es posible que deba desarrollar un plan más integral para ciertos proyectos, un
aspecto que se abarca en el enfoque siguiente.
Desarrollar un plan integral de ataque
Este puede ser el mejor enfoque para proyectos de mayor tamaño y más complejos, en los que puede ser
necesario volver a estructurar el código o reescribir ciertas áreas de código por completo para admitir .NET Core.
El enfoque es el siguiente:
1. Ejecute ApiPort en un proyecto.
2. Observe dónde se usa cada tipo no portátil y cómo ese uso afecta a la portabilidad general.
Comprenda la naturaleza de esos tipos. ¿Son pocos, pero se usan con frecuencia? ¿Son muchos, pero no
se usan con frecuencia? ¿Se usan de manera concentrada o se distribuyen en todo el código?
¿Es simple aislar código no portátil para poder trabajar con él con más eficacia?
¿Es necesario refactorizar el código?
En el caso de los tipos no portátiles, ¿existen API alternativas que permitan realizar la misma tarea? Por
ejemplo, si usa la clase WebClient, es posible que, en lugar de esta, pueda usar la clase HttpClient.
¿Hay API portátiles distintas disponibles para realizar una tarea, incluso si no se trata de un reemplazo?
Por ejemplo, si usa XmlSchema para analizar un archivo XML, pero no necesita la detección de
esquemas XML, puede usar las API System.Xml.Linq e implementar el análisis por su cuenta en lugar de
depender de una API.
3. Si tiene ensamblados difíciles de trasladar, ¿debe pensarse en dejarlos en .NET Framework por ahora? Algunos
aspectos que debe considerar:
Puede que en la biblioteca tenga alguna funcionalidad no compatible con .NET Core, porque depende
demasiado de la funcionalidad específica de Windows o específica de .NET Framework. ¿Debe
considerarse la posibilidad de dejar atrás esa funcionalidad por ahora y lanzar una versión temporal para
.NET Core de la biblioteca con menos características, hasta que haya recursos disponibles para portar las
características?
¿Sería útil una refactorización en este caso?
4. ¿Es razonable escribir su propia implementación de una API de .NET Framework no disponible? Podría
considerar copiar, modificar y usar código del código fuente de referencia de .NET Framework. El código fuente
de referencia está sujeto a la licencia de MIT, por lo que tiene plena libertad para usar la fuente como base para
su propio código. Solo debe asegurarse de atribuir adecuadamente la propiedad de Microsoft en el código.
5. Repita este proceso las veces que sea necesario para proyectos distintos.
La fase de análisis puede tardar un poco en función del tamaño de la base de código. Dedicar tiempo en esta fase a
comprender profundamente el ámbito de los cambios que se necesitan y para desarrollar un plan suele ahorrarle
tiempo a largo plazo, principalmente si tiene una base de código compleja.
El plan podría significar realizar cambios importantes en la base de código mientras se sigue apuntando a .NET
Framework 4.7.2, lo que hace que esta sea una versión más estructurada del enfoque anterior. La forma de ejecutar
el plan depende de la base de código.
Enfoque mixto
Es probable que vaya a combinar los enfoques anteriores en función de cada proyecto. Debe hacer lo que
corresponda para usted y su base de código.

Portar las pruebas


La mejor forma de asegurarse de que todo funciona correctamente cuando traslada el código es probarlo mientras
lo traslada a .NET Core. Para ello, debe usar un marco de pruebas que compila y ejecuta pruebas para .NET Core.
Actualmente tiene 3 opciones:
xUnit
Introducción
Herramienta para convertir un proyecto MSTest en xUnit
NUnit
Introducción
Entrada de blog sobre la migración de MSTest a NUnit.
MSTest

Enfoque recomendado
En última instancia, el esfuerzo de portabilidad depende significativamente de la estructura del código .NET
Framework. Una forma conveniente de portar el código consiste en comenzar por la base de la biblioteca, que son
los componentes fundamentales del código. Pueden ser los modelos de datos u otras clases y métodos
fundamentales que todo lo demás usa directa o indirectamente.
1. Porte el proyecto de prueba que comprueba el nivel de la biblioteca cuya portabilidad se está realizando
actualmente.
2. Copie la base de la biblioteca en un nuevo proyecto .NET Core y seleccione la versión del estándar .NET que
desea admitir.
3. Haga los cambios necesarios para la compilación del código. Muchas de estas acciones pueden requerir
agregar dependencias del paquete NuGet al archivo csproj.
4. Ejecute las pruebas y haga los ajustes que sean necesarios.
5. Elija el nivel de código siguiente que se va a portar y repita los pasos anteriores.
Si empieza por la base de la biblioteca y avanza a partir de ella para probar cada nivel según sea necesario, la
portabilidad es un proceso sistemático en el que se aíslan los problemas a un nivel de código a la vez.

Pasos siguientes
Organización de proyectos para .NET Core
Organización del proyecto para admitir .NET
Framework y .NET Core
20/01/2020 • 4 minutes to read • Edit Online

Puede crear una solución que se compila para .NET Framework y .NET Core en paralelo. En este artículo se tratan
varias opciones de organización del proyecto para ayudarlo a lograr este objetivo. Los siguientes son algunos
escenarios típicos que debe considerar cuando decida cómo va a configurar el diseño del proyecto con .NET Core.
Es posible que la lista no abarque todos los aspectos que quiere, pero debe darles prioridad en función de las
necesidades del proyecto.
Combinar los proyectos existentes y los proyectos de .NET Core en proyectos únicos
Para qué se usa:
Simplifica el proceso de compilación mediante la compilación de un proyecto único en lugar de varios
proyectos, donde cada uno de ellos tiene como destino una plataforma o versión distinta de .NET
Framework.
Simplifica la administración de archivos de origen en proyectos con compatibilidad con múltiples
versiones, porque debe administrar un solo archivo de proyecto. Cuando agrega o quita archivos de
origen, las alternativas requieren que los sincronice manualmente con los otros proyectos.
Para generar fácilmente un paquete NuGet para consumo.
Le permite escribir código para una versión específica de .NET Framework en las bibliotecas a través del
uso de directivas de compilador.
Escenarios no admitidos:
Se necesita que los desarrolladores que usan Visual Studio 2017 abran los proyectos existentes. Para
admitir versiones anteriores de Visual Studio, una opción mejor es mantener los archivos de proyecto en
distintas carpetas.
Mantener separados los proyectos existentes y los proyectos de .NET Core nuevos
Para qué se usa:
Compatibilidad de desarrollo en proyectos existentes para desarrolladores y colaboradores que podrían
no tener Visual Studio 2017 o una versión posterior.
Para disminuir la posibilidad de generar nuevos errores en proyectos existentes porque esos proyectos
no requieren renovación de código.

Ejemplo
Considere el siguiente repositorio:
Código fuente
A continuación se describen varias formas de agregar compatibilidad para .NET Core para este repositorio en
función de las restricciones y la complejidad de los proyectos existentes.

Reemplazo de proyectos existentes por un proyecto .NET Core con


compatibilidad con múltiples versiones
Reorganice el repositorio de manera que se quite cualquier archivo *.csproj existente y se cree un archivo *.csproj
único que establezca varios marcos de trabajo como destino. Esta es una opción excelente, porque un proyecto
único se puede compilar para distintos marcos de trabajo. También tiene la capacidad de controlar distintas
dependencias y opciones de compilación por cada marco de trabajo de destino.

Código fuente
Los cambios que debe tener en cuenta son los siguientes:
Se reemplazan packages.config y *.csproj con un nuevo archivo *.csproj de .NET Core. Los paquetes NuGet se
especifican con <PackageReference> ItemGroup .

Mantenimiento de los proyectos existentes y creación de un proyecto


.NET Core
Si hay proyectos existentes que tienen como destino marcos de trabajo anteriores, puede que desee dejarlos
intactos y usar un proyecto .NET Core para establecer como destino marcos de trabajo futuros.

Código fuente
.NET Core y los proyectos existentes se mantienen en carpetas independientes. Mantener los proyectos en
carpetas independientes evita que sea necesario tener Visual Studio 2017 o versiones posteriores. Puede crear una
solución independiente que solo abra los proyectos anteriores.

Vea también
Documentación sobre la portabilidad a .NET Core
Tecnologías de .NET Framework no disponibles en
.NET Core
20/01/2020 • 6 minutes to read • Edit Online

Varias tecnologías disponibles para las bibliotecas de .NET Framework no están disponibles para su uso con .NET
Core, por ejemplo, dominios de aplicaciones, comunicación remota, seguridad de acceso del código (CAS ),
transparencia de seguridad y System.EnterpriseServices. Si las bibliotecas se basan en una o varias de estas
tecnologías, considere los enfoques alternativos que se describen a continuación. Para obtener más información
sobre la compatibilidad de API, consulte Cambios importantes en .NET Core.
El hecho de que una API o tecnología no estén implementadas actualmente no implica que sea incompatible
deliberadamente. Busque los repositorios de GitHub para .NET Core para ver si un problema particular que
encuentre se debe al diseño. Si no encuentra dicho indicador, registre un problema en el repositorio dotnet/runtime
para solicitar API y tecnologías específicas. Los problemas que migran solicitudes se marcan con la etiqueta port-
to-core.

Dominios de aplicaciones
Los dominios de aplicación aíslan las aplicaciones entre sí. Los dominios de aplicación requieren la compatibilidad
con el runtime y suelen ser muy caros. No se admite la creación de dominios de aplicación adicionales y no existen
planes para agregar esta funcionalidad en el futuro. En el caso del aislamiento del código, use contenedores o
procesos independientes como alternativa. Para cargar ensamblados de forma dinámica, use la clase
AssemblyLoadContext.
Para facilitar la migración de código de .NET Framework, .NET Core expone algunas de las superficies de la API
AppDomain. Algunas de las API funcionan con normalidad (por ejemplo, AppDomain.UnhandledException),
algunos miembros no hacen nada (por ejemplo, SetCachePath) y algunos de ellos generan
PlatformNotSupportedException (por ejemplo, CreateDomain). Compruebe los tipos que usa con el
System.AppDomain origen de referencia en el repositorio de GitHub dotnet/runtime. Asegúrese de seleccionar la
rama que coincida con su versión implementada.

Comunicación remota
La comunicación remota de .NET se identificó como una arquitectura problemática. Se usa para la comunicación
entre dominios de aplicaciones, una funcionalidad que ya no es compatible. Además, la comunicación remota
requiere la compatibilidad con el runtime, cuyo mantenimiento resulta caro. Por estos motivos, la comunicación
remota de .NET no es compatible con .NET Core y no se prevé agregar esta compatibilidad en el futuro.
Para la comunicación entre procesos, considere la posibilidad de usar mecanismos de comunicación entre procesos
(IPC ) como alternativa a la comunicación remota, como las clases System.IO.Pipes o MemoryMappedFile.
En los equipos, utilice una solución basada en red como una alternativa. Si es posible, use un protocolo de texto sin
formato con poca sobrecarga, como HTTP. El servidor web Kestrel, el servidor web que usa ASP.NET Core, se
puede usar como opción aquí. También considere el uso de System.Net.Sockets para escenarios de conexión entre
equipos basada en red. Para obtener más opciones, vea .NET Open Source Developer Projects: Messaging
(Proyectos de desarrolladores de código abierto de .NET: mensajería).

Seguridad de acceso del código (CAS)


El espacio aislado, que se basa en el runtime o en el marco para restringir qué recursos usa o ejecuta una aplicación
administrada, no es compatible con .NET Framework y, por tanto, tampoco se admite en .NET Core. Hay
demasiados casos en .NET Framework y en el runtime en los que se produce una elevación de privilegios para
continuar tratando la seguridad de acceso al código (CAS ) como un límite de seguridad. Además, la seguridad de
acceso del código dificulta más la implementación y suele tener implicaciones en el rendimiento de corrección para
las aplicaciones que no pretenden usar esta funcionalidad.
Use los límites de seguridad que proporciona el sistema operativo, como la virtualización, los contenedores o las
cuentas de usuario para ejecutar procesos con el menor conjunto de privilegios.

Transparencia de seguridad
De forma similar a lo que ocurre con la seguridad de acceso al código, la transparencia de seguridad separa el
código de espacios aislados del código crítico de seguridad de manera declarativa, pero ya no se admite como un
límite de seguridad. Silverlight usa mucho esta característica.
Use los límites de seguridad que proporciona el sistema operativo, como la virtualización, los contenedores o las
cuentas de usuario para ejecutar procesos con el menor conjunto de privilegios.

System.EnterpriseServices
System.EnterpriseServices (COM+) no es compatible con .NET Core.

Pasos siguientes
Análisis de dependencias
Herramientas útiles para la portabilidad a .NET Core
20/01/2020 • 2 minutes to read • Edit Online

Las herramientas enumeradas en este artículo pueden ser útiles cuando realice la portabilidad:
Analizador de portabilidad de .NET: una cadena de herramientas que puede generar un informe de portabilidad
del código entre .NET Framework y .NET Core:
Como una herramienta de línea de comandos
Como una extensión de Visual Studio
Analizador de API en .NET: un analizador de Roslyn que detecta posibles riesgos de compatibilidad de las API
de C# en distintas plataformas y detecta llamadas a API en desuso.
Además, puede intentar portar soluciones más pequeñas o proyectos individuales en el formato de archivo de
proyecto de .NET Core con la herramienta CsprojToVs2017.

WARNING
CsprojToVs2017 es una herramienta de terceros. No hay ninguna garantía de que funcione con todos los proyectos, y podría
provocar cambios sutiles de comportamiento de los que dependa. CsprojToVs2017 debe usarse como punto de partida que
automatiza los elementos básicos que se pueden automatizar. No es una solución que se garantice para migrar formatos de
archivo de proyecto.
Uso del paquete de compatibilidad de Windows
para trasladar código a .NET Core
20/01/2020 • 4 minutes to read • Edit Online

Algunos de los problemas más comunes que se encuentran al trasladar código existente a .NET Core son las
dependencias con API y las tecnologías que solo se encuentran en .NET Framework. El paquete de
compatibilidad de Windows proporciona muchas de estas tecnologías, por lo que es mucho más fácil crear
aplicaciones de .NET Core y bibliotecas de .NET Standard.
Este paquete es una extensión lógica de .NET Standard 2.0 que aumenta considerablemente las compilaciones del
conjunto de API y el código existente prácticamente sin modificaciones. Con el fin de mantener la promesa de
.NET Standard ("es el conjunto de API que proporcionan todas las implementaciones de .NET"), el paquete no
incluye tecnologías que no puedan funcionar en todas las plataformas, como el Registro, Windows Management
Instrumentation (WMI) o las API de emisión de la reflexión.
El paquete de compatibilidad de Windows está un nivel por encima de .NET Standard y proporciona acceso a
tecnologías que solo son de Windows. Es especialmente útil para los clientes que quieren migrar a .NET Core
pero piensan permanecer en Windows como primer paso. En ese escenario, la imposibilidad de usar tecnologías
solo de Windows es únicamente un escollo para la migración sin ninguna ventaja arquitectónica.

Contenido del paquete


El paquete de compatibilidad de Windows se proporciona mediante el paquete NuGet
Microsoft.Windows.Compatibility y se puede hacer referencia a él desde proyectos para .NET Core o .NET
Standard.
Proporciona unas 20.000 API, incluidas API solo de Windows y API de varias plataformas de las siguientes áreas
tecnológicas:
Páginas de códigos
CodeDom
Configuración
Servicios de directorio
Dibujo
ODBC
Permisos
Puertos
Listas de control de acceso (ACL ) de Windows
Windows Communication Foundation (WCF )
Criptografía de Windows
Registro de eventos de Windows
Instrumental de administración de Windows (WMI)
Contadores de rendimiento de Windows
Registro de Windows
Memoria caché de tiempo de ejecución de Windows
servicios de Windows
Para más información, vea las especificaciones del paquete de compatibilidad.
Primeros pasos
1. Antes de migrar, asegúrese de echar un vistazo al proceso de migración.
2. Al migrar código existente a .NET Core o .NET Standard, instale el paquete NuGet
Microsoft.Windows.Compatibility.
Si quiere permanecer en Windows, ya está listo.
3. Si quiere ejecutar la aplicación .NET Core o la biblioteca de .NET Standard en Linux o macOS, use el
analizador de API para informarse de qué API no funcionan en varias plataformas.
4. Quite esas API, reemplácelas con alternativas multiplataforma o restrínjalas con una comprobación de
plataforma, como:

private static string GetLoggingPath()


{
// Verify the code is running on Windows.
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam\AssetManagement"))
{
if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
return configuredPath;
}
}

// This is either not running on Windows or no logging path was configured,


// so just use the path for non-roaming user-specific data files.
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(appDataPath, "Fabrikam", "AssetManagement", "Logging");
}

Para ver una demostración, vaya al vídeo de Channel 9 sobre el paquete de compatibilidad de Windows.
Procedimiento para: Migrar una aplicación de
escritorio de Windows Forms a .NET Core
03/12/2019 • 17 minutes to read • Edit Online

En este artículo se explica cómo migrar una aplicación de escritorio basada en Windows Forms de .NET
Framework a .NET Core 3.0 o una versión posterior. El SDK de .NET Core 3.0 incluye compatibilidad para las
aplicaciones de Windows Forms. Windows Forms sigue siendo un marco de solo Windows y solo se ejecuta en
Windows. En este ejemplo se usa la CLI del SDK de .NET Core para crear y administrar un proyecto.
En este artículo, se usan diferentes nombres para identificar los tipos de archivos que se utilizan para la migración.
Al migrar su proyecto, sus archivos se nombrarán de manera diferente, así que establezca una relación mental con
los que se enumeran a continuación:

ARCHIVO DESCRIPCIÓN

MyApps.sln Nombre del archivo de la solución.

MyForms.csproj Nombre del proyecto de Windows Forms de .NET Framework


para migrar.

MyFormsCore.csproj Nombre del nuevo proyecto de .NET Core que crea.

MyAppCore.exe Ejecutable de la aplicación de Windows Forms de .NET Core.

Requisitos previos
Visual Studio 2019 para cualquier trabajo de diseñador que desee hacer.
Instale las cargas de trabajo de Visual Studio siguientes:
Desarrollo de escritorio de .NET
Desarrollo multiplataforma de .NET Core
Un proyecto de Windows Forms en funcionamiento en una solución que se construye y ejecuta sin
problemas.
Un proyecto codificado en C#.
.NET Core 3.0 o una versión posterior.

NOTE
Visual Studio 2017 no es compatible con proyectos de .NET Core 3.0. Visual Studio 2019 admite proyectos de
.NET Core 3.0, pero todavía no admite el diseñador visual para los proyectos de Windows Forms de .NET Core 3.0. Para usar
el diseñador visual, debe tener un proyecto de Windows Forms de .NET en una solución que comparta los archivos de
formularios con el proyecto de .NET Core.

Tenga en cuenta que:


Al migrar una aplicación de Windows Forms de .NET Framework, hay algunas cosas que debe tener en cuenta.
1. Compruebe que la aplicación cumple los requisitos para la migración.
Use el analizador de portabilidad de .NET para determinar si el proyecto se migrará a .NET Core 3.0. Si el
proyecto tiene problemas con .NET Core 3.0, el analizador le ayuda a identificar esos problemas.
2. Está usando una versión diferente de Windows Forms.
Cuando se publicó .NET Core 3.0 (versión preliminar 1), Windows Forms se puso a disposición de los
usuarios en código abierto en GitHub. El código para Windows Forms de .NET Core es una bifurcación del
código base de Windows Forms de .NET Framework. Es posible que existan algunas diferencias y la
aplicación no se migre.
3. El paquete de compatibilidad de Windows puede ayudarle con la migración.
Algunas API que están disponibles en .NET Framework no están disponibles en .NET Core 3.0. El paquete
de compatibilidad de Windows agrega muchas de estas API y puede ayudar a que su aplicación de
Windows Forms sea compatible con .NET Core.
4. Actualice los paquetes de NuGet utilizados por el proyecto.
Siempre se recomienda usar las últimas versiones de los paquetes de NuGet antes de cualquier migración.
Si la aplicación hace referencia a cualquier paquete de NuGet, actualícelo a la versión más reciente.
Asegúrese de que la aplicación se compila correctamente. Tras la actualización, si se han producido errores
en el paquete, cambie el paquete a la versión más reciente que no rompa el código.
5. Visual Studio 2019 aún no admite el Diseñador de Forms para .NET Core 3.0
Actualmente, debe mantener el archivo de proyecto de Windows Forms de .NET Framework existente si
desea utilizar el Diseñador de Forms de Visual Studio.

Creación de un nuevo proyecto de SDK


El nuevo proyecto .NET Core 3.0 que cree debe estar en un directorio diferente de su proyecto de .NET
Framework. Si ambos están en el mismo directorio, es posible que tenga conflictos con los archivos que se
generan en el directorio obj. En este ejemplo, vamos a crear un directorio denominado MyFormsAppCore en el
directorio SolutionFolder:

SolutionFolder
├───MyApps.sln
├───MyFormsApp
│ └───MyForms.csproj
└───MyFormsAppCore <--- New folder for core project

A continuación, deberá crear el proyecto MyFormsCore.csproj en el directorio MyFormsAppCore. Puede crear


este archivo manualmente utilizando el editor de texto que prefiera. Pegue el siguiente XML:

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

</Project>

Si no desea crear manualmente el archivo de proyecto, puede usar Visual Studio o el SDK de .NET Core para
generar el proyecto. Sin embargo, debe eliminar todos los demás archivos generados por la plantilla de proyecto,
excepto el archivo de proyecto. Para usar el SDK, ejecute el siguiente comando desde el directorio
SolutionFolder:
dotnet new winforms -o MyFormsAppCore -n MyFormsCore

Después de crear MyFormsCore.csproj, la estructura de directorios debe ser similar a la siguiente:

SolutionFolder
├───MyApps.sln
├───MyFormsApp
│ └───MyForms.csproj
└───MyFormsAppCore
└───MyFormsCore.csproj

Tendrá que agregar el proyecto MyFormsCore.csproj a MyApps.sln con Visual Studio o la CLI de .NET Core
desde el directorio SolutionFolder:

dotnet sln add .\MyFormsAppCore\MyFormsCore.csproj

Corrección de la generación de información de ensamblado


Los proyectos de Windows Forms que se crearon con .NET Framework incluyen un archivo AssemblyInfo.cs , que
contiene los atributos de ensamblado, como la versión del ensamblado que se generará. Los proyectos de estilo
SDK generan automáticamente esta información basándose en el archivo de proyecto de SDK. Tener ambos tipos
de "información de ensamblado" crea un conflicto. Resuelva este problema deshabilitando la generación
automática, lo que obliga al proyecto a usar su archivo AssemblyInfo.cs existente.
Hay tres opciones para agregar al nodo <PropertyGroup> principal.
GenerateAssemblyInfo
Al establecer esta propiedad en false , no se generan los atributos del ensamblado. Esto evita el conflicto
con el archivo AssemblyInfo.cs existente en el proyecto de .NET Framework.
AssemblyName
El valor de esta propiedad es el binario de salida que se crea al compilar. El nombre no necesita una
extensión agregada. Por ejemplo, el uso de MyCoreApp genera MyCoreApp.exe .
RootNamespace
El espacio de nombres predeterminado que utiliza el proyecto. Debe coincidir con el espacio de nombres
predeterminado del proyecto de .NET Framework.
Agregue estos tres elementos al nodo <PropertyGroup> en el archivo MyFormsCore.csproj :

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>MyCoreApp</AssemblyName>
<RootNamespace>WindowsFormsApp1</RootNamespace>
</PropertyGroup>

</Project>
Adición de código fuente
Ahora, el proyecto MyFormsCore.csproj no compila ningún código. De forma predeterminada, los proyectos de
.NET Core incluyen automáticamente todo el código fuente en el directorio actual y los directorios secundarios.
Debe configurar el proyecto para incluir código del proyecto de .NET Framework con una ruta de acceso relativa.
Si el proyecto de .NET Framework usa archivos .resx para los iconos y los recursos de los formularios, deberá
incluirlos también.
Agregue el siguiente nodo <ItemGroup> al proyecto. Cada instrucción incluye un patrón global de archivo que
incluye los directorios secundarios.

<ItemGroup>
<Compile Include="..\MyFormsApp\**\*.cs" />
<EmbeddedResource Include="..\MyFormsApp\**\*.resx" />
</ItemGroup>

Como alternativa, puede crear una entrada <Compile> o <EmbeddedResource> para cada archivo en el proyecto de
.NET Framework.

Adición de paquetes NuGet


Agregue cada paquete NuGet al que hace referencia el proyecto de .NET Framework al proyecto de .NET Core.
Lo más probable es que su aplicación de Windows Forms de .NET Framework tenga un archivo packages.config
que contenga una lista de todos los paquetes de NuGet a los que hace referencia su proyecto. Puede buscar en
esta lista para determinar qué paquetes de NuGet se agregarán al proyecto de .NET Core. Por ejemplo, si el
proyecto de .NET Framework hizo referencia a los paquetes de NuGet MetroFramework , MetroFramework.Design y
MetroFramework.Fonts , agregue cada uno al proyecto con Visual Studio o la CLI de .NET Core del directorio
SolutionFolder:

dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework


dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework.Design
dotnet add .\MyFormsAppCore\MyFormsCore.csproj package MetroFramework.Fonts

Los comandos anteriores podrían agregar las siguientes referencias de NuGet al proyecto MyFormsCore.csproj:

<ItemGroup>
<PackageReference Include="MetroFramework" Version="1.2.0.3" />
<PackageReference Include="MetroFramework.Design" Version="1.2.0.3" />
<PackageReference Include="MetroFramework.Fonts" Version="1.2.0.3" />
</ItemGroup>

Migración de bibliotecas de controles


Si tiene un proyecto de biblioteca de controles de Windows Forms para migrar, las instrucciones son las mismas
que para migrar un proyecto de aplicación de Windows Forms de .NET Framework, excepto algunas opciones de
configuración. Y, en lugar de compilar en un archivo ejecutable, se compila en una biblioteca. La diferencia entre el
proyecto ejecutable y el proyecto de biblioteca, además de las rutas de acceso para los patrones globales de
archivo que incluyen el código fuente, es mínima.
Usando el ejemplo del paso anterior, vamos a expandir los proyectos y archivos con los que estamos trabajando.
ARCHIVO DESCRIPCIÓN

MyApps.sln Nombre del archivo de la solución.

MyControls.csproj Nombre del proyecto de controles de Windows Forms de .NET


Framework para migrar.

MyControlsCore.csproj Nombre del nuevo proyecto de biblioteca de .NET Core que


crea.

MyCoreControls.dll La biblioteca de controles de Windows Forms de .NET Core.

SolutionFolder
├───MyApps.sln
├───MyFormsApp
│ └───MyForms.csproj
├───MyFormsAppCore
│ └───MyFormsCore.csproj

├───MyFormsControls
│ └───MyControls.csproj
└───MyFormsControlsCore
└───MyControlsCore.csproj <--- New project for core controls

Tenga en cuenta las diferencias entre el proyecto MyControlsCore.csproj y el proyecto MyFormsCore.csproj creado
anteriormente.

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
- <OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
- <AssemblyName>MyCoreApp</AssemblyName>
- <RootNamespace>WindowsFormsApp1</RootNamespace>
+ <AssemblyName>MyControlsCore</AssemblyName>
+ <RootNamespace>WindowsFormsControlLibrary1</RootNamespace>
</PropertyGroup>

<ItemGroup>
- <Compile Include="..\MyFormsApp\**\*.cs" />
- <EmbeddedResource Include="..\MyFormsApp\**\*.resx" />
+ <Compile Include="..\MyFormsControls\**\*.cs" />
+ <EmbeddedResource Include="..\MyFormsControls\**\*.resx" />
</ItemGroup>

</Project>

Este es un ejemplo del aspecto que podría tener el archivo de proyecto de biblioteca de controles de Windows
Forms de .NET Core:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>

<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyName>MyCoreControls</AssemblyName>
<RootNamespace>WindowsFormsControlLibrary1</RootNamespace>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\MyFormsControls\**\*.cs" />
<EmbeddedResource Include="..\MyFormsControls\**\*.resx" />
</ItemGroup>

</Project>

Como puede ver, se quitó el nodo <OutputType> , que establece el compilador de forma predeterminada para
generar una biblioteca en lugar de un archivo ejecutable. <AssemblyName> y <RootNamespace> se han cambiado. En
concreto, <RootNamespace> debe coincidir con el espacio de nombres de la biblioteca de controles de Windows
Forms que va a migrar. Y, finalmente, los nodos <Compile> y <EmbeddedResource> se ajustaron para apuntar a la
carpeta de la biblioteca de controles de Windows Forms que está migrando.
A continuación, en el proyecto principal MyFormsCore.csproj de .NET Core, agregue una referencia a la nueva
biblioteca de controles de Windows Forms de .NET Core. Agregue una referencia con Visual Studio o la CLI de
.NET Core desde el directorio SolutionFolder:

dotnet add .\MyFormsAppCore\MyFormsCore.csproj reference .\MyFormsControlsCore\MyControlsCore.csproj

El comando anterior agrega lo siguiente al proyecto MyFormsCore.csproj:

<ItemGroup>
<ProjectReference Include="..\MyFormsControlsCore\MyControlsCore.csproj" />
</ItemGroup>

Problemas de compilación
Si tiene problemas al compilar los proyectos, puede que esté usando algunas API solo de Windows que están
disponibles en .NET Framework, pero no en .NET Core. Puede intentar agregar el paquete de NuGet del paquete
de compatibilidad de Windows al proyecto. Este paquete solo se ejecuta en Windows y agrega aproximadamente
20 000 API de Windows a los proyectos de .NET Core y .NET Standard.

dotnet add .\MyFormsAppCore\MyFormsCore.csproj package Microsoft.Windows.Compatibility

El comando anterior agrega lo siguiente al proyecto MyFormsCore.csproj:

<ItemGroup>
<PackageReference Include="Microsoft.Windows.Compatibility" Version="2.0.1" />
</ItemGroup>

Diseñador de Windows Forms


Como se detalla en este artículo, Visual Studio 2019 solo admite el Diseñador de Forms en los proyectos de
.NET Framework. Mediante la creación de un proyecto de .NET Core en paralelo, puede probar el proyecto con
.NET Core mientras utiliza el proyecto de .NET Framework para diseñar formularios. El archivo de solución incluye
proyectos de .NET Framework y .NET Core. Agregue y diseñe sus formularios y controles en el proyecto de .NET
Framework, y en función de los patrones globales de archivos que agreguemos a los proyectos de .NET Core,
cualquier archivo nuevo o modificado se incluirá automáticamente en los proyectos de .NET Core.
Una vez que Visual Studio 2019 sea compatible con el Diseñador de Windows Forms, podrá copiar/pegar el
contenido de su archivo de proyecto de .NET Core en el archivo de proyecto de .NET Framework. A continuación,
elimine los patrones globales de archivo agregados con los elementos <Source> y <EmbeddedResource> . Corrija las
rutas a cualquier referencia de proyecto utilizada por su aplicación. Esto actualiza eficazmente el proyecto de .NET
Framework a un proyecto de .NET Core.

Pasos siguientes
Obtenga más información sobre el paquete de compatibilidad de Windows.
Vea un vídeo sobre cómo migrar el proyecto de Windows Forms de .NET Framework a .NET Core.
2 minutes to read
Carga de dependencias en .NET Core
04/11/2019 • 2 minutes to read • Edit Online

Todas las aplicaciones .NET Core tienen dependencias. Incluso la aplicación sencilla hello world tiene
dependencias en partes de las bibliotecas de clases de .NET Core.
La descripción de la lógica de carga de ensamblados predeterminados de .NET Core puede ayudar a comprender y
depurar incidencias de implementación habituales.
En algunas aplicaciones, las dependencias se determinan dinámicamente en runtime. En estas situaciones, es
fundamental entender cómo se cargan los ensamblados administrados y las dependencias no administradas.

Descripción de AssemblyLoadContext
La API AssemblyLoadContext es fundamental para el diseño de carga de .NET Core. En el artículo Descripción de
AssemblyLoadContext se proporciona información general conceptual para el diseño.

Carga de detalles
Los detalles del algoritmo de carga se describen brevemente en varios artículos:
Algoritmo de carga de ensamblado administrado
Algoritmo de carga de ensamblado satélite
Algoritmo de carga de biblioteca no administrada (nativa)
Sondeo predeterminado

Creación de una aplicación de .NET Core con complementos


En el tutorial Creación de una aplicación .NET Core con complementos se describe cómo crear un elemento
AssemblyLoadContext personalizado. Usa un elemento AssemblyDependencyResolver para resolver las
dependencias del complemento. El tutorial aísla correctamente las dependencias del complemento de la aplicación
host.

Uso y depuración de la descargabilidad de ensamblado en .NET Core


El artículo Uso y depuración de la descargabilidad de ensamblado en .NET Core es un tutorial paso a paso.
Muestra cómo cargar una aplicación .NET Core, ejecutarla y luego descargarla. En el artículo también se
proporcionan sugerencias de depuración.
Descripción de
System.Runtime.Loader.AssemblyLoadContext
25/10/2019 • 10 minutes to read • Edit Online

La clase AssemblyLoadContext es única en .NET Core. En este artículo se intenta complementar la documentación
de la API AssemblyLoadContext con información conceptual.
Este artículo es relevante para los desarrolladores que implementan carga dinámica, en particular los
desarrolladores de marco de carga dinámica.

¿Qué es AssemblyLoadContext?
Cada aplicación de .NET Core usa implícitamente AssemblyLoadContext. Es el proveedor del runtime para buscar
y cargar las dependencias. Cada vez que se carga una dependencia, se invoca una instancia de
AssemblyLoadContext para buscarla.
Proporciona un servicio de búsqueda, carga y almacenamiento en caché de ensamblados administrados y
otras dependencias.
Para admitir la carga y descarga de código dinámico, crea un contexto aislado con el fin de cargar el código
y sus dependencias en su propia instancia de AssemblyLoadContext.

¿Cuándo necesita varias instancias de AssemblyLoadContext?


Una única instancia de AssemblyLoadContext se limita a cargar exactamente una versión de un elemento
Assembly por nombre de ensamblado simple, AssemblyName.Name.
Esta restricción puede convertirse en un problema cuando se cargan módulos de código de forma dinámica. Cada
módulo se compila de forma independiente y puede depender de distintas versiones de un elemento Assembly.
Este problema se produce normalmente cuando distintos módulos dependen de versiones diferentes de una
biblioteca usada habitualmente.
Para admitir la carga de código de forma dinámica, la API AssemblyLoadContext proporciona versiones en
conflicto de carga de un elemento Assembly en la misma aplicación. Cada instancia de AssemblyLoadContext
proporciona un diccionario único que asigna cada AssemblyName.Name a una instancia de Assembly concreta.
También proporciona un mecanismo práctico para agrupar las dependencias relacionadas con un módulo de
código para su descarga posterior.

¿Qué tiene de especial la instancia de AssemblyLoadContext.Default?


La instancia de AssemblyLoadContext.Default la rellena automáticamente el runtime en el inicio. Utiliza el sondeo
predeterminado para buscar y encontrar todas las dependencias estáticas.
Resuelve los escenarios de carga de dependencias más comunes.

¿Cómo admite AssemblyLoadContext las dependencias dinámicas?


AssemblyLoadContext tiene varios eventos y funciones virtuales que se pueden invalidar.
La instancia de AssemblyLoadContext.Default solo admite la invalidación de los eventos.
Los artículos Algoritmo de carga de ensamblado administrado, Algoritmo de carga de ensamblado satélite y
Algoritmo de carga de biblioteca no administrada (nativa) hacen referencia a todos los eventos y funciones
virtuales disponibles. En los artículos se muestra la posición relativa de cada evento y función en los algoritmos de
carga. En este artículo no se reproduce esa información.
En esta sección se tratan los principios generales de las funciones y eventos relevantes.
Ser reiterativo. Una consulta para una dependencia concreta siempre debe tener como resultado la misma
respuesta. Se debe devolver la misma instancia de dependencia cargada. Este requisito es fundamental para la
coherencia de la caché. En el caso concreto de los ensamblados administrados, creamos una caché de
Assembly. La clave de caché es un nombre de ensamblado sencillo, AssemblyName.Name.
Normalmente no se inician. Se espera que estas funciones devuelvan null , en lugar de iniciarse, cuando no
se pueda encontrar la dependencia solicitada. El inicio finalizará la búsqueda prematuramente y propagará una
excepción al autor de la llamada. El inicio se debe restringir a errores inesperados, como un ensamblado
dañado o una condición de memoria insuficiente.
Evitar la recursividad. Tenga en cuenta que estas funciones y controladores implementan las reglas de carga
para buscar dependencias. Su implementación no debe llamar a las API que desencadenan la recursividad.
Normalmente, el código debería llamar a las funciones de carga AssemblyLoadContext que requieran una
ruta de acceso concreta o un argumento de referencia de memoria.
Cargar en el elemento AssemblyLoadContext correcto. La elección de dónde cargar las dependencias es
específica de la aplicación. Estos eventos y funciones implementan la opción. Cuando el código llama a las
funciones de carga por ruta de acceso AssemblyLoadContext, les llama en la instancia en la que se quiere
cargar el código. En algún momento, devolver null y permitir que AssemblyLoadContext.Default controle la
carga puede ser la opción más sencilla.
Tenga en cuenta las carreras de subprocesos. La carga la pueden desencadenar varios subprocesos.
AssemblyLoadContext controla las carreras de subprocesos mediante la adición atómica de ensamblados a su
caché. La instancia del que pierde la carrera se descarta. En la lógica de implementación, no agregue lógica
adicional que no controle correctamente varios subprocesos.

¿Cómo se aíslan las dependencias dinámicas?


Cada instancia de AssemblyLoadContext representa un ámbito único para instancias de Assembly y definiciones
de Type.
No existe aislamiento binario entre estas dependencias. Solo están aisladas por no encontrarse entre sí por
nombre.
En cada AssemblyLoadContext:
AssemblyName.Name puede hacer referencia a una instancia de Assembly distinta.
Type.GetType puede devolver una instancia de tipo distinta para el mismo tipo name .

¿Cómo se comparten las dependencias?


Las dependencias se pueden compartir fácilmente entre instancias de AssemblyLoadContext. El modelo general es
que un elemento AssemblyLoadContext cargue una dependencia. El otro comparte la dependencia mediante el uso
de una referencia en el ensamblado cargado.
Este uso compartido es necesario para los ensamblados en runtime. Estos ensamblados solo se pueden cargar en
AssemblyLoadContext.Default. Lo mismo se requiere en el caso de marcos como ASP.NET , WPF o WinForms .
Se recomienda cargar las dependencias compartidas en AssemblyLoadContext.Default. Este uso compartido es el
modelo de diseño común.
El uso compartido se implementa en la codificación de la instancia de AssemblyLoadContext personalizada.
AssemblyLoadContext tiene varios eventos y funciones virtuales que se pueden invalidar. Cuando alguna de estas
funciones devuelve una referencia a una instancia de Assembly que se ha cargado en otra instancia de
AssemblyLoadContext, se comparte la instancia de Assembly. El algoritmo de carga estándar se aplaza a
AssemblyLoadContext.Default para cargar con el fin de simplificar el patrón común de uso compartido. Consulte
Algoritmo de carga de ensamblado administrado.

Complicaciones
Incidencias de conversión de tipos
Cuando dos instancias de AssemblyLoadContext contienen definiciones de tipo con el mismo name , no son del
mismo tipo. Son del mismo tipo si y solo si proceden de la misma instancia de Assembly.
Para complicar las cosas, los mensajes de excepción sobre estos tipos no coincidentes pueden ser confusos. Se
hace referencia a los tipos en los mensajes de excepción por sus nombres de tipo simple. En este caso, el mensaje
de excepción común tendría el formato siguiente:

El objeto de tipo "IsolatedType" no se puede convertir al tipo "IsolatedType".

Depuración de incidencias de conversión de tipos


Dado un par de tipos no coincidentes, es importante conocer también lo siguiente:
El elemento Type.Assembly de cada tipo.
El elemento AssemblyLoadContext de cada tipo., que se puede obtener a través de la función
AssemblyLoadContext.GetLoadContext(Assembly).
Dado dos objetos a y b , la evaluación en el depurador de lo siguiente resultará útil:

// In debugger look at each assembly's instance, Location, and FullName


a.GetType().Assembly
b.GetType().Assembly
// In debugger look at each AssemblyLoadContext's instance and name
System.Runtime.AssemblyLoadContext.GetLoadContext(a.GetType().Assembly)
System.Runtime.AssemblyLoadContext.GetLoadContext(b.GetType().Assembly)

Resolución de incidencias de conversión de tipos


Existen dos modelos de diseño para resolver estas incidencias de conversión de tipos.
1. Usar tipos comunes compartidos. Este tipo compartido puede ser un tipo en runtime primitivo o puede
implicar la creación de un nuevo tipo compartido en un ensamblado compartido. A menudo, el tipo
compartido es una interfaz definida en un ensamblado de aplicación. Vea también: ¿Cómo se comparten las
dependencias?.
2. Utilice técnicas de serialización para realizar la conversión de un tipo a otro.
Sondeo predeterminado
25/10/2019 • 4 minutes to read • Edit Online

La instancia de AssemblyLoadContext.Default se encarga de buscar las dependencias de un ensamblado. En este


artículo se describe la lógica de sondeo de la instancia de AssemblyLoadContext.Default.

Propiedades de sondeo configuradas por host


Cuando se inicia el runtime, el host de tiempo de ejecución proporciona un conjunto de propiedades de sondeo
con nombre que configuran las rutas de acceso de sondeo de AssemblyLoadContext.Default.
Cada propiedad de sondeo es opcional. Si está presente, cada propiedad es un valor de cadena que contiene una
lista delimitada de rutas de acceso absolutas. El delimitador es ";" en Windows y ":" en el resto de plataformas.

NOMBRE DE LA PROPIEDAD DESCRIPCIÓN

TRUSTED_PLATFORM_ASSEMBLIES Lista de rutas de acceso de archivos de ensamblado de


plataforma y aplicación.

PLATFORM_RESOURCE_ROOTS Lista de rutas de acceso de directorio para buscar


ensamblados de recursos satélite.

NATIVE_DLL_SEARCH_DIRECTORIES Lista de rutas de acceso de directorio para buscar bibliotecas


no administradas (nativas).

APP_PATHS Lista de rutas de acceso de directorio para buscar bibliotecas


administradas.

APP_NI_PATHS Lista de rutas de acceso de directorio para buscar imágenes


nativas de ensamblados administrados.

¿Cómo se rellenan las propiedades?


Existen dos escenarios principales para rellenar las propiedades, en función de si existe el archivo
<myapp>.deps.json.
Cuando el archivo *.deps.json está presente, se analiza para rellenar las propiedades de sondeo.
Cuando el archivo *.deps.json no está presente, se supone que el directorio de la aplicación contiene todas las
dependencias. El contenido del directorio se usa para rellenar las propiedades de sondeo.
Además, los archivos *.deps.json para cualquier marco al que se hace referencia se analizan de forma similar.
Por último, se puede usar la variable de entorno ADDITIONAL_DEPS para agregar dependencias adicionales.
Cómo ver las propiedades de sondeo desde un código administrado
Cada propiedad está disponible mediante una llamada a la función AppContext.GetData(String) con el nombre de
la propiedad de la tabla anterior.
Cómo depurar la construcción de las propiedades de sondeo
El host de tiempo de ejecución de .NET Core generará mensajes de seguimiento útiles cuando se habiliten
determinadas variables de entorno:
VARIABLE DE ENTORNO DESCRIPCIÓN

COREHOST_TRACE=1 Habilita el seguimiento.

COREHOST_TRACEFILE=<path> Realiza un seguimiento de una ruta de acceso de archivo en


lugar del elemento stderr predeterminado.

COREHOST_TRACE_VERBOSITY Establece el nivel de detalle de 1 (inferior) a 4 (superior).

Sondeo predeterminado de ensamblado administrado


Al realizar un sondeo para buscar un ensamblado administrado, AssemblyLoadContext.Default busca en orden en:
Archivos que coinciden con AssemblyName.Name en TRUSTED_PLATFORM_ASSEMBLIES (después de quitar
extensiones de archivo).
Archivos de ensamblado de imagen nativa en APP_NI_PATHS con extensiones de archivo comunes.
Archivos de ensamblado en APP_PATHS con extensiones de archivo comunes.

Sondeo de ensamblado satélite (recurso)


Con el fin de buscar un ensamblado satélite para una referencia cultural concreta, construya un conjunto de rutas
de acceso de archivos.
Para cada ruta de acceso de PLATFORM_RESOURCE_ROOTS y, después, APP_PATHS , anexe la cadena CultureInfo.Name,
un separador de directorios, la cadena AssemblyName.Name y la extensión ".dll".
Si existe algún archivo coincidente, intente cargarlo y devolverlo.

Sondeo de biblioteca no administrada (nativa)


Al realizar un sondeo para buscar una biblioteca no administrada, NATIVE_DLL_SEARCH_DIRECTORIES se busca
mediante una búsqueda de una biblioteca coincidente.
Algoritmo de carga de ensamblado administrado
25/11/2019 • 4 minutes to read • Edit Online

Los ensamblados administrados se ubican y se cargan con un algoritmo que implica varias fases.
Todos los ensamblados administrados, excepto los ensamblados satélite y los de WinRT , usan el mismo algoritmo.

¿Cuándo se cargan los ensamblados administrados?


El mecanismo más común para desencadenar la carga de un ensamblado administrado es una referencia estática
de ensamblado. El compilador inserta estas referencias siempre que el código usa un tipo definido en otro
ensamblado. Estos ensamblados los carga ( load-by-name ) el runtime, según sea necesario.
El uso directo de API específicas también desencadenará cargas:

API DESCRIPCIÓN ACTIVE ASSEMBLYLOADCONTEX T

AssemblyLoadContext.LoadFromAssem Load-by-name La instancia de this.


blyName

AssemblyLoadContext.LoadFromAssem Cargue desde la ruta de acceso. La instancia de this.


blyPath
AssemblyLoadContext.LoadFromNa
tiveImagePath

AssemblyLoadContext.LoadFromStrea Cargue desde el objeto. La instancia de this.


m

Assembly.LoadFile Cargue desde la ruta de acceso en una La nueva instancia de


nueva instancia de AssemblyLoadContext.
AssemblyLoadContext.

Assembly.LoadFrom Cargue desde la ruta de acceso en la Instancia de


instancia de AssemblyLoadContext.Default.
AssemblyLoadContext.Default.
Agregue un controlador Resolving
a AssemblyLoadContext.Default. El
controlador cargará las
dependencias del ensamblado
desde su directorio.

Assembly.Load(AssemblyName) Load-by-name . Se infiere del autor de la llamada.


Assembly.Load(String) Prefiere los métodos
AssemblyLoadContext.
Assembly.LoadWithPartialName

Assembly.Load(Byte[]) Cargue desde el objeto en una nueva La nueva instancia de


Assembly.Load(Byte[], Byte[]) instancia de AssemblyLoadContext. AssemblyLoadContext.
API DESCRIPCIÓN ACTIVE ASSEMBLYLOADCONTEX T

Type.GetType(String) Load-by-name . Se infiere del autor de la llamada.


Type.GetType(String, Boolean) Prefiere los métodos Type.GetType
con un argumento
Type.GetType(String, Boolean, assemblyResolver .
Boolean)

Assembly.GetType Si el tipo name describe un tipo Se infiere del autor de la llamada.


genérico calificado con el ensamblado, Prefiere Type.GetType al utilizar
desencadene un elemento nombres de tipo calificados con el
Load-by-name . ensamblado.

Activator.CreateInstance(String, String) Load-by-name . Se infiere del autor de la llamada.


Activator.CreateInstance(String, Prefiere los métodos
String, Object[]) Activator.CreateInstance que
toman un argumento Type.
Activator.CreateInstance(String,
String, Boolean, BindingFlags,
Binder, Object[], CultureInfo,
Object[])

Algoritmo
El algoritmo siguiente describe cómo el runtime carga un ensamblado administrado.
1. Determine el elemento AssemblyLoadContext de active .
En el caso de una referencia estática de ensamblado, active AssemblyLoadContext es la instancia que
ha cargado el ensamblado de referencia.
Las API preferidas hacen que active AssemblyLoadContext sean explícitos.
Otras API infieren el elemento AssemblyLoadContext de active . Para estas API, se usa la propiedad
AssemblyLoadContext.CurrentContextualReflectionContext. Si su valor es null , se usa la instancia de
AssemblyLoadContext inferida.
Consulte la tabla anterior.
2. En el caso de los métodos Load-by-name , el elemento AssemblyLoadContext activo carga el ensamblado.
En orden de prioridad por:
Comprobar su cache-by-name .
Llamar a la función de AssemblyLoadContext.Load.
Comprobar la memoria caché de las instancias de AssemblyLoadContext.Default y ejecutar la lógica
sondeo predeterminado de ensamblado administrado.
Generar el evento AssemblyLoadContext.Resolving para el AssemblyLoadContext activo.
Generar el evento AppDomain.AssemblyResolve.
3. Para los demás tipos de cargas, el AssemblyLoadContext active carga el ensamblado. En orden de
prioridad por:
Comprobar su cache-by-name .
Cargar desde la ruta de acceso especificada o el objeto de ensamblado sin formato.
4. En cualquier caso, si se ha cargado un ensamblado recientemente, entonces ocurre lo siguiente:
Se genera el evento AppDomain.AssemblyLoad.
Se agrega una referencia al elemento cache-by-name de la instancia de AssemblyLoadContext del
ensamblado.
5. Si se encuentra el ensamblado, se agrega una referencia según sea necesario al elemento cache-by-name
de la instancia de AssemblyLoadContext de active .
Algoritmo de carga de ensamblado satélite
25/10/2019 • 5 minutes to read • Edit Online

Los ensamblados satélite se utilizan con el fin de almacenar los recursos localizados personalizados para el idioma
y la referencia cultural.
Los ensamblados satélite usan un algoritmo de carga distinto al de los ensamblados administrados generales.

¿Cuándo se cargan los ensamblados satélite?


Los ensamblados satélite se cargan al cargar un recurso localizado.
La API básica para cargar recursos localizados es la clase System.Resources.ResourceManager. En última
instancia, la clase ResourceManager llamará al método GetSatelliteAssembly para cada CultureInfo.Name.
Las API de nivel alto pueden abstraer la API de nivel bajo.

Algoritmo
El proceso de reserva de recursos de .NET Core conlleva los pasos siguientes:
1. Determine la instancia de AssemblyLoadContext de active . En todos los casos, la instancia de active es
el elemento AssemblyLoadContext del ensamblado que se ejecuta.
2. La instancia de active intenta cargar un ensamblado satélite para la referencia cultural solicitada por
orden de prioridad al realizar lo siguiente:
Comprobar la memoria caché.
Comprobar en el directorio del ensamblado actualmente en ejecución un subdirectorio que coincida
con el elemento CultureInfo.Name solicitado (por ejemplo, es-MX ).

NOTE
Esta característica no se ha implementado en .NET Core antes de la versión 3.0.

NOTE
En Linux y macOS, el subdirectorio distingue entre mayúsculas y minúsculas y debe cumplir lo siguiente:
Coincidir exactamente con mayúsculas y minúsculas.
Estar en minúsculas.

Si active es la instancia de AssemblyLoadContext.Default, ejecutar la lógica sondeo del


ensamblado de satélite (recurso) predeterminado.
Llamar a la función de AssemblyLoadContext.Load.
Generar el evento AssemblyLoadContext.Resolving.
Generar el evento AppDomain.AssemblyResolve.
3. Si se carga un ensamblado satélite:
Se genera el evento AppDomain.AssemblyLoad.
Se busca en el ensamblado el recurso solicitado. Si el runtime encuentra el recurso en el ensamblado, lo
usará. Si no encuentra el recurso, seguirá con la búsqueda.

NOTE
Para buscar un recurso dentro del ensamblado satélite, el entorno de ejecución busca el archivo de recursos
solicitado por ResourceManager para el CultureInfo.Name actual. En el archivo de recursos, busca el nombre del
recurso solicitado. Si no se encuentra ninguno, se considera que no se encontró el recurso.

4. Luego, el runtime busca los ensamblados de referencias culturales primarias a través de muchos niveles
potenciales, y cada vez repite los pasos 2 y 3.
Cada referencia cultural tiene solo un elemento primario, que está definido mediante la propiedad
CultureInfo.Parent.
La búsqueda de las referencias culturales primarias se detiene cuando la propiedad Parent de una
referencia cultural es CultureInfo.InvariantCulture.
En el caso de InvariantCulture, no se vuelve a los pasos 2 y 3, sino que continúa con el paso 5.
5. Si todavía no se encuentra el recurso, se usa el recurso para la referencia cultural predeterminada (de
reserva).
Normalmente, los recursos de la referencia cultural predeterminada se incluyen en el ensamblado de la
aplicación principal. Sin embargo, se puede especificar UltimateResourceFallbackLocation.Satellite para la
propiedad NeutralResourcesLanguageAttribute.Location. Este valor indica que la ubicación de reserva final
para los recursos es un ensamblado satélite, en lugar del ensamblado principal.

NOTE
La referencia cultural predeterminada es la reserva final. Por lo tanto, se recomienda incluir siempre un conjunto de
recursos exhaustivo en el archivo de recursos predeterminado. Esto ayuda a evitar que se produzcan excepciones. Al
tener un conjunto exhaustivo, se proporciona una reserva para todos los recursos y se garantiza que al menos un
recurso esté siempre presente para el usuario, incluso si no es específico de la referencia cultural.

6. Por último,
si el tiempo de ejecución no encuentra un archivo de recursos para una referencia cultural
predeterminada (de reserva), se produce una excepción MissingManifestResourceException o
MissingSatelliteAssemblyException.
Si se encuentra el archivo de recursos pero el recurso solicitado no se encuentra, la solicitud devuelve
null .
Algoritmo de carga de biblioteca no administrada
(nativa)
25/10/2019 • 2 minutes to read • Edit Online

Las bibliotecas no administradas se ubican y se cargan con un algoritmo que implica varias fases.
El algoritmo siguiente describe cómo se cargan las bibliotecas nativas a través de PInvoke .

Algoritmo de la biblioteca de carga PInvoke


PInvoke usa el algoritmo siguiente al intentar cargar un ensamblado no administrado:
1. Determine el elemento AssemblyLoadContext de active . En el caso de una biblioteca de carga no
administrada, el elemento AssemblyLoadContext de active es el que tiene el ensamblado que define
PInvoke .

2. En el caso del elemento AssemblyLoadContext de active , intente buscar el ensamblado en orden de


prioridad por:
Comprobar la memoria caché.
Llamar al delegado System.Runtime.InteropServices.DllImportResolver actual que establece la
función NativeLibrary.SetDllImportResolver(Assembly, DllImportResolver).
Llamar a la función AssemblyLoadContext.LoadUnmanagedDll en el elemento
AssemblyLoadContext de active .
Comprobar la memoria caché de la instancia de AppDomain y ejecutar la lógica de sondeo de
biblioteca no administrada (nativa).
Generar el evento AssemblyLoadContext.ResolvingUnmanagedDll para el elemento
AssemblyLoadContext de active .
Creación de una aplicación de .NET Core con
complementos
25/11/2019 • 15 minutes to read • Edit Online

Este tutorial muestra cómo crear un contexto AssemblyLoadContext personalizado para cargar complementos. Se
usa un elemento AssemblyDependencyResolver para resolver las dependencias del complemento. El tutorial aísla
correctamente las dependencias del complemento de la aplicación host. Aprenderá a:
Estructurar un proyecto para admitir los complementos.
Crear un elemento AssemblyLoadContext personalizado para cargar cada complemento.
Usar el tipo System.Runtime.Loader.AssemblyDependencyResolver para permitir que los complementos
tengan dependencias.
Crear complementos que se puedan implementar fácilmente con solo copiar los artefactos de compilación.

Requisitos previos
Instale el SDK de .NET Core 3.0 o una versión más reciente.

Crear la aplicación
El primer paso es crear la aplicación:
1. Cree una carpeta nueva y, en ella, ejecute el siguiente comando:

dotnet new console -o AppWithPlugin

2. Para facilitar la compilación del proyecto, cree un archivo de solución de Visual Studio en la misma carpeta.
Ejecute el siguiente comando:

dotnet new sln

3. Ejecute el siguiente comando para agregar el proyecto de aplicación a la solución:

dotnet sln add AppWithPlugin/AppWithPlugin.csproj

Ahora ya se puede rellenar el esqueleto de la aplicación. Reemplace el código del archivo


AppWithPlugin/Program.cs con el código siguiente:
using PluginBase;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace AppWithPlugin
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length == 1 && args[0] == "/d")
{
Console.WriteLine("Waiting for any key...");
Console.ReadLine();
}

// Load commands from plugins.

if (args.Length == 0)
{
Console.WriteLine("Commands: ");
// Output the loaded commands.
}
else
{
foreach (string commandName in args)
{
Console.WriteLine($"-- {commandName} --");

// Execute the command with the name passed as an argument.

Console.WriteLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}

Creación de las interfaces de complemento


El paso siguiente en la creación de una aplicación con complementos consiste en definir la interfaz que los
complementos tienen que implementar. Se recomienda crear una biblioteca de clases que contenga los tipos que
se van a usar para la comunicación entre la aplicación y los complementos. Esta división permite publicar la
interfaz de complemento como un paquete sin tener que enviar la aplicación completa.
En la carpeta raíz del proyecto, ejecute . Además, ejecute
dotnet new classlib -o PluginBase
dotnet sln add PluginBase/PluginBase.csproj para agregar el proyecto al archivo de la solución. Elimine el archivo
PluginBase/Class1.cs y cree uno en la carpeta PluginBase con el nombre ICommand.cs con la definición de
interfaz siguiente:
namespace PluginBase
{
public interface ICommand
{
string Name { get; }
string Description { get; }

int Execute();
}
}

Esta interfaz ICommand es la que van a implementar todos los complementos.


Ahora que se ha definido la interfaz ICommand , el proyecto de aplicación se puede rellenar un poco más. Agregue
una referencia desde el proyecto AppWithPlugin al proyecto PluginBase con el comando
dotnet add AppWithPlugin\AppWithPlugin.csproj reference PluginBase\PluginBase.csproj desde la carpeta raíz.

Reemplace el comentario // Load commands from plugins con el fragmento de código siguiente para habilitarlo
para cargar complementos desde rutas de acceso de archivo determinadas:

string[] pluginPaths = new string[]


{
// Paths to plugins to load.
};

IEnumerable<ICommand> commands = pluginPaths.SelectMany(pluginPath =>


{
Assembly pluginAssembly = LoadPlugin(pluginPath);
return CreateCommands(pluginAssembly);
}).ToList();

Después, reemplace el comentario // Output the loaded commands por el fragmento de código siguiente:

foreach (ICommand command in commands)


{
Console.WriteLine($"{command.Name}\t - {command.Description}");
}

Reemplace el comentario // Execute the command with the name passed as an argument por el fragmento de código
siguiente:

ICommand command = commands.FirstOrDefault(c => c.Name == commandName);


if (command == null)
{
Console.WriteLine("No such command is known.");
return;
}

command.Execute();

Y, por último, agregue los métodos estáticos denominados LoadPlugin y CreateCommands a la clase Program ,
como se muestra aquí:
static Assembly LoadPlugin(string relativePath)
{
throw new NotImplementedException();
}

static IEnumerable<ICommand> CreateCommands(Assembly assembly)


{
int count = 0;

foreach (Type type in assembly.GetTypes())


{
if (typeof(ICommand).IsAssignableFrom(type))
{
ICommand result = Activator.CreateInstance(type) as ICommand;
if (result != null)
{
count++;
yield return result;
}
}
}

if (count == 0)
{
string availableTypes = string.Join(",", assembly.GetTypes().Select(t => t.FullName));
throw new ApplicationException(
$"Can't find any type which implements ICommand in {assembly} from {assembly.Location}.\n" +
$"Available types: {availableTypes}");
}
}

Carga de complementos
Ahora la aplicación puede cargar correctamente y crear instancias de los comandos a partir de los ensamblados
de complemento cargados, pero todavía no puede cargar los ensamblados de complemento. Cree un archivo
denominado PluginLoadContext.cs en la carpeta AppWithPlugin con el contenido siguiente:
using System;
using System.Reflection;
using System.Runtime.Loader;

namespace AppWithPlugin
{
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;

public PluginLoadContext(string pluginPath)


{
_resolver = new AssemblyDependencyResolver(pluginPath);
}

protected override Assembly Load(AssemblyName assemblyName)


{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}

return null;
}

protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)


{
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}

return IntPtr.Zero;
}
}
}

El tipo PluginLoadContext se deriva de AssemblyLoadContext. El tipo AssemblyLoadContext es un tipo especial en


el runtime que permite a los desarrolladores aislar los ensamblados cargados en grupos diferentes para
asegurarse de que las versiones de ensamblado no entren en conflicto. Además, un elemento
AssemblyLoadContext personalizado puede elegir otras rutas de acceso desde las que cargar los ensamblados e
invalidar el comportamiento predeterminado. El elemento PluginLoadContext usa una instancia del tipo
AssemblyDependencyResolver que se introdujo en .NET Core 3.0 para resolver los nombres de ensamblado en rutas
de acceso. El objeto AssemblyDependencyResolver se construye con la ruta de acceso a una biblioteca de clases
.NET. Resuelve los ensamblados y las bibliotecas nativas en sus rutas de acceso relativas en función del archivo
deps.json para la biblioteca de clases cuya ruta de acceso se haya pasado al constructor
AssemblyDependencyResolver . El elemento AssemblyLoadContext personalizado permite que los complementos
tengan sus propias dependencias y el elemento AssemblyDependencyResolver facilita la tarea de cargar
correctamente las dependencias.
Ahora que el proyecto AppWithPlugin tiene el tipo PluginLoadContext , actualice el método Program.LoadPlugin
con el cuerpo siguiente:
static Assembly LoadPlugin(string relativePath)
{
// Navigate up to the solution root
string root = Path.GetFullPath(Path.Combine(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(
Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));

string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\',


Path.DirectorySeparatorChar)));
Console.WriteLine($"Loading commands from: {pluginLocation}");
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);
return loadContext.LoadFromAssemblyName(new
AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
}

Al usar una instancia de PluginLoadContext diferente para cada complemento, los complementos puede tener
dependencias diferentes o incluso en conflicto sin ningún problema.

Complemento simple sin dependencias


En la carpeta raíz, siga estos pasos:
1. Ejecute el siguiente comando para crear un nuevo proyecto de biblioteca de clases denominado
HelloPlugin :

dotnet new classlib -o HelloPlugin

2. Ejecute el siguiente comando para agregar el proyecto a la solución AppWithPlugin :

dotnet sln add HelloPlugin/HelloPlugin.csproj

3. Reemplace el archivo HelloPlugin/Class1.cs con un archivo denominado HelloCommand.cs con el


contenido siguiente:

using PluginBase;
using System;

namespace HelloPlugin
{
public class HelloCommand : ICommand
{
public string Name { get => "hello"; }
public string Description { get => "Displays hello message."; }

public int Execute()


{
Console.WriteLine("Hello !!!");
return 0;
}
}
}

Ahora, abra el archivo HelloPlugin.csproj. Debería tener un aspecto similar al siguiente:


<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

</Project>

Entre las etiquetas <Project> , agregue los elementos siguientes:

<ItemGroup>
<ProjectReference Include="..\PluginBase\PluginBase.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>

El elemento <Private>false</Private> es importante. Indica a MSBuild que no copie PluginBase.dll en el


directorio de salida para HelloPlugin. Si el ensamblado PluginBase.dll está presente en el directorio de salida,
PluginLoadContext encontrará el ensamblado y lo cargará cuando cargue el ensamblado HelloPlugin.dll. En este
momento, el tipo HelloPlugin.HelloCommand implementará la interfaz ICommand de PluginBase.dll en el directorio
de salida del proyecto HelloPlugin , no la interfaz ICommand que se carga en el contexto de carga predeterminado.
Como el runtime considera que estos dos tipos son tipos diferentes de ensamblados distintos, el método
AppWithPlugin.Program.CreateCommands no encontrará los comandos. Como resultado, los metadatos
<Private>false</Private> son necesarios para la referencia al ensamblado que contiene las interfaces de
complemento.
Ahora que se ha completado el proyecto HelloPlugin , se debe actualizar el proyecto AppWithPlugin para saber
dónde se puede encontrar el complemento HelloPlugin . Después del comentario // Paths to plugins to load ,
agregue @"HelloPlugin\bin\Debug\netcoreapp3.0\HelloPlugin.dll" como un elemento de la matriz pluginPaths .

Complemento con dependencias de biblioteca


Casi todos los complementos son más complejos que un simple ejemplo "Hola mundo", y muchos tienen
dependencias en otras bibliotecas. En los proyectos de complemento JsonPlugin y OldJson del ejemplo se
muestran dos ejemplos de complementos con dependencias de paquetes NuGet en Newtonsoft.Json . Los propios
archivos del proyecto no tienen información especial para las referencias del proyecto y, después de agregar las
rutas de acceso de complemento a la matriz pluginPaths , los complementos se ejecutan perfectamente, incluso
en la misma ejecución de la aplicación AppWithPlugin. Pero estos proyectos no copian los ensamblados a los que
se hace referencia en su directorio de salida, por lo que los ensamblados deben estar presentes en la máquina del
usuario para que los complementos funcionen. Hay dos maneras de solucionar este problema. La primera opción
consiste en usar el comando dotnet publish para publicar la biblioteca de clases. Como alternativa, si quiere
poder usar la salida de dotnet build para el complemento, puede agregar la propiedad
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> entre las etiquetas <PropertyGroup> del archivo
de proyecto del complemento. Vea el proyecto de complemento XcopyablePlugin para obtener un ejemplo.

Otros ejemplos en la muestra


Puede encontrar el código fuente completo para este tutorial en el repositorio dotnet/samples. El ejemplo
completo incluye algunos otros ejemplos de comportamiento AssemblyDependencyResolver . Por ejemplo, el objeto
AssemblyDependencyResolver también puede resolver las bibliotecas nativas, así como los ensamblados satélite
localizados en paquetes NuGet. UVPlugin y FrenchPlugin en el repositorio de ejemplos demuestran estos
escenarios.
Referencia a un complemento desde un paquete NuGet
Supongamos que hay una aplicación A que tiene una interfaz de complemento definida en el paquete NuGet
denominado A.PluginBase . ¿Cómo se hace referencia correctamente al paquete en el proyecto de complemento?
Para las referencias de proyecto, el uso de los metadatos <Private>false</Private> en el elemento
ProjectReference del archivo de proyecto ha impedido que el archivo DLL se copiara en la salida.

Para hacer referencia correctamente al paquete A.PluginBase , le interesará cambiar el elemento


<PackageReference> del archivo de proyecto por lo siguiente:

<PackageReference Include="A.PluginBase" Version="1.0.0">


<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>

Esto evita que los ensamblados A.PluginBase se copien en el directorio de salida del complemento y asegura que
el complemento use la versión de A.PluginBase la aplicación A.

Recomendaciones para plataformas de destino de complemento


Como en la carga de dependencias de complemento se usa el archivo deps.json, hay un problema relacionado con
la plataforma de destino del complemento. En concreto, los complementos deben tener como destino un runtime
como .NET Core 3.0, en lugar de una versión de .NET Standard. El archivo .deps.json se genera en función de la
plataforma de destino del proyecto y, como muchos paquetes compatibles con .NET Standard incluyen
ensamblados de referencia para compilar en .NET Standard y ensamblados de implementación para runtimes
específicos, es posible que el archivo .deps.json no vea correctamente los ensamblados de implementación, o bien
que tome la versión de .NET Standard de un ensamblado en lugar de la de .NET Core que se espera.

Referencias del marco de trabajo de complementos


En la actualidad, los complementos no pueden introducir nuevos marcos en el proceso. Por ejemplo, no puede
cargar un complemento que use el marco Microsoft.AspNetCore.App en una aplicación en la que solo se use el
marco Microsoft.NETCore.App raíz. La aplicación host debe declarar referencias a todos los marcos de trabajo
necesarios para los complementos.
2 minutes to read
Compilación de .NET Core a partir del código fuente
10/01/2020 • 8 minutes to read • Edit Online

La capacidad de compilar .NET Core a partir de su código fuente es importante en varios sentidos: facilita la
portabilidad de .NET Core a nuevas plataformas, permite contribuciones y correcciones del producto y permite
crear versiones personalizadas de .NET. En este artículo, se proporcionan instrucciones para los desarrolladores
que quieren compilar y distribuir sus propias versiones de .NET Core.

Compilación de CLR a partir del código fuente


El código fuente de CLR de .NET Core puede encontrarse en el repositorio dotnet/runtime en GitHub.
Actualmente, la compilación depende de los siguientes requisitos previos:
Git
CMake
Python
un compilador de C++.
Para compilar CLR después de instalar estos requisitos previos, invoque el script de compilación ( build.cmd en
Windows, o build.sh en Linux y macOS ) en la base del repositorio dotnet/runtime.
La instalación de los componentes varía según el sistema operativo (SO ). Consulte las instrucciones de
compilación de su sistema operativo específico:
Windows
Linux
macOS
FreeBSD
NetBSD
No hay ninguna compilación cruzada entre sistemas operativos (solo para ARM, que se basa en X64).
Debe estar en la plataforma concreta para compilar esa plataforma.
La compilación tiene dos buildTypes principales:
Debug (valor predeterminado): compila el tiempo de ejecución con las optimizaciones mínimas y las
comprobaciones (aserciones) en tiempo de ejecución adicionales. Aunque esta reducción en el nivel de
optimización y las comprobaciones adicionales ralentizan la ejecución en tiempo de ejecución, resultan útiles
para realizar la depuración. Este es el valor recomendado para los entornos de desarrollo y pruebas.
Release: compila el tiempo de ejecución con las optimizaciones completas y sin las comprobaciones en tiempo
de ejecución adicionales. Aunque el rendimiento en tiempo de ejecución será mucho más rápido, puede tardar
un poco más en compilarse y puede resultar complicado realizar la depuración. Pase release al script de
compilación para seleccionar este tipo de compilación.
Además, de forma predeterminada, la compilación no solo crea los archivos ejecutables en tiempo de ejecución,
sino que también compila todas las pruebas. Hay bastantes pruebas, lo que exige una cantidad considerable de
tiempo que no es necesario si tan solo se quiere experimentar con los cambios. Para omitir las compilaciones de
pruebas, agregue el argumento skiptests al script de compilación, como en el ejemplo siguiente (reemplace
.\build con ./build.sh en los equipos Unix):
.\build skiptests

En el ejemplo anterior, se ha mostrado cómo compilar el tipo Debug , que tiene las comprobaciones (aserciones) en
tiempo de desarrollo habilitadas y las optimizaciones deshabilitadas. Para compilar el tipo de versión (velocidad
máxima), haga lo siguiente:

.\build release skiptests

Puede encontrar más opciones de compilación con build si usa el calificador -? o -help.
Usar la compilación
La compilación coloca todos los archivos generados en el directorio bin en la base del repositorio. Hay un
directorio bin\Log que contiene archivos de registro generados durante la compilación (más útil cuando se produce
un error en la compilación). La salida real se coloca en un directorio bin\Producto [plataforma ].[arquitectura de
CPU ].[tipo de compilación] , como bin\Producto\Windows_NT.x64.Release.
Aunque el resultado de la compilación "sin procesar" a veces resulta útil, normalmente solo interesan los paquetes
de NuGet, que se colocan en el subdirectorio .nuget\pkg del directorio de salida anterior.
Hay dos técnicas básicas para usar el nuevo tiempo de ejecución:
1. Use dotnet.exe y NuGet para crear una aplicación. Vea Usar la compilación para obtener instrucciones
sobre cómo crear un programa que use el nuevo tiempo de ejecución mediante paquetes de NuGet que
acaba de crear y la interfaz de la línea de comandos (CLI) de "dotnet". Esta técnica es la forma probable en
que los desarrolladores que no usan el tiempo de ejecución van a consumir el nuevo tiempo de ejecución.
2. Use corerun.exe para ejecutar una aplicación con archivos DLL sin empaquetar. Este repositorio
también define un host simple denominado corerun.exe que NO tiene ninguna dependencia en NuGet.
Debe indicar al host de dónde obtiene los archivos DLL necesarios que usa y tiene que recopilarlos
manualmente. Esta técnica se usa en todas las pruebas del repositorio dotnet/runtime, y es útil para el bucle
local rápido "editar-compilar-depurar", como en el caso de las pruebas unitarias preliminares. Vea Executing
.NET Core Apps with CoreRun.exe (Ejecutar aplicaciones de .NET Core con CoreRun.exe) para obtener más
información sobre el uso de esta técnica.

Compilar la CLI a partir del código fuente


El código fuente de la CLI de .NET Core puede encontrarse en el repositorio dotnet/cli en GitHub.
Para compilar la CLI de .NET Core, necesita tener lo siguiente instalado en su equipo.
Windows y Linux:
GIT en la ruta de acceso
macOS:
GIT en la ruta de acceso
Xcode
OpenSSL
Para compilar, ejecute build.cmd en Windows, o build.sh en Linux y macOS desde la raíz. Si no quiere ejecutar
pruebas, ejecute build.cmd -t:Compile o ./build.sh -t:Compile . Para compilar la CLI en macOS Sierra, debe
ejecutar export DOTNET_RUNTIME_ID=osx.10.11-x64 para establecer la variable de entorno DOTNET_RUNTIME_ID.
Usar la compilación
Use el ejecutable dotnet de artifacts/{os}-{arch}/stage2 para probar la CLI que acaba de crear. Si quiere usar la
salida de compilación al invocar a dotnet desde la consola actual, también puede agregar artifacts/{os}-
{arch}/stage2 a la ruta de acceso.

Vea también
Entorno de ejecución .NET
.NET Core CLI Developer Guide (Guía para desarrolladores de la CLI de .NET Core)
Empaquetado de distribución de .NET Core
Empaquetado de distribución de .NET Core
20/01/2020 • 12 minutes to read • Edit Online

Como .NET Core está disponible cada vez en más plataformas, resulta útil aprender cómo empaquetarlo,
nombrarlo y versionarlo. De esta manera, los mantenedores de paquetes pueden ayudar a garantizar una
experiencia coherente, independientemente de dónde los usuarios elijan ejecutar .NET. Este artículo resultará útil
para los usuarios que:
Intentan compilar .NET Core desde el origen.
Desean realizar cambios en la CLI de .NET Core que pueden afectar a la distribución o a los paquetes
generados resultantes.

Diseño de disco
Cuando se instala, .NET Core consta de varios componentes que están dispuestos tal y como se indica a
continuación en el sistema de archivos:

{dotnet_root} (*)
├── dotnet (1)
├── LICENSE.txt (8)
├── ThirdPartyNotices.txt (8)
├── host (*)
│ └── fxr (*)
│ └── <fxr version> (2)
├── sdk (*)
│ ├── <sdk version> (3)
│ └── NuGetFallbackFolder (4) (*)
├── packs (*)
│ ├── Microsoft.AspNetCore.App.Ref (*)
│ │ └── <aspnetcore ref version> (11)
│ ├── Microsoft.NETCore.App.Ref (*)
│ │ └── <netcore ref version> (12)
│ ├── Microsoft.NETCore.App.Host.<rid> (*)
│ │ └── <apphost version> (13)
│ ├── Microsoft.WindowsDesktop.App.Ref (*)
│ │ └── <desktop ref version> (14)
│ └── NETStandard.Library.Ref (*)
│ └── <netstandard version> (15)
├── shared (*)
│ ├── Microsoft.NETCore.App (*)
│ │ └── <runtime version> (5)
│ ├── Microsoft.AspNetCore.App (*)
│ │ └── <aspnetcore version> (6)
│ ├── Microsoft.AspNetCore.All (*)
│ │ └── <aspnetcore version> (6)
│ └── Microsoft.WindowsDesktop.App (*)
│ └── <desktop app version> (7)
└── templates (*)
│ └── <templates version> (17)
/
├── etc/dotnet
│ └── install_location (16)
├── usr/share/man/man1
│ └── dotnet.1.gz (9)
└── usr/bin
└── dotnet (10)

(1) dotnet: el host (también conocido como "muxer") tiene dos roles diferentes: activar un entorno de
ejecución para iniciar una aplicación y activar un SDK para enviarle comandos. El host es un ejecutable nativo (
dotnet.exe ).

Aunque hay un único host, la mayoría del resto de componentes está en directorios con versión (2,3,5,6). Esto
significa que puede haber varias versiones en el sistema ya que se instalan en paralelo.
(2) host/fxr/<versión de fxr> : contiene la lógica de resolución del marco que usa el host. El host usa la
versión más reciente de hostfxr que está instalada. Hostfxr es responsable de seleccionar el entorno de
ejecución adecuado cuando se ejecuta una aplicación de .NET Core. Por ejemplo, una aplicación compilada
para .NET Core 2.0.0 utiliza el runtime de 2.0.5 cuando esté disponible. De forma similar, hostfxr selecciona
el SDK adecuado durante el desarrollo.
(3) sdk/<versión sdk> : el SDK (también conocido como "las herramientas") es un conjunto de
herramientas administradas que se usan para escribir y compilar aplicaciones y bibliotecas de .NET Core. El
SDK incluye la interfaz de línea de comandos (CLI) de .NET Core, los compiladores de lenguajes
administrados, MSBuild y las tareas y los destinos de compilación asociados, NuGet, nuevas plantillas de
proyecto, etcétera.
(4) sdk/NuGetFallbackFolder: contiene una caché de paquetes NuGet que un SDK usa durante la
operación de restauración, como cuando se ejecuta dotnet restore o dotnet build . Esta carpeta solo se
usa antes de .NET Core 3.0. No se puede compilar desde el origen, porque contiene recursos binarios
compilados previamente desde nuget.org .

La carpeta shared contiene marcos. Un marco compartido proporciona un conjunto de bibliotecas en una
ubicación central para que las puedan usar diferentes aplicaciones.
(5) shared/Microsoft.NETCore.App/<versión del entorno de ejecución> : este marco contiene el
entorno de ejecución de .NET Core y compatibilidad con las bibliotecas administradas.
(6) shared/Microsoft.AspNetCore.{App,All}/<versión de aspnetcore> : contiene las bibliotecas de
ASP.NET Core. Las bibliotecas de Microsoft.AspNetCore.App se desarrollan y se admiten como parte del
proyecto de .NET Core. Las bibliotecas de Microsoft.AspNetCore.All son un superconjunto que también
contiene bibliotecas de terceros.
(7) shared/Microsoft.Desktop.App/<versión de aplicación de escritorio> : contiene las bibliotecas de
escritorio de Windows. Esto no se incluye en plataformas que no son de Windows.
(8) LICENSE.txt,ThirdPartyNotices.txt: son las licencias .NET Core y de bibliotecas de terceros que se
usan en .NET Core.
(9,10) dotnet.1.gz, dotnet: dotnet.1.gz es la página manual de dotnet. dotnet es un vínculo simbólico al
host(1) de dotnet. Estos archivos se instalan en ubicaciones bien conocidas para la integración del sistema.
(11,12) Microsoft.NETCore.App.Ref,Microsoft.AspNetCore.App.Ref: describe la API de una versión
x.y de .NET Core y de ASP.NET Core respectivamente. Estos paquetes se utilizan al compilar para esas
versiones de destino.
(13) Microsoft.NETCore.App.Host.<rid> : contiene un binario nativo para la plataforma rid . Este
binario es una plantilla cuando se compila una aplicación de .NET Core en un archivo binario nativo para
esa plataforma.
(14) Microsoft.WindowsDesktop.App.Ref: describe la API de la versión x.y de las aplicaciones de
escritorio de Windows. Estos archivos se usan al compilar para ese destino. Esto no se proporciona en
plataformas que no son de Windows.
(15) NETStandard.Library.Ref: describe la API x.y de netstandard. Estos archivos se usan al compilar
para ese destino.
(16) /etc/dotnet/install_location: es un archivo que contiene la ruta de acceso completa a {dotnet_root}
. La ruta de acceso puede terminar con una nueva línea. No es necesario agregar este archivo cuando la raíz
es /usr/share/dotnet .
(17) templates: contiene las plantillas que usa el SDK. Por ejemplo, dotnet new busca plantillas de
proyecto aquí.
Varios paquetes usan las carpetas marcadas con (*) . Algunos formatos de paquete (por ejemplo, rpm )
requieren un tratamiento especial de esas carpetas. El mantenedor de paquetes debe encargarse de esto.

Paquetes recomendados
El control de versiones de .NET Core se basa en los números de versión [major].[minor] del componente del
entorno de ejecución. La versión del SDK usa el mismo valor [major].[minor] y tiene un valor [patch]
independiente que combina la semántica de la característica y la revisión del SDK. Por ejemplo: la versión 2.2.302
del SDK es la segunda versión de revisión de la tercera versión de características del SDK que admite el
runtime 2.2. Para obtener más información sobre el funcionamiento del control de versiones, vea .NET Core
versioning overview (Introducción al control de versiones de .NET Core).
Algunos de los paquetes incluyen parte del número de versión en su nombre. Esto permite instalar una versión
concreta. No se incluye el resto de la versión en el nombre de la versión. Esto permite al administrador de
paquetes del sistema operativo actualizar los paquetes (por ejemplo, instalar automáticamente correcciones de
seguridad). Los administradores de paquetes compatibles son específicos de Linux.
A continuación se enumeran los paquetes recomendados:
dotnet-sdk-[major].[minor] : instala el SDK más reciente del runtime concreto.
Versión: <versión de runtime>
Ejemplo: dotnet-sdk-2.1
Contiene: (3),(4)
Dependencias: dotnet-runtime-[major].[minor] , aspnetcore-runtime-[major].[minor] ,
dotnet-targeting-pack-[major].[minor] , aspnetcore-targeting-pack-[major].[minor] ,
netstandard-targeting-pack-[netstandard_major].[netstandard_minor] ,
dotnet-apphost-pack-[major].[minor] y dotnet-templates-[major].[minor]
aspnetcore-runtime-[major].[minor] : instala un runtime concreto de ASP.NET Core.

Versión: <versión aspnetcore de runtime>


Ejemplo: aspnetcore-runtime-2.1
Contiene: (6)
Dependencias: dotnet-runtime-[major].[minor]
dotnet-runtime-deps-[major].[minor] (Opcional) : instala las dependencias para ejecutar aplicaciones
independientes.
Versión: <versión de runtime>
Ejemplo: dotnet-runtime-deps-2.1
Dependencias: dependencias específicas de la distribución
dotnet-runtime-[major].[minor] : instala un runtime concreto.

Versión: <versión de runtime>


Ejemplo: dotnet-runtime-2.1
Contiene: (5)
Dependencias: dotnet-hostfxr-[major].[minor] y dotnet-runtime-deps-[major].[minor]
dotnet-hostfxr-[major].[minor] : dependencia.
Versión: <versión de runtime>
Ejemplo: dotnet-hostfxr-3.0
Contiene: (2)
Dependencias: dotnet-host
dotnet-host : dependencia.

Versión: <versión de runtime>


Ejemplo: dotnet-host
Contiene: (1), (8), (9), (10), (16)
dotnet-apphost-pack-[major].[minor] : dependencia.
Versión: <versión de runtime>
Contiene: (13)
dotnet-targeting-pack-[major].[minor] : permite establecer como destino un runtime que no sea el más
reciente.
Versión: <versión de runtime>
Contiene: (12)
aspnetcore-targeting-pack-[major].[minor] : permite establecer como destino un runtime que no sea el más
reciente.
Versión: <versión aspnetcore de runtime>
Contiene: (11)
netstandard-targeting-pack-[netstandard_major].[netstandard_minor] : permite establecer como destino una
versión de netstandard.
Versión: <versión de sdk>
Contiene: (15)
dotnet-templates-[major].[minor]

Versión: <versión de sdk>


Contiene: (15)
dotnet-runtime-deps-[major].[minor] requiere el conocimiento de las dependencias concretas de distribución.
Dado que el sistema de compilación de distribución puede derivar esto de forma automática, el paquete es
opcional, en cuyo caso estas dependencias se agregan directamente al paquete dotnet-runtime-[major].[minor] .
Cuando el contenido del paquete se encuentra en una carpeta con versión, el nombre del paquete
[major].[minor] coincide con el nombre de la carpeta con versión. En todos los paquetes, excepto en
netstandard-targeting-pack-[netstandard_major].[netstandard_minor] , esto también coincide con la versión de
.NET Core.
Las dependencias entre paquetes deben usar un requisito de versión igual o mayor que. Por ejemplo,
dotnet-sdk-2.2:2.2.401 requiere aspnetcore-runtime-2.2 >= 2.2.6 . Esto hace posible que el usuario actualice su
instalación mediante un paquete raíz (por ejemplo, dnf update dotnet-sdk-2.2 ).
La mayoría de las distribuciones requieren que todos los artefactos se compilen desde el origen. Esto tiene algún
impacto en los paquetes:
Las bibliotecas de terceros de shared/Microsoft.AspNetCore.All no se pueden compilar fácilmente desde el
origen. Por tanto, se omite esa carpeta en el paquete aspnetcore-runtime .
La carpeta NuGetFallbackFolder se rellena con artefactos binarios desde nuget.org . Debe permanecer
vacía.
Es posible que varios paquetes dotnet-sdk proporcionen los mismos archivos para la carpeta
NuGetFallbackFolder . Para evitar problemas con el administrador de paquetes, estos archivos deben ser idénticos
(suma de comprobación, fecha de modificación, etc.).

Compilar paquetes
El repositorio dotnet/source-build proporciona instrucciones sobre cómo crear un paquete tarball de origen del
SDK de .NET Core y todos sus componentes. La salida del repositorio de compilación de código fuente coincide
con el diseño que se describe en la primera sección de este artículo.
project.json y Visual Studio 2015 con .NET Core
23/10/2019 • 2 minutes to read • Edit Online

El 7 de marzo de 2017, la documentación de .NET Core y ASP.NET Core se actualizó para la versión de Visual
Studio 2017. En la versión anterior de la documentación se usaba Visual Studio 2015 y las herramientas de versión
preliminar en función del archivo project.json.
La versión de la documentación anterior a la actualización del 7 de marzo está disponible en un archivo PDF y en
una rama del repositorio de documentación.

Documentación PDF
La mejor fuente de la documentación anterior es .NET Core: PDF para project.json y Visual Studio 2015.

Rama del repositorio de documentación


Puede ver la versión anterior de la documentación en el repositorio, pero muchos vínculos no funcionarán y
muchos fragmentos de código son referencias que no se expanden.
.NET Core: rama de project.json del repositorio de documentación

Versión actual de la documentación


Documentación de .NET Core
Documentación de ASP.NET Core

También podría gustarte