Introduccion a ASP.NET Core - VVAA

Introducción a ASP.NET Core Luis Ruiz Pavón Unai Zorrilla Castro Eduard Tomàs Quique Martínez INTRODUCCIÓN A ASP.NET C

Views 27 Downloads 0 File size 6MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Introducción a ASP.NET Core Luis Ruiz Pavón Unai Zorrilla Castro Eduard Tomàs Quique Martínez

INTRODUCCIÓN A ASP.NET CORE

DERECHOS RESERVADOS © 2016, respecto a la primera edición en español, por Krasis Consulting, S. L. www.Krasis.com ISBN: 978-84-945822-2-6

CREATIVIDAD: Diseño Cubierta: Pablo Iglesias Francisco Fruta Cubierta: El aguacate es un fruto exótico carnoso que se obtiene del árbol tropical del mismo nombre. En algunas partes de América del Sur se conoce como Palta. Se cree que es originario de México, y su nombre procede del del náhuatl ahuácatl (testículo en español). Presenta unas dimensiones de 5-6 cm de longitud. El peso normal oscila entre 200-400 g. La corteza es gruesa y dura de color verde cuyo tono depende de la variedad. La pulpa es aceitosa de color crema a verde amarillento. Posee una única semilla redondeada de color pardo claro y 2-4 cm, que aparece recubierta de una delgada capa leñosa.

Agradecimientos Nunca pensé que escribir un libro llevaría tanto trabajo, más aún cuando uno no es escritor ni por vocación, ni por profesión, y además tiene que compaginarlo al mismo tiempo con su vida familiar y laboral. Así debo agradecer a mi familia la comprensión que ha tenido conmigo durante este tiempo. A mi madre Antonia, porque de no ser por ella y por sus sabios consejos no sería lo que soy y no habría podido llegar hasta aquí. A mi padre, Luis, que me ha enseñado lo importante que es trabajar duro y nunca tirar la toalla en los momentos duros. A mi mujer Natalia, porque la debo todo en esta vida, porque sin ella yo no soy nada y porque me ha regalado lo más bonito de esta vida, mis 2 hijas, Paula y Martina. A mis hermanas Rocío, Vero y Ana, que son un pilar fundamental en mi vida. A mis sobrinos Ciro, Javier, Candela y Alejandro. A mis cuñados Miguel, JJ y Arse por cuidar de mis hermanas. A mis suegros Pilar y Manolo y a mi cuñada Ruth, por quererme como uno más en la familia y por su ayuda incondicional. A Unai, por ofrecerme la oportunidad de formar parte de este libro. Luis Ruiz Pavón Hace ya un tiempo que pensé que nunca más tendría que pasar por el trance de escribir un prólogo de un libro. Después de hacer este trabajo diversas veces las ganas de enfrentarme a un folio en blanco habían desaparecido. No tenía demasiadas ilusiones por escribir sobre versiones 5, 6, 7 de un producto ya conocido en que me parecía estar repitiendo continuamente lo mismo. Sin embargo, hace ya unos meses, entre mis compañeros de libro y yo pensamos que tanto .NET Core como ASP.NET Core 1 eran lo suficientemente motivantes como lanzarnos de nuevo a esta aventura. Nuevas cosas

que enseñar y sobre todo aprender, porque escribiendo un libro se aprende un montón de cosas. De nuevo, mucha gente de la comunidad aquí en España está involucrada en esta nueva versión del producto, sobre la que nosotros ahora escribimos, una comunidad llena de tiburones que crean mucho contenido y comparten en muchos grupos de usuarios sus experiencias y lecciones aprendidas. Para esta comunidad de tiburones va dedicado este libro, para que sigan luchando contra los rapes, para que sigan creciendo, para que sigan disfrutando con lo que hacen y sigan haciéndonos disfrutar a los demás. Por supuesto este libro se lo dedico también a mi mujer e hija, a las cuales no hago más que robarles tiempo para estas aventuras. ¡¡Gracias!! Para finalizar este libro está dedicado también a todos mis compañeros de Plain Concepts, compañeros con los que aprendo todos los días. Unai Zorrilla Castro A Neus y Noa que, a pesar de sufrir mi falta de tiempo, nunca han dejado de animarme. Sin ellas no hubiera sido posible. Eduard Tomàs i Avellana La verdad es que este es el primer prólogo que escribo y espero que no sea el último. Esta experiencia me ha servido para saber lo duro que es enfrentarse a una hoja en blanco y para que me entren ganas de querer afrontar esta aventura de nuevo. Desde pequeño he tenido una gran virtud, siempre he sabido rodearme de gente mejor que yo para mejorar todo lo posible y esta vez no iba a ser diferente. Por el ello lo primero que me gustaría es dar las gracias a Unai, Luis y Eduard por dejarme aportar un pequeño granito de arena en esta aventura llamada libro. Sobre todo, a Unai que ha orquestado todo esto para que tengamos este libro con nosotros. Tengo la suerte de no solo compartir con ellos esta aventura, sino que comparto el día a día de mi trabajo y siempre es un placer trabajar con gente como ellos. El día a día, cuando tu trabajo y tu pasión se unen siempre se lo tienes que agradecer a los que te rodean, ya que al final son ellos los que sacrifican muchas cosas para estemos involucrados en lo que muchas veces nos gusta llamarle comunidad. Por ello quiero dar las gracias a mis padres Manuel y Donilia que me han dado todo lo necesario y los valores para ser quien soy a día de hoy. A Sheila que es la persona con la que he decidido empezar un viaje juntos llamado vida y es la que ve como semana a semana tengo que hacer una maleta y arrancar un iv

viaje para participar en eventos o por trabajo ya que como ella dice esto es lo que te hace feliz. A mi familia y familia política que siempre están ahí cuando los he necesitado. Y por último a Plain Concepts, la empresa que no solo me ha hecho crecer como profesional, sino que me ha hecho ser mejor persona y me ha dado muchos momentos a recordad durante estos años. Por todo esto y más ¡muchas gracias! Quique Martínez

Contenido AGRADECIMIENTOS ............................................................................................... III CONTENIDO ............................................................................................................VII AUTORES ................................................................................................................ XIII PRÓLOGO ................................................................................................................ XV CAPÍTULO 1: INTRODUCCIÓN A .NET CORE 1.0...........................................19 1.- ¿Por qué .NET CORE? ............................................................................................................. 19 2.- .NET standard Library y .NET standard platform ............................................................. 20 3.- ¿Qué es .NET CORE? .............................................................................................................. 24 3.1.- CoreFx.............................................................................................................................. 28 3.2.- CoreCLR ........................................................................................................................ 29 3.3.- CoreRT ............................................................................................................................ 29 3.4.- CLI 31 3.4.1.- El comando new ..................................................................................................... 32 3.4.2.- El comando restore............................................................................................... 32 3.4.3.- El comando run ...................................................................................................... 34 3.4.4.- El comando build.................................................................................................... 35 3.4.5.- El comando test...................................................................................................... 37 3.4.6.- El comando pack .................................................................................................... 39 3.4.7.- El comando publish................................................................................................ 40 3.5.- Instalación de .NET Core SDK .................................................................................. 41 3.5.1.- Instalación en Windows ....................................................................................... 42 3.5.2.- Instalación en Linux ............................................................................................... 48 3.5.3.- Instalación en MacOS............................................................................................ 51 3.5.4.- Instalación de Dotnet en Docker ...................................................................... 54 CAPÍTULO 2: INTRODUCCIÓN A ASP.NET CORE 1.0 ...................................65 1.- Introducción................................................................................................................................ 65 1.1.- Estructura de una aplicación ASP.NET Core ......................................................... 67 1.1.1.- Global.json ............................................................................................................... 74 1.1.2.- Project.json .............................................................................................................. 75 1.1.3.- La carpeta wwwroot ............................................................................................. 83 1.2.- Anatomía de una aplicación ASP.NET Core ........................................................... 87 1.3.- Desarrollando ASP.NET Core con dotnet watch ................................................. 88

viii Introducción a ASP.NET Core

CAPÍTULO 3: STARTUP..........................................................................................93 1.- Introducción................................................................................................................................ 93 1.1.- El constructor ................................................................................................................. 94 1.2.- El método Configure..................................................................................................... 95 1.3.- El método ConfigureServices ..................................................................................... 96 1.4.- Servicios disponibles ..................................................................................................... 97 2.- Configuraciones por entorno................................................................................................. 98 2.1.- Development .................................................................................................................. 99 2.2.- Staging ............................................................................................................................. 100 2.3.- Production ..................................................................................................................... 100 2.4.- Las variables de entorno ............................................................................................ 100 2.4.1.- Variables de entorno en Windows ................................................................. 101 2.4.2.- Variables de entorno en Linux ......................................................................... 104 2.4.3.- Variables de entorno en OS X ......................................................................... 105 2.5.- Convenciones de configuración ............................................................................... 106 2.5.1.- Determinando el entorno en tiempo de ejecución .................................... 106 2.5.2.- Convenciones de la clase Startup .................................................................... 108 CAPÍTULO 4: MIDDLEWARES ............................................................................111 1.2.3.4.-

Introducción.............................................................................................................................. 111 Los métodos run, map y use ................................................................................................ 113 Creando nuestro primer middleware ................................................................................ 118 Middlewares comunes ............................................................................................................ 122 4.1.- Uso de ficheros estáticos........................................................................................... 122 4.1.1.- Manejo de errores y páginas de excepción ................................................... 124

CAPÍTULO 5: ASP.NET CORE MVC ...................................................................127 1.- Introducción a Core MVC .................................................................................................... 127 1.1.- De MVC5 a Core MVC.............................................................................................. 128 1.1.1.- Creando el controlador ..................................................................................... 129 1.1.2.- Creando la vista.................................................................................................... 130 1.1.3.- Novedades de Razor........................................................................................... 131 1.2.- La tabla de rutas ........................................................................................................... 132 2.- Model Binding ........................................................................................................................... 134 2.1.- Model Binding en MVC5 ............................................................................................ 134 2.2.- Model Binding en WebAPI 2..................................................................................... 138 2.3.- Model binding en Core MVC.................................................................................... 142 2.3.1.- Model Binding sin usar [FromBody] ................................................................ 143 2.3.2.- Model binding usando [FromBody] ................................................................. 145 2.3.3.- Personalizando el model binding...................................................................... 146 2.3.4.- Creando un model binder propio ................................................................... 146 2.3.5.- Creando un input formatter propio ............................................................... 148 2.4.- Validación del modelo ................................................................................................ 150 2.4.1.- Validación por atributos..................................................................................... 151 2.4.2.- Validación usando IValidatableObject ............................................................. 151 viii

Contenido ix

3.- Creación de APIS HTTP ........................................................................................................ 153 3.1.- Negociación de contenido......................................................................................... 153 3.1.1.- Action Results....................................................................................................... 153 3.1.2.- Devolver datos en un formato específico ..................................................... 155 3.1.3.- Devolver datos a través de negociación de contenido .............................. 156 3.1.4.- Output formatters ............................................................................................... 156 3.1.5.- Limitar los formatos de salida........................................................................... 158 3.1.6.- Output formatters predefinidos ...................................................................... 160 3.2.- Enrutamiento ................................................................................................................ 161 3.2.1.- El atributo Route.................................................................................................. 161 3.2.2.- Comodines en las plantillas de la URL ........................................................... 163 3.2.3.- Valores de ruta ..................................................................................................... 164 4.- Tag Helpers ............................................................................................................................... 165 4.1.- Uso de tag helpers existentes .................................................................................. 167 4.1.1.- Form tag helper .................................................................................................... 168 4.1.2.- Input tag helper .................................................................................................... 168 4.1.3.- Textarea tag helper ............................................................................................. 170 4.1.4.- Label tag helper .................................................................................................... 170 4.1.5.- Select tag helper ................................................................................................... 171 4.1.6.- Image tag helper ................................................................................................... 174 4.1.7.- Environment tag helper ...................................................................................... 174 4.1.8.- Link tag helper ...................................................................................................... 175 4.1.9.- Script tag helper ................................................................................................... 177 4.1.10.- Tag helpers de validaciones......................................................................... 177 4.2.- Creación de tag helpers ............................................................................................. 178 4.2.1.- Creando un tag helper sencillo ........................................................................ 179 4.2.2.- Añadir atributos al tag helper ........................................................................... 180 4.2.3.- Respetando los atributos existentes ............................................................... 181 4.2.4.- Procesando el contenido ................................................................................... 182 4.2.5.- Un tag helper repetidor ..................................................................................... 184 5.- View Components y vistas parciales .................................................................................. 185 5.1.- Vistas parciales en Core MVC ................................................................................ 187 5.1.1.- Ubicación de vistas parciales............................................................................. 187 5.1.2.- Paso de datos a las vistas parciales .................................................................. 188 5.1.3.- Inyección de dependencias en vistas ............................................................... 188 5.2.- View Components....................................................................................................... 189 5.2.1.- Creación de View Components....................................................................... 189 5.3.- Invocación de View Components............................................................................ 191 CAPÍTULO 6: TRABAJANDO CON DATOS .....................................................193 1.- Introducción.............................................................................................................................. 193 2.- Creando un modelo................................................................................................................ 194 3.- Configuraciones personalizadas ........................................................................................... 198 3.1.- OnModelCreating ........................................................................................................ 198 3.2.- Configuraciones individuales ..................................................................................... 200 4.- Nuevos elementos de Modelado......................................................................................... 201 4.1.- Identidad......................................................................................................................... 201

x Introducción a ASP.NET Core

4.1.1.- Identidad y secuencias ........................................................................................ 202 4.1.2.- Hilo .......................................................................................................................... 203 4.2.- Shadow Properties y Backing Fields ........................................................................ 204 4.3.- Claves alternativas o restricciones únicas ............................................................. 208 5.- Consulta y manipulación de datos....................................................................................... 209 5.1.- Evaluación de consultas en cliente .......................................................................... 210 5.2.- Consultas Raw .............................................................................................................. 212 6.- Testing ........................................................................................................................................ 213 6.1.- InMemory....................................................................................................................... 213 6.2.- SQLite InMemory ........................................................................................................ 215 CAPÍTULO 7: AUTENTICACIÓN Y AUTORIZACIÓN EN ASP.NET CORE 1.0................................................................................................................................217 1.2.3.4.-

Introducción.............................................................................................................................. 217 ASP.NET Core autenticación y autorización .................................................................. 218 ASP.NET Core identity ......................................................................................................... 225 Autorización en ASP.NET Core .......................................................................................... 238 4.1.- Autorización simple..................................................................................................... 238 4.2.- Autorización basada en roles.................................................................................... 239 4.3.- Autorización basada en claims.................................................................................. 242 4.4.- Autorización basada en políticas personalizadas ................................................. 244 4.5.- Autorización basada en recursos............................................................................. 248

CAPÍTULO 8: CONFIGURACIÓN .......................................................................253 1.- Introducción.............................................................................................................................. 253 2.- Configuration............................................................................................................................ 255 2.1.- Almacenes de configuración ..................................................................................... 256 2.1.1.- JSON ....................................................................................................................... 257 2.1.2.- INI ............................................................................................................................ 260 2.1.3.- XML ......................................................................................................................... 261 2.1.4.- Secretos de usuario............................................................................................. 262 2.1.5.- Variables de entorno........................................................................................... 264 2.2.- Tipado de la configuración ........................................................................................ 265 2.3.- Fuentes de configuración personalizadas ............................................................... 268 CAPÍTULO 9: LOGGING .......................................................................................271 1.- Introducción.............................................................................................................................. 271 2.- Logging........................................................................................................................................ 271 2.1.- ILoggerFactory.............................................................................................................. 272 2.2.- Proveedores por defecto, Console / Debug ........................................................ 273 2.2.1.- Utilizando el servicio de configuración........................................................... 273 2.2.2.- Debug Window .................................................................................................... 274 2.3.- Serilog ............................................................................................................................. 275 2.3.1.- Serilog y Seq .......................................................................................................... 277 2.4.- Escribiendo nuestras trazas....................................................................................... 278 x

Contenido xi

2.4.1.- Usando ILoggerFactory como dependencia .................................................. 278 2.4.2.- Utilizando ILogger ................................................................................................ 279 2.5.- Proveedores de log personalizados ........................................................................ 279 CAPÍTULO 10: GLOBALIZACIÓN Y LOCALIZACIÓN ..................................283 1.- Introducción.............................................................................................................................. 283 2.- Detección de la cultura .......................................................................................................... 284 2.1.- QueryStringRequestCultureProvider ..................................................................... 286 2.2.- AcceptLanguageHeaderRequestCultureProvider ................................................ 288 2.3.- CookieRequestCultureProvider .............................................................................. 289 2.4.- Proveedores de cultura personalizados ................................................................. 290 2.5.- Localizando nuestro contenido ................................................................................ 291 CAPÍTULO 11: CACHING .....................................................................................299 1.- Introducción.............................................................................................................................. 299 2.- Caché .......................................................................................................................................... 300 2.1.- IMemoryCache ............................................................................................................. 300 2.1.1.- ICacheEntry ........................................................................................................... 301 2.1.2.- Usando IMemoryCache...................................................................................... 302 2.2.- IDistributedCache........................................................................................................ 303 2.2.1.- SQL Server como caché distribuida................................................................ 304 2.2.2.- Redis como caché distribuida ........................................................................... 306 3.- Response cache ........................................................................................................................ 306 4.- Output cache ............................................................................................................................ 310 CAPÍTULO 12: PUBLICAR APLICACIONES ASP.NET CORE ......................313 1.- Introducción.............................................................................................................................. 313 2.- Publicar Internet Information Services (ISS) ..................................................................... 315 2.1.- Configuración de IIS .................................................................................................... 315 2.2.- Instalación de .NET Core Windows Server Hosting ......................................... 317 2.3.- Configuración de nuestra aplicación ASP.NET Core ......................................... 318 2.4.- Creación de nuestro sitio web................................................................................. 320 2.5.- Configuración de Data Protection .......................................................................... 323 2.6.- Despliegue de la aplicación ........................................................................................ 324 3.- Publicar en un contendor Docker ...................................................................................... 332 4.- Publicar en un servidor linux ................................................................................................ 340 4.1.- Instalación y configuración Nginx ............................................................................ 340 4.2.- Monitorizando nuestra aplicación............................................................................ 344 5.- Despliegue continuo en Azure con VSTS ......................................................................... 347 ÍNDICE ANALÍTICO ...............................................................................................357

Autores Luis Ruiz Pavón Desarrollador por vocación y, desde hace 15 años, dedicado de manera profesional al mundo del desarrollo de software. Ha trabajado con multitud de tecnologías y lenguajes, aunque en los últimos 10 años se ha centrado sobre todo en tecnologías Microsoft. Es Most Valuable Professional desde 2012 en la categoría de ASP.NET. Es co-fundador del grupo de usuarios de Madrid MsCoders, cuyo objetivo principal es el de servir como lugar de encuentro y reunión quincenal donde se debatan y compartan temas técnicos especialmente relacionados con tecnologías Microsoft. Trabaja en Plain Concepts. Unai Zorrilla Castro Lleva cerca de 15 años desarrollando software como consultor independiente y en diversas empresas privadas, realizando las tareas de arquitectura de software bajo plataforma .NET y tocando distintas ramas tecnológicas. Autor de varios libros y ponente habitual en conferencias de desarrollo, colabora activamente con la comunidad, con la que le gusta estar en permanente contacto. Ha sido galardonado con el reconocimiento MVP de Microsoft en diversas categorías desde el año 2006. Es socio fundador y Development Team Leader en Plain Concepts. Eduard Tomàs i Avellana Eduard Tomás es ingeniero informático y atesora más de 12 años de experiencia como desarrollador. Está especializado en desarrollo de aplicaciones web y móviles. Mantiene un blog sobre desarrollo en general y ASP.NET MVC en particular en http://geeks.ms/etomas. Colabora con la comunidad impartiendo charlas presenciales, en formato webcast y en eventos de distintos grupos de usuarios. Hace de su pasión su profesión desarrollando en Plain Concepts. Quique Martínez Alén Un apasionado de la arquitectura de software y del Cloud Computing (en concreto Microsoft Azure), ha sido nombrado Microsoft MVP de esta tecnología durante los últimos 4 años, y además pertenece a los Azure Insiders. Le encanta ser ponente en eventos técnicos y colaborar todo lo posible en comunidades de desarrollo. Actualmente tiene el placer de trabajar en Plain Concepts. xiii

CAPÍTULO

1

Introducción a .NET Core 1.0

¿Te imaginas poder crear aplicaciones .NET para Windows, Linux y Mac con un editor multiplataforma y con un conjunto de herramientas adaptadas al desarrollo moderno de aplicaciones? ¿Suena muy bien verdad? Pues eso ya es real. Ahora .NET Core es Open Source, multiplataforma y abre nuevos escenarios para todos los desarrolladores .NET.

1.- ¿POR QUÉ .NET CORE? Ha pasado mucho tiempo desde que Microsoft liberó la primera versión de .NET Framework allá en el año 2002. Desde entonces, millones de desarrolladores lo hemos usado, desde la versión 1.0 hasta la más actual (.NET Framework 4.6), para construir aplicaciones de todo tipo, aplicaciones para escritorio con Winforms y WPF, aplicaciones web usando WebForms y más tarde MVC, aplicaciones para todo tipo de dispositivos, desde los Windows Mobile con .NET Compact Framework hasta aplicaciones para tabletas con Windows 8. Pero la industria del desarrollo de software está en continuo cambio, y desde entonces han aparecido muchos frameworks de desarrollo nuevos para hacerle la competencia. Por otra parte, .NET Framework es un entorno muy maduro para el desarrollo de aplicaciones empresariales pero con una serie de limitaciones que no pueden cambiar sino se rompe con el pasado: 

Soporte solo para plataformas Windows (Microsoft no daba soporte para Mono). 19

20 Introducción a ASP.NET Core



Framework monolítico.



Ciclos de lanzamiento muy largos (2 años) debido a su naturaleza monolítica.



Mayor consumo de memoria.

Además de todos estos puntos que hemos citado, otro de los problemas actuales derivados de .NET Framework tiene que ver con las instalaciones. Como seguramente sabrás, es un requisito previo que antes de ejecutar cualquier aplicación .NET Framework en una máquina, tengamos instalada la versión correspondiente de .NET Framework. Y debemos tener mucho cuidado con las actualizaciones que hagamos, pues podríamos romper otras aplicaciones que ya se están ejecutando en producción. Si una nueva versión de .NET Framework es liberada y queremos utilizar esta nueva versión para un nuevo desarrollo y aprovechar las nuevas características que traiga consigo, una vez terminado nuestro desarrollo, tendremos que proveer o instalar antes la nueva versión de .NET Framework. Y es algo conocido en el mundo del desarrollo de software que o somos dueños y señores de nuestros servidores o si por el contrario trabajamos en una empresa o para un cliente que tiene un departamento de IT, no actualizará a la ligera las máquinas a la nueva versión de .NET sin antes realizar algún tipo de laboratorio experimental para ver que nada afecta a lo que ya existe y está funcionando en producción. Así pues, debido a todos los cambios que se han efectuado en .NET Core a nivel de arquitectura, disponemos de un framework mucho más modular y ligero, que consume menos memoria y aprovecha mejor los recursos. Otro punto no menos importante es la multiplataforma, ya que puede ejecutarse en Linux, MacOS y Windows. Así pues, podemos afirmar que .NET Core es el futuro, fruto de la innovación y el esfuerzo por parte de Microsoft para ofrecernos a los desarrolladores las mejores herramientas adaptadas para el desarrollo moderno.

2.- .NET STANDARD LIBRARY Y .NET STANDARD PLATFORM Cuando .NET Framework se liberó, los desarrolladores no teníamos muchos problemas, sólo había una versión de .NET 1.0 y poco más. Al cabo de no mucho tiempo, Microsoft liberó .NET Compact Framework, que era una copia reducida de .NET Framework lista para poder ejecutarse en dispositivos con capacidad reducida, específicamente en Windows Mobile. A partir de ese momento, los desarrolladores tuvimos que empezar a lidiar con múltiples versiones fragmentadas de .NET Framework para las distintas plataformas, pasando por Silverlight, Windows Phone y Windows

Introducción a .NET Core 1.0 21

Store. Cada una de estas plataformas es un subconjunto de .NET Framework, de tal manera que tiene su propio runtime, su propio framework y su propio modelo de desarrollo. Y claro está, las múltiples versiones de cada uno de estos frameworks, hacían que los desarrolladores de bibliotecas tuvieran que crear varios proyectos diferentes para cada versión. Desde el punto de vista del desarrollador no ha sido una tarea sencilla tener que lidiar con toda esta problemática. Piensa en la cantidad de veces que probablemente has tenido que usar en tú código directivas de compilación, o archivos linkeados entre proyectos (por ejemplo cuando necesitabas compartir código entre aplicaciones WPF y Silverlight) para poder reutilizar el máximo código entre diferentes plataformas, y por lo tanto no tener que mantener código duplicado, (que al final lo único que introduce es ruido en el mantenimiento a la par que eleva el coste). Si a todo esto se le suma la aparición de .NET Core y la compra de Xamarin por parte de Microsoft, el panorama actual que nos queda es algo como el que se muestra en la siguiente imagen:

Figura 1.- Estado actual del mundo .NET

Tanto .NET Framework como .NET Core comparten muchos componentes: los lenguajes (C#/VB.NET), el compilador Roslyn, el compilador JIT encargado de convertir el código IL a código nativo de 32 y 64 bits (RyuJIT), el recolector de basura, etc. Para paliar un poco esta problemática y hacernos la vida algo más fácil a los desarrolladores, Microsoft creó la Biblioteca de clases portables o PCL. Se trata de un nuevo tipo de proyecto incluido en Visual Studio, que nos permite crear aplicaciones multiplataforma y bibliotecas de una manera rápida y sencilla para garantizar portabilidad binaria entre diferentes modelos de aplicación.

22 Introducción a ASP.NET Core

Figura 2.- Podemos elegir las plataformas de destino en las que compartirán este código.

Su funcionamiento se basa en ofrecer a los desarrolladores un contrato común para todas las plataformas que elijamos usando un único proyecto. De esta forma nos aseguramos de que estamos desarrollando código que se ejecutará para todas las plataformas de destino. Para ello, se crea un perfil de compilación, que es una combinación de plataformas que comparten un API común. Cuando estas bibliotecas portables se empaquetan en NuGet, se expresan como un conjunto de frameworks estáticos, por ejemplo portable-net45+win8. Esto describe la intención de que queremos ejecutarlo en .NET Framerwork 4.5 y Windows 8.0. El problema de esta aproximación radica en que los perfiles son estáticos e inmutables en el tiempo, es decir, si aparece una nueva versión de .NET, por ejemplo la 4.5.1 que es un súper conjunto de .NET 4.5, a priori no debería haber ningún problema y debería funcionar nuestra biblioteca, pero en la práctica no es así. En Visual Studio estaban todas esas definiciones de perfiles, por lo que no permitía llamar a un método que estaba en .NET tradicional y en Windows Phone no. Para solucionar este problema, Microsoft ha decidido crear lo que se conoce con el nombre de .NET Standard Library. Podemos ver la .NET Standard Library como la siguiente generación de evolución de las PCL, ya que como similitud podríamos decir

Introducción a .NET Core 1.0 23

que ambas definen APIs que pueden ser usadas para compartir código entre diferentes plataformas, pero existe una serie de diferencias. En este caso la .NET Standard Library no se vincula a un conjunto de plataformas, sino a una versión de .NET Standard. Es lo que se conoce con el término anglosajón “open-ended” o básicamente, que no están ligadas a una lista estática de monikers como las bibliotecas portables, por ejemplo portable-a+b+c. En este caso aparece un nuevo moniker llamado netstandard, así pues cuando desarrollemos una biblioteca no vamos a vincularla a ese conjunto estático, sino que lo vincularemos a una versión de netstandard. Para entender su funcionamiento, fíjate en la siguiente imagen:

Figura 3.- Correspondencia de .NET Platform Standard con otras plataformas.

Si nuestra biblioteca apunta a la versión 1.3 de .NET Platform Standard, quiere decir que solo podrá ejecutarse de .NET 4.6 en adelante, en .NET Core, en Universal Windows Platform y en Mono/Xamarin. Además nuestra biblioteca puede consumir bibliotecas de versiones 1.0, 1.1 y 1.2 de .NET Platform Standard.

24 Introducción a ASP.NET Core

En la siguiente imagen se muestra cómo encaja .NET Standard Library y .NET Platform Standard en el panorama actual de .NET:

Figura 4.- .NET Standard Library y .NET Platform Standard.

Para entender todo esto desde un punto de vista más práctico, unos de los arquitectos de .NET Core y ASP.NET ha creado este fragmento de código https://gist.github.com/davidfowl/8939f305567e1755412d6dc0b8baf1b7 donde explica la relación de la NET Standard Library, las APIs soportadas y las diferentes plataformas. Así pues, te recomendamos que le eches un vistazo detenidamente.

3.- ¿QUÉ ES .NET CORE? .NET Core es la implementación multiplataforma y de código abierto de .NET. Fue impulsado desde un principio por los equipos de producto de .NET, CLR y ASP.NET, que tenían la necesidad de reescribir este framework desde cero con el objetivo de que fuese un framework ligero y rápido para ejecutarse en la tanto onpremise como en la nube y crear aplicaciones web modernas, microservicios, bibliotecas de clases y aplicaciones de consola que se puedan ejecutarse en Windows, Linux y MacOS. Al contrario que .NET tradicional, el cual se instala a través de un solo paquete de instalación de unos 400 Mb y solo dispone de runtime para ejecutarse en Windows (sin contar con Mono), esta nueva implementación está totalmente desacoplada de Windows, pudiendo ejecutarse en otros sistemas operativos como Linux y MacOS. Es totalmente modular y permite al desarrollador añadir solo aquellos componentes que su aplicación necesita con el plus añadido de poder desplegar el framework junto con la aplicación, lo que posibilita escenarios side-by-side donde diferentes aplicaciones que utilizan versiones de framework diferentes, conviven sin afectarse las unas a las otras y evitando problemas en las actualizaciones de las mismas.

Introducción a .NET Core 1.0 25

.NET Core se instala de manera diferente a como estábamos acostumbrados, en vez de ser parte del S.O, .NET Core se instala a través de paquetes de NuGet y es distribuido junto con la aplicación, que es la que tiene la responsabilidad de desplegarlo posibilitando el escenario side-by-side con las ventajas que ello conlleva. A continuación puedes ver cuáles son los modelos de programación soportados en .NET Core 1.0:

Figura 5.- Modelos de aplicación soportados en .NET Core 1.0

.NET Core consiste en una máquina virtual o como se conoce en el idioma anglosajón Common Language Runtime y que en .NET Core se llama CoreCLR. NET Core también se compone de un conjunto de bibliotecas modulares base, CoreFx también llamado .NET Core Framework. Esto permite al desarrollador incluir solo aquellas bibliotecas que son necesarias sin necesidad de sobrecargar nuestra aplicación y no incorporar aquello que no necesitamos. También está formado por un conjunto de herramientas de línea de comandos multiplataforma conocidas como .NET CLI (dotnet). Además, como alternativa a CoreCLR, disponemos también de CoreRT, que es otra máquina virtual optimizada para escenarios AOT (Ahead Of time Compilation) y que más adelante veremos con más detenimiento y conoceremos su importancia. Además de todos estos proyectos, .NET Core también se apoya en los compiladores Roslyn y LLILC. Los principales valores de NET Core son: 

Multiplataforma: actualmente NET Core está soportado en los tres principales sistema operativos: Linux, Windows y OS X. Hay otros sistemas operativos

26 Introducción a ASP.NET Core

como FreeBSD y Alpine donde .NET Core está siendo portado, pero no están oficialmente soportadas. Las aplicaciones deben ser recompiladas por entorno, lo que hace que se puedan ejecutar de manera nativa. 

Código abierto: el código fuente de .NET Core está disponible en GitHub con licencia MIT y Apache 2. La dirección es https://github.com/dotnet/core.



Adquisición natural: .NET Core se distribuye principalmente de 2 maneras. Como paquetes de NuGet, como un conjunto de paquetes NuGet que los desarrolladores pueden escoger y elegir a su gusto. El runtime y las bibliotecas base pueden ser descargadas desde NuGet usando los gestores de paquetes específicos de casa sistema operativo, como APT, Homebrew y Yum. También están disponibles imágenes de Docker en el hub de Microsoft. (sobre Docker veremos un apartado de instalación específico).



Framework modular: .NET Core ha sido diseñado para ser modular, permitiendo al desarrollador incluir las bibliotecas de .NET Core y las dependencias que va a necesitar. Cada aplicación decide qué versión de .NET Core va a utilizar evitando así conflictos con componentes compartidos. Este tipo de aproximaciones se alinean perfectamente con el desarrollo de software usando contenedores Docker.



Compatibilidad: .NET Core es compatible con .NET Framework, Xamarin y Mono vía .NET Standard Library.



Soporte: es de código abierto y permite que la comunidad pueda participar y está totalmente soportado por Microsoft.

Con .NET Core podemos desplegar nuestras aplicaciones de dos formas: 1. Framework-dependent deployment (FDD): como su nombre indica, son aplicaciones que dependen de que .NET Core esté instalado en la máquina donde vayamos a ejecutar/desplegar nuestra aplicación, esto hace que nuestra aplicación sea portable entre las diferentes versiones de .NET Core. Las aplicaciones portables sólo contiene nuestro código y dependencias con librerías de terceros. Las principales ventajas de este tipo de aplicaciones son: 

No tenemos que definir con antelación los sistemas operativos en los que queremos que nuestra aplicación se pueda ejecutar.



El tamaño de nuestra aplicación es más reducido, pues no tenemos que instalar .NET Core, sólo código y dependencias con bibliotecas de terceros.

Introducción a .NET Core 1.0 27



Múltiples aplicaciones usarán la misma instalación de .NET Core, lo cual se traduce en un ahorro de espacio en disco y memoria de nuestros servidores.

Pero existen algunas desventajas con este tipo de aplicaciones: 

Nuestra aplicación solo podrá ejecutarse con la versión de .NET Core que hayamos especificado o para una superior si ha sido instalada en la máquina donde vayamos a ejecutarla.



Puede ser que el runtime de .NET Core o las bibliotecas de CoreFX cambien sin nuestro conocimiento en futuros lanzamientos y en casos extraños, nuestra aplicación se comporte de manera diferente.

2. Self-contained deployment (SCD): al contrario que las aplicaciones FDD, no dependen de que .NET Core esté instalado en la sistema de destino. A parte del código y de las bibliotecas de terceros, incluyen tanto el runtime de .NET Core como las bibliotecas de .NET Core. Esto hace que nuestras aplicaciones SCD estén aisladas completamente de otras aplicaciones .NET Core. Esto hace que el tamaño de nuestra aplicación crezca sobre las portables, pero también hace que el despliegue sea mucho más sencillo porque no importa que la máquina de destino tenga o no instalado .NET Core. La desventaja frente a las portables es que tenemos que especificar por adelantado en el fichero project.json en qué plataformas se ejecutará nuestra aplicación. Las principales ventajas de elegir este tipo de aplicaciones son: 

Tenemos en todo momento control total sobre la versión de .NET Core que se instala en el sistema.



Nos aseguramos siempre que nuestra aplicación se ejecutará en el sistema de destino, pues nuestra aplicación provee el framework sobre el que se tiene que ejecutar.

Al igual que las FDD existen alguna serie de desventajas: 

Como NET Core se despliega junto con nuestra aplicación, deberemos especificar con anterioridad cuáles son los sistemas operativos en los que queremos ejecutar nuestra aplicación.



El tamaño de nuestra aplicación es mayor que en el las FDD, al tener que incluir .NET Core.



Si desplegamos muchas aplicaciones de tipo SCD en un mismo sistema, el consumo de disco crecerá, pues cada aplicación despliega una versión de .NET Core.

28 Introducción a ASP.NET Core

Una vez visto que es .NET Core y que tipos de despliegues existen, vamos a ver cuáles son los cuatro pilares de .NET Core:

Figura 6.- Los 4 pilares de .NET Core

Todos estos proyectos son de código abierto, por lo que se puedes consultar su código fuente y contribuir a través de GitHub: https://github.com. En cada uno de los apartados iremos viendo cuáles son las urls de cada uno de los repositorios de código fuente.

3.1.- CoreFx https://github.com/dotnet/corefx

CoreFx o .NET Core Libraries es la biblioteca de clases base de .NET Core. Incluye System.Collections, System.IO, System.Xml, y otros muchos espacios de nombres fundamentales. Al contrario que en .NET Framework que todo era monolítico, CoreFx ha sido diseñada de manera modular basándose en paquetes de NuGet. Cada uno de sus componentes es un paquete de NuGet que puede ser instalado en solitario junto con sus dependencias. La ventaja de que el framework esté basado en paquetes NuGet, es que diferentes áreas del framework pueden ir evolucionando más rápidamente y a diferentes velocidades, comparado con el tradicional .NET framework, que tenía releases completos mucho más pesados y las áreas más lentas de evolución podrían frenar la rápida evolución de otras áreas del framework Hay una parte conocida como “mscorlib” (Microsoft Common Object Runtime Library) donde residen los tipos base de .NET Core, entre los que se encuentran String, Int, DateTime y otros muchos más que puede ver en el siguiente enlace https://github.com/dotnet/coreclr/tree/master/src/mscorlib. Este código vive en el

Introducción a .NET Core 1.0 29

repositorio de CoreCLR porque debe ser desarrollado y versionado junto con el runtime .NET. El resto de CoreFx es agnóstico de la implementación del runtime, lo que quiere decir que puede ejecutarse en cualquier .NET runtime compatible.

3.2.- CoreCLR https://github.com/dotnet/coreclr

CoreCLR (Common Language Runtime) es el nuevo runtime multiplataforma de .NET Core. El CLR es la máquina virtual de .NET que se encarga de leer el código IL (Lenguaje intermedio) generado por el compilador Roslyn y hace uso del compilador “Just-In-Time” (JIT) para convertirlo en lenguaje máquina específico para el sistema operativo y la CPU sobre la que se está ejecutando. El compilador JIT que está usando es RyuJIT, que es un compilador de 64 bits de nueva generación que Microsoft liberó en 2015 y que es el doble de rápido. Incluye características de bajo nivel como el recolector de basura (GC) que es el encargado de liberar los objetos de memoria que ya no son usados por nuestras aplicaciones. Dentro de este proyecto podemos encontrar mscorlib (Microsoft Common Object Runtime Library) que contiene los tipos de más bajo nivel (string, struct, int, etc.) y que son necesarios para la ejecución del runtime, de ahí que formen parte de este proyecto. Al contrario que nuestro querido .NET Framework CLR, CoreCLR es de código abierto (Licencia MIT) y multiplataforma (Linux, OS X y Windows). Otras de las ventajas de este nuevo runtime es que puede desplegarse junto con nuestra aplicación, por lo que, si lo deseamos, ya no tendremos que preocuparnos más por mensajes del tipo “Esta aplicación requiere .NET Framework X para poder ejecutarse”. Esta última característica hace posible que podamos desplegar aplicaciones side-by side, es decir, que ya no tenemos que preocuparnos más cuando trabajemos con las últimas versiones del framework y despleguemos éstas en un servidor que ya tiene ejecutándose aplicaciones con versiones anteriores porque aquéllas no se verán afectadas.

3.3.- CoreRT https://github.com/dotnet/corert

30 Introducción a ASP.NET Core

CoreRT es una alternativa a CoreCLR. Aquí probablemente te preguntes: ¿por qué otro runtime adicional a CoreCLR? Pues porque CoreRT es un runtime optimizado para escenarios AOT (Ahead Of Time compilation). A continuación, y antes de continuar, vamos a ver qué diferencias hay entre la compilación JIT y AOT para entender por qué es importante este nuevo runtime. Los compiladores JIT son responsables de convertir el código IL en código máquina nativo. Esto lo hacen mientras nuestra aplicación se está ejecutando, así que cada vez que se llama a un método de un ensamblado por primera vez, lo compilan en ese momento de ahí su nombre en inglés (Just In Time). De esta manera es posible ejecutar nuestras aplicaciones en diferentes sistemas operativos y CPUs, que claro está, tengan .NET Runtime instalado. Además, JIT se lleva tiempo de compilación y uso de CPU por lo que impacta en el rendimiento de la aplicación. Los compiladores AOT compilan el código IL a código máquina nativo, pero por el contrario, lo hacen de manera anticipada y además específica para la CPU y el sistema operativo en el que se está compilando, (ojo no confundir con ejecutando). Esto hace que podamos distribuir nuestra aplicación sin necesidad de instalar el .NET Runtime. La implementación por defecto usa RyuJIT, pero existen otros compiladores alternativos como IL-to-C++ compiler y LLILC (que se pronuncia LILAC), que está basado en la arquitectura de compiladores LLVM y, que aunque fue implementado originalmente para compilar C/C++ actualmente se usa para muchos otros lenguajes como Objective-C, Haskell, Swift, Java, y muchos otros. LLILC proveerá compilación AOT centrándose más en la optimización del código nativo generado. Las ventajas de usar compilación nativa son: 

El compilador AOT genera un único ejecutable que incluye la aplicación, las dependencias y el runtime, en este caso CoreRT.



Son más rápidas ejecutándose, el código ya está compilado y no es necesario generarlo en tiempo de ejecución (JIT).

Y por supuesto, abren nuevos escenarios que antes no disponíamos: 

Despliegues XCOPY, copiar un solo ejecutable de una máquina a otra (del mismo tipo) sin tener que instalar el .NET Runtime.



Crear y ejecutar una imagen de Docker con un único ejecutable de nuestra aplicación ASP.NET.

Introducción a .NET Core 1.0 31

3.4.- CLI https://github.com/dotnet/cli

.NET Core CLI (.NET Core Command Line Interface) es un conjunto de herramientas multiplataforma por línea de comandos que nos permite crear aplicaciones y bibliotecas con .NET Core. Es la base sobre la que otras herramientas de alto nivel, como por ejemplo los entornos integrados de desarrollo (IDEs), editores…, serán construidas. Si trabajamos con Visual Studio, el uso de CLI será bastante transparente gracias a la integración con el IDE. La CLI se instala a través del SDK de .NET Core Como cualquier otro SDK, dependiendo de nuestro escenario podemos instalarlo usando los instaladores nativos de cada sistema operativo o instalar el SDK usando los scripts de instalación. Los instaladores nativos se usan principalmente para instalar el SDK en nuestras máquinas de desarrollo. El SDK se distribuye a través de instaladores específicos para cada sistema operativo, en el caso de Ubuntu como paquetes DEB y en el caso de Windows como instaladores MSI. Cuando ejecutamos el instalador, éste se encarga de preparar el entorno por nosotros, para una vez finalizada la instalación, esté disponible para ser usado por el usuario. Esta instalación requiere privilegios de administración. Por otra parte, los scripts de instalación están pensados para desplegarse en entornos como desarrollo, staging o producción. Lo ideal para desplegar el SDK en este tipo de entornos, es automatizar todo el proceso a través de un servidor de integración continua (Jenkins, Travis, MSBuild, etc.) para evitar tener que estar haciendo una instalación atendida en cada nuevo entorno que aparezca. La instalación del SDK a través de script no necesita privilegios de administración. Por defecto, la CLI de .NET Core se instala side-by-side, lo que significa que podemos tener múltiples versiones de la CLI en nuestra máquina. A continuación se muestra la lista de comandos que vienen por defecto instalados con la CLI: 

new



restore



run



build



test

32 Introducción a ASP.NET Core



publish



pack

Seguidamente vamos a ir viendo uno por uno todos los comandos anteriores.

3.4.1.- El comando new El comando new se utiliza para crear un nuevo proyecto. dotnet new [-t/--type] [-l/--lang]

Con dotnet new vamos a poder crear un pequeño ejemplo de proyecto .NET Core para poder hacer nuestras pruebas desde la línea de comandos. Cuando ejecutamos el comando dotnet new sobre un directorio, se generan un par de ficheros: 1. Un fichero Program.cs o Program.fs (dependiendo del lenguaje que hayamos escogido) que contiene el código de ejemplo de un sencillo “Hola Mundo”. 2. Un fichero project.json. Los argumentos que recibe el comando dotnet new son: 1. -l --lang: es el lenguaje con el que se creará el proyecto. Los dos posibles valores son C# o F#. El valor por defecto es C# por lo que no será necesario especificarlo. Los valores csharp, fsharp, cs o fs son opciones válidas. 2. -t --type: es el tipo de proyecto que queremos crear. Los posibles valores son console, web, lib y xunittest. El valor por defecto es console. Un ejemplo de uso sería el siguiente: dotnet new –l f# -t web

Con esta instrucción crearemos un proyecto de tipo web con el lenguaje F#.

3.4.2.- El comando restore El comando restore se utiliza para restaurar todas las dependencias de nuestro proyecto: Dotnet restore [--source] [--packages] [--disable-parallel] [-fallbacksource] [--configfile] [--verbosity] []

Introducción a .NET Core 1.0 33

El comando dotnet restore llama a NuGet para restaurar todas las dependencias de nuestra aplicación. NuGet analiza el fichero project.json y descarga los paquetes que sean necesarios. Para restaurar dichas dependencias, NuGet necesita tener configurados unos feeds, que son donde están ubicados los paquetes. Dichos feeds suelen estar ubicados en el fichero de configuración Nuget.config; de hecho cuando instalamos la CLI se crea uno por defecto. Nosotros podemos añadir más feeds creando nuestro propio fichero Nuget.config en el directorio de nuestro proyecto, por ejemplo, un feed privado nuestro o a Myget. Los feeds también se pueden especificar por línea de comandos al comando restore. Podemos especificar el directorio donde queremos que se restauren los paquetes usando el argumento --packages. Si no lo especificamos, se usa la ubicación por defecto de NuGet que es el directorio .nuget/packges que se encuentra el directorio personal del usuario (por ejemplo, /home/user1 en sistemas operativos Linux o C:\Users\user1 en Windows). Este directorio actúa como caché local, quiere decir que NuGet buscará si existe ya un paquete en este directorio, si existe lo usará y si no lo descargará del repositorio de internet. Una vez ejecutado el comando restore, si miramos en el directorio de nuestra aplicación, descubriremos que se ha creado un nuevo fichero project.lock.json. El fichero project.lock.json contiene el conjunto de dependencias de NuGet y otra serie de información que describe nuestra aplicación. Además, este fichero es usado por otros comandos como dotnet build y dotnet run. Los argumentos que recibe el comando restore son: 1. [root]: una lista de proyectos o carpetas de proyectos para restaurar sus dependencias. La lista se puede obtener de una ruta al fichero project.json, global.json o a una carpeta. Se ejecuta de manera recursiva y para cada uno de los ficheros project.json que encuentre. 2. -s --source: podemos especificar la ubicación que se utilizará durante la restauración de dependencias. Este parámetro sobrescribirá todas las ubicaciones especificadas en el fichero Nuget.config. Podemos especificar múltiples ubicaciones especificando varias veces este parámetro. 3. --packages: sirve para especificar el directorio donde se descargarán los paquetes. 4. --disable-parallel: deshabilitar la restauración de paquetes en paralelo. 5. -f –fallbacksource: usado para indicar una o varias ubicaciones de paquetes alternativas por si la operación de restauración de dependencias falla. Podemos indicar múltiples ubicaciones definiendo varias veces este parámetro.

34 Introducción a ASP.NET Core

6. --configfile: podemos especificar la ruta del fichero Nuget.config que vamos a utilizar en la restauración. 7. --verbosity: habilitar el modo verboso al comando restore. Los valores que admite este parámetro son Debug, Verbose, Information, Minimal, Warning y Error. A continuación se muestran un par de ejemplos de uso del comando restore: dotnet restore

Esta es la ejecución por defecto. Restaura todas las dependencias para el proyecto que se encuentra en el directorio actual. dotnet restore netcoretests\project.json

Restaura todas las dependencias del proyecto netcoretests.

3.4.3.- El comando run El comando run se usa para ejecutar nuestro código fuente sin necesidad de compilar previamente. dotnet run [--framework] [--configuration] [--project] [--help] [--]

Nos permite ejecutar nuestra aplicación desde el código fuente y con un solo comando. En realidad lo que run está haciendo es compilar el código fuente si no ha sido compilado previamente o si hay cambios en el código fuente, y del resultado de dicha compilación si no hay errores, ejecuta el programa. Para la compilación usa el comando dotnet build, que compila el código fuente a un ensamblado .NET. El resultado de dicha compilación se almacena en el directorio bin, al igual que en .NET tradicional. Si dicho directorio no existe, lo crea. Por último, debemos usar dotnet run sólo en el ámbito de nuestro proyecto. Para ejecutar una dll debemos usar el driver de dotnet dotnet app.dll

Los argumentos que recibe el comando run son: 1. [--]: delimita los argumentos del propio comando de los que recibe la aplicación. Todos los argumentos que se pongan detrás de – serán los argumentos que reciba la aplicación al ejecutarse.

Introducción a .NET Core 1.0 35

2. -f –framework: especifica el framework con el que se ejecuta nuestra aplicación. 3. -c --configuration [Debug|Release]: especifica la configuración que se usará cuando se publique la aplicación. Por defecto y al igual que .NET tradicional es Debug. 4. -p --project [PATH]: podemos indicar qué proyecto queremos ejecutar. Puede ser la ruta al fichero project.json o al directorio que contiene el fichero project.json. Si no especificamos este parámetro, por defecto será el directorio actual. A continuación se muestran varios ejemplos de uso del comando run: dotnet run

Esta es la ejecución por defecto. Ejecuta el proyecto que se encuentra en el directorio actual. dotnet run --project /projects/project1/project.json

Ejecuta el proyecto que hemos especificado al parámetro project. dotnet run --project /projects/project1/project.json –configuration Release

Ejecuta el proyecto que hemos especificado en el parámetro project con la configuración de Release.

3.4.4.- El comando build El comando build compila un proyecto y todas las dependencias. dotnet build [--output] [--build-base-path] [--framework] [-configuration] [--runtime] [--version-suffix] [--build-profile] [--noincremental] [--no-dependencies] []

El comando build compila múltiples archivos de código fuente de un proyecto y todas sus dependencias en un archivo binario. Este archivo binario contiene el IL (Lenguaje intermedio) y tendrá extensión dll. El comando build necesita que previamente se haya ejecutado el comando restore y que exista el fichero project.lock.json (como ya comentamos previamente cuando vimos el comando restore). Si no existe dicho fichero, el comando nos mostrará el siguiente mensaje:

36 Introducción a ASP.NET Core

Figura 7.- Ejecución de dotnet build sin antes haber ejecutado un restore.

Antes de que el proceso de compilación comience, el comando build realiza un análisis para asegurarse de que el proyecto y todas sus dependencias cumplen con una serie de chequeos de seguridad: 

No se hace uso de scripts de pre/post compilación.



No se hace uso de herramientas de compilación tipo resgen.



Solo se usan compiladores válidos (csc, vbc, fsc).

Si queremos crear un archivo ejecutable de nuestra aplicación, necesitamos añadir una sección de configuración especial al fichero project.json: { "compilerOptions": { "emitEntryPoint": true } }

Los argumentos que recibe el comando build son: 1. -o –output: podemos especificar el directorio donde se generarán los binarios. Por defecto se generan en el directorio bin. 2. -b --build-base-path: podemos indicar el directorio donde se crearán los archivos temporales de la compilación. Por defecto se generan en el directorio obj. 3. -f --framework: compilar para un framework específico. El framework debe estar definido en el fichero project.json. 4. -c –configuration: permite especificar la configuración sobre la que queremos compilar. Si no indicamos ninguna, por defecto se compila en Debug. 5. -r --runtime: podemos precisar el runtime de destino para cual estamos compilando.

Introducción a .NET Core 1.0 37

6. --version-suffix: es posible definir el sufijo de la versión que se ha especificado con * en el fichero project.json. Este versionado se basa en la guía de estilos de versionado de NuGet. https://docs.nuget.org/create/versioning. 7. --build-profile: para especificar que se mantenga los chequeos de seguridad para poder mantener las compilaciones incrementales. Esto quiere decir, que si hemos compilado previamente y no hay cambios, dotnet build omitirá la compilación. 8. --no-incremental: con este parámetro evitamos la compilación incremental y podemos forzar la compilación de todo el grafo de dependencias de proyectos: 9.

--no-dependencies: ignora las dependencias con otros proyectos y compila el proyecto especificado como raíz.

3.4.5.- El comando test El comando test ejecuta las pruebas usando el test runner que se haya configurado. dotnet test [--configuration] [--output] [--build-base-path] [-framework] [--runtime] [--no-build] [--parentProcessId] [--port] []

El comando dotnet test se usa para ejecutar las pruebas de un proyecto. Estas pruebas son bibliotecas de clases que tienen dependencias con algún entorno de pruebas como pueden ser xUnit, Nunit, etc. y que dotnet test usa para poder ejecutarlas. Estos frameworks son paquetes de NuGet que instalan y restauran como una dependencia más del proyecto. En los proyectos de pruebas tenemos que especificar además cuál es el test Runner con el que queremos que se ejecuten las pruebas. Esto se hace a través del fichero project.json y una propiedad llamada “testRunner”. El valor de esta propiedad debe ser el nombre del entorno de pruebas unitarias. A continuación se muestra el fichero project.json con las propiedades que necesitamos: { "version": "1.0.0-*", "buildOptions": { "debugType": "portable" }, "dependencies": { "System.Runtime.Serialization.Primitives": "4.1.1", "xunit": "2.1.0",

38 Introducción a ASP.NET Core

"dotnet-test-xunit": "1.0.0-rc2-192208-24" }, "testRunner": "xunit", "frameworks": { "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0" } }, "imports": [ "dotnet5.4", "portable-net451+win8" ] } } }

El comando dotnet test soporta dos modelos de ejecución: 1. Consola: en modo consola, ejecutando el comando dotnet test nos mostrará la salida de ejecución de las pruebas. 2. Diseño: por ejemplo cuando los usemos desde los IDEs o editores ligeros. Los argumentos que recibe el comando test son: 1. [project]: podemos indicar la ruta del proyecto sobre el cual queremos ejecutar las pruebas. Si no especificamos ninguno será sobre el directorio actual. 2. -c --configuration: sirve para definir la configuración sobre la que se ejecutarán las pruebas. Si no se especifica nada, el valor por defecto es Release. 3. -o --output: permite especificar el directorio donde puede buscar los ficheros binarios para ejecutar las pruebas. 4. -b --build-base-path: podemos definir el directorio donde se generarán los archivos temporales. 5. -f --framework 6. -r --runtime 7. --no-build: se salta la fase de compilación en la ejecución de las pruebas. 8. --parentProcessId: este parámetro es usado por los IDE’s y editores ligeros para indicar su id de proceso. El test terminará si el proceso padre termina.

Introducción a .NET Core 1.0 39

9. --port: este parámetro es usado por los IDEs y editores ligeros para precisarle al test dónde está el puerto desde donde están escuchando para que pueda conectarse. A continuación se muestran un par ejemplos de uso del comando test: dotnet test

Esta es la ejecución por defecto. Ejecuta todas las pruebas del proyecto que se encuentran en el directorio actual. dotnet test /projects/project1/project.json

Ejecuta las pruebas del proyecto project1.

3.4.6.- El comando pack El comando pack empaqueta el código en un paquete de NuGet. dotnet pack [--output] [--no-build] [--build-base-path] [-configuration] [--version-suffix] []

El comando pack compila el proyecto y crea los paquetes de NuGet. El resultado de esta operación son dos paquetes con la extensión nupkg. Uno contiene el código y el otro los símbolos de depuración. Las dependencias con otros paquetes de NuGet son añadidas al fichero nuspec para que puedan ser resueltas cuando el paquete se instala. Las referencias a otros proyectos no son empaquetadas por defecto junto al proyecto que la referencia. Si queremos empaquetar dichas referencias, tenemos que especificárselo en el fichero project.json tal cual se muestra en el siguiente fragmento de código: { "version": "1.0.0-*", "dependencies": { "Project2": { "target": "project1", "type": "build" } } }

El comando dotnet pack por defecto compila siempre el proyecto. Podemos especificar que se salte el proceso de compilación cuando estamos empaquetando nuestro proyecto. Un ejemplo donde nos puede ser útil esta aproximación es en escenarios de integración continua donde sabemos que ya ha sido compilado el proyecto con anterioridad.

40 Introducción a ASP.NET Core

Los argumentos que recibe el comando pack son: 1. [project]: proyecto a empaquetar. Podemos definir la ruta del proyecto que queremos empaquetar o la ruta al fichero project.json. Si no especificamos ninguno será sobre el directorio actual. 2. -o --output: indicamos en qué directorio queremos que nos deje los paquetes de NuGet. 3.

--no-build: se salta la fase de compilación. Útil en escenarios de integración continua.

4. --build-base-path: podemos especificarle el directorio donde queremos que deje los artefactos temporales de la compilación. Si no se especifica nada, por defecto los deja en el directorio obj. 5. -c --configuration: permite indicar la configuración sobre la que queremos compilar. Si no especificamos ninguna, por defecto se compila en Debug. A continuación se muestran varios ejemplos de uso del comando pack: dotnet pack

Es la ejecución por defecto. Genera los paquetes de NuGet para el directorio actual. dotnet pack --no-build

Genera los paquetes de NuGet para el directorio actual y se salta el proceso de compilación.

3.4.7.- El comando publish El comando publish empaqueta la aplicación y todas sus dependencias en un directorio listo para su publicación: dotnet publish [--framework] [--runtime] [--build-base-path] [-output] [--version-suffix] [--configuration] []

El comando dotnet publish compila la aplicación, lee todas las dependencias establecidas en el fichero project.json y publica el resultado en un directorio. Los argumentos que recibe el comando publish son: 1. [project]: el comando dotnet publish necesita un fichero project.json para poder ejecutarse. Si no especificamos ningún fichero project.json, buscará

Introducción a .NET Core 1.0 41

un fichero project.json en el directorio actual y si no lo encuentra nos mostrará un error. 2. -f --framework: publica la aplicación para el framework que se le especifica. Si no indicamos ningún framework como parámetro, intentará leer el framework que está especificado en el fichero project.json y si no encuentra ningún framework válido lanzará un error. Si se ha especificado más de un framework válido, el comando publish hará una publicación para cada uno de estos frameworks. 3. -r --runtime: podemos especificar para qué runtime queremos publicar. 4. -b --build-base-path: permite indicar el directorio donde queremos que deje los artefactos temporales de la compilación. 5. -o --output: sirve para definir donde queremos dejar el resultado de la publicación. Si no se especifica nada, para las aplicaciones portables el directorio por defecto será ./bin/[configuration]/[framework]/ y para las aplicaciones auto contenidas será. /bin/[configuration]/[framework]/[runtime]. 6. --version-suffix: podemos definir el sufijo de la versión que se ha especificado con * en el fichero project.json. Este versionado se basa en la guía de estilos de versionado de NuGet. https://docs.nuget.org/create/versioning. 7. -c --configuration: permite especificar cuál será la configuración que queremos usar para la publicación. El valor por defecto si no se especifica nada es Debug. A continuación se muestran varios ejemplos de uso del comando publish: dotnet publish

Ejecución por defecto que publica una aplicación usando el framework que se haya establecido en el fichero project.json del directorio actual. dotnet publish ~/projects/project1/project.json

Publica la aplicación usando el fichero project.json.

....