ASP.NET Core, nuevo modelo de configuración

Hello world!

Con la llegada de core a nuestras vidas, una de las cosas que mas “choca” es ver que ya no tenemos web.config. Con lo que lo mas normal es que nos asalten varias dudas, como por ejemplo: ¿Donde configuro ahora mi cadena de conexión a la base de datos? o ¿Dónde puedo poner todas mis keys de configuración de mi web?…

La respuesta es simple: HELLO appsettings.json!! En el momento que estamos en el mundo del desarrollo, dominado por las “apis” y los “jsons”, el viejo modelo de XML por el que se regía el web.config (trabajaba como un diccionario Key-Value) se ha quedado obsoleto, con lo que Microsoft con la llegada de ASP.NET core se ha decidido por un nuevo sistema de configuración para nuestras aplicaciones basado en un json, que como ya sabéis, es menos pesado, mas legible y sobre todo mas estructurado.

Hecha esta breve introducción, vamos al tema. Lo primero que nos vamos a encontrar en nuestra nueva aplicación en core es un appsettings.json el cual tendrá el siguiente formato:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Smtp": {
    "Server": "0.0.0.1",
    "User": "nfanjul@pasiona.com",
    "Pass": "123456789",
    "Port": "25"
  }
}

Como podéis ver, ya le he incluido una configuración para un servidor smtp, en este post nos centraremos en como recoger estos valores desde nuestra aplicación.

Lo primero que deberemos hacer es crearnos un modelo con las propiedades que hemos puesto en nuestra configuración, este modelo será donde se mapearán los valores que hayamos configurado en nuestro appsettings.json:

public class Smtp
    {
        public string Server { get; }
        public string User { get; }
        public string Pass { get; }
        public int Port { get; }
    }

El siguiente paso será irnos a la clase startup y en su constructor añadir nuestro appsettings.json: 

public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

En este código podemos ver varias cosas interesantes:

  • Parámetro “optional”: Aquí podremos decir si el appsettings.json es obligatorio o no.
  • Parámetro “reloadOnChange”: Especificaremos si queremos que se recargue la aplicación cuando hagamos cambios en los settings.
  • Segundo “addJsonFile”: ahí podríamos tener un segundo settings para la gestión de nuestros settings locales, y dado que la ejecución de este constructor es secuencial machacaría el appsettings.json principal con nuestros settings locales. Esto nos facilitará el poder tener conexiones a nuestras bases de datos locales. Gestionar esto desde el web.config era un poco í ya q tendríamos que utilizar el famoso “Templating” que tantos dolores de cabeza nos dio en su momento. Por otro lado, al ser opcional no pasará nada si no existe, pudiendo así no tenerlo subido a nuestro repositorio de código.

Continuemos… Una vez visto esto, queda realmente ver como leemos ese appsettings.json. Cuando trabajábamos con el web.config tirábamos de la clase ConfigurationManager , ahora en core también tendremos un helper para cargar esto y poder tenerlo accesible desde todo el ciclo de vida de la aplicación sin tener que utilizar librerías de terceros para el tratamiento de json (ej: Newtonsoft). Para ello en la misma clase startup tendremos el método ConfigureServices  desde el cual podremos resolver la carga de nuestros settings de la siguiente manera:

public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
            services.Configure<Smtp>(Configuration.GetSection("Smtp"));
        }

Donde le especificaremos:

  • <Smtp>: Nuestro modelo de datos creado para estos settings.
  • Configuration.GetSection(“Smtp”): al GetSection le pasaremos nombre de la propiedad del json que queremos cargar.

Con habéis podido ver, esta nueva forma de tener nuestros settings es mucho mas limpia, ya que podríamos crearnos tantas secciones como quisiéramos para poder tener agrupados todos los settings por funcionalidad.

Con esto y un bizcocho… Saludos y hasta pronto!

Anuncios
ASP.NET Core, nuevo modelo de configuración

Métodos de Extensión, pon un “this” en tu desarrollo

Hello world!

¿Cuantas veces nos ha pasado que tenemos que agregar funcionalidad a un tipo ya existente? O peor aún ¿que pasa si tenemos que modificar algo también existente que no sabemos que repercusiones tendrá? y ¿si tenemos que mapear entre objetos? Estas y algunas otras preguntas son las que intentaré destripar en este post.

Vamos con un poquito de literatura, ¿Qué son los métodos de extensión? Según la msdn:

Los métodos de extensión permiten “agregar” métodos a los tipos existentes sin crear un nuevo tipo derivado, recompilar o modificar de otra manera el tipo original. Los métodos de extensión son una clase especial de método estático, pero se les llama como si fueran métodos de instancia en el tipo extendido.

Esta muy bien la definición, pero no acabo de ver esto de los métodos de extensión, ni como aplicarlo a mi código… Y si os digo .ToString()string.IsNullOrWhiteSpace(xxxx), y muchos otros que seguro que habéis utilizado millones de veces y no os habíais parado a pensar que esa funcionalidad “extra” de los tipos que la nos proporciona el propio framework de .NET, podríamos aplicarla a nuestros tipos…

Empezaremos declarando la  clase Phone:

public class Phone
    {
        public Guid Id { get; set; }
        public string SerialNumber { get; set; }
        public string Model { get; set; }
        public string Description { get; set; }
        public List Properties { get; set; }
    }

En esta clase lo primero que se me ocurre es querer validar si tiene informadas Properties  o no… ya que a la larga tendremos que hacer mil veces la validación de si tiene registros, con la típica doble validación de if(phone.Properties != null && phone.Properties.Count > 0). la verdad que ese if metido en cada uno de los sitios desde donde tengamos que utilizar nuestra clase Phone no es demasiado “elegante”. ¿Como resolveríamos esto de una forma mas elegante? pues extendiendo nuestra clase de la siguiente manera:

public static class PhoneExtension
    {
        public static bool HasProperties(this Phone source)
        {
            if (source.Properties != null && source.Properties.Count > 0)
                return true;
            else
                return false;
        }
    }

Es esta clase podemos ver 2 puntos clave, uno es que la clase tiene que ser estática, y el otro es el this que ponemos en el parámetro del método, este especifica para que tipo va a funcionar este método, es decir, este método pertenece al tipo “xxxx”.

Otra de las cosas para las que se puede utilizar esto, es para el mapeo entre diferentes tipos, por ejemplo para convertir tu dto a tu viewModel. Vale si, me diréis que actualmente ya hay librerías como AutoMapper que me lo hace “automaticamente”, pongo esto entre comillas porque efectivamente te lo hace “automaticamente” siempre y cuando cumpla la convención de nombres… Pero eso no siempre es así, o incluso hay veces que nos va a interesar tener un control mas exhausto del mapeo. Veamos un ejemplo:

En este caso nos crearemos una clase PhoneDto que tendrá solamente 2 propiedades que serán las que tengamos que transportar entre capas:

public class PhoneDto
{
      public string SerialNumber { get; set; }
      public string Description { get; set; }
}

Dentro de la misma clase estática que nos habíamos creado previamente, podemos incluir algo como esto:

public static PhoneDto ToPhoneDto(this Phone source)
{
      if (source == null) return null;
      var result = new PhoneDto();
      result.Description = source.Description;
      result.SerialNumber = source.SerialNumber;
      return result;
}

Y con esto ya tendríamos nuestro mapper implementando, simplemente extendiendo nuestro modelos de datos.

Por ultimo quedaría ver como utilizarlo. Pues es tan simple como nombre del objeto “punto” y esto ya nos mostrará el intelligence (OJO, hay que añadir el using*) con todas las extensiones/propiedades que tenga nuestro objeto!

extension
Intelligence VS mostrando la extensión

Hasta VS 2015, se tenia que añadir el using a mano… pero a partir de esta versión, con la combinación de teclas “Ctrl + .” ya te sabe reconocer y proponer tus propias extensiones para importarlas como using.

Espero que os resulte útil!

Un saludo y hasta pronto!

Métodos de Extensión, pon un “this” en tu desarrollo

Resumen 2016

Hello world!

Después de mucho tiempo sin escribir, o mejor dicho, sin poner nada nuevo, ya que las entradas de este sitio vienen de un blog anterior, tengo la intención de volver a escribir. No penséis que durante este tiempo he estado parado… nada mas lejos de la realidad, si que he estado parado en términos literarios pero no en “faranduleo”, definiendo “faranduleo” como el acto de ponerse delante de “x” personas para explicarles cositas… vamos, lo que viene siendo dar charlas! Esto es algo que me hacia especial ilusión hacer, el hecho de poder transmitir pero “face to face”, nada de hacerlo escupiendo 4 palabras en un blog!

Acreditación Codemotion 2016
Acreditación Codemotion 2016

Todo esto del “faranduleo” empezó un día cualquiera, hace ya un año, en una conversación de café… Conseguí “engañar” a mi compañera Carmen para embarcarnos en esta nueva aventura. Después de mil horas de preparación, nervios, tensión y montones de sensaciones inexplicables, el resumen es el siguiente:

Si a esto sumamos una formación que impartí para mis compis de Pasiona sobre MVC… Cerramos el año con 9 eventos! Quizá ahora entendáis un poco mejor el porque he tenido olvidado el tema del blog…

Equipo [T] en Codemotion 2016
Equipo [T] en Codemotion 2016

Y este es el resumen de 2016 a nivel de “faranduleo”. Ahora toca descansar, centrarme en el blog y encarar 2017 con ganas y fuerzas renovadas!

Os dejo en enlace a todas las slides de las charlas –> Aquí

Saludos y hasta pronto!

Resumen 2016

MVC: ActionLink a otro controlador #MERGE

Hello world,

Desarrollando una de mis primeras paginas con MVC, me he encontrado con el problema de tener que hacer una llamada a un controlador distinto al que tiene mi vista. Como seguramente todos sabéis, para hacer la llamada a la misma vista es tan simple como muestro en el siguiente ejemplo:

@Html.ActionLink("TextoDelLink", "NombreDelAction", "NombreDelControlador", new { id = item.id })

Con esto ya tendríamos creado nuestro link a una nueva vista, siempre y cuando esta esté dentro del mismo controlador. Ahora bien, si lo que necesitamos es llamar a una de vista de otro controlador, seria suficiente con añadir un parámetro mas, el valor de este parámetro seria null, quedando de la siguiente manera:

@Html.ActionLink("TextoDelLink", "NombreDelAction", "NombreDelControlador", new { id = item.id }, null)

Para los no puestos en materia, explicaré cada uno de los parámetros:

  • TextoDelLink: Este es el texto que se muestra en el link.
  • NombreDelAction: Nombre del Action que hemos creado en nuestro controlador.
  • NombreDelControlador: Nombre del la clase del controlador.
  • new { id = item.id }: Lista de parámetros que queremos pasar a la nueva vista.

Con estas líneas tendremos montados nuestros links a otras vistas, tanto del mismo controlador, como de distinto controlador.

MVC: ActionLink a otro controlador #MERGE

Arquitectura DDD y sus capas #MERGE

Hello world,

Con este post pretendo hacer una breve introducción al tipo de arquitectura DDD y explicar la funcionalidad de cada una de sus capas. No entraré en demasiados detalles técnicos, para eso ya existen libros donde profundizar mucho más en este tipo de arquitectura.

¿Qué es DDD (Domain Driven Design)?

Es un tipo de arquitectura de software orientada a dominio (ámbito para el cual estamos desarrollando la aplicación), donde éste es el que se encargará de guiar el desarrollo del software. El objetivo principal es conseguir tener un modelo de dominio rico y que vaya creciendo poco a poco con las nuevas implementaciones.

¿Qué es el Dominio?

El dominio es donde se definen los procesos y las reglas de negocio de nuestra aplicación, es decir, es donde se define la funcionalidad de la aplicación.

Capas de arquitectura DDD.

Antes de nada pongamos un simple diagrama de capas en las que se divide:

ddd1

Un ejemplo de distribución de las capas en el Visual Studio seria el siguiente:

ddd2

Ahora pasaremos a explicar cada una de las capas empezando por la parte superior:

  1. UserInterface: Esta será nuestra capa de presentación. Aquí pondremos nuestro proyecto MVC, ASP, o lo que utilicemos como front-endde nuestra aplicación.
  2. Application: Esta capa es la que nos sirve como nexo de unión de nuestro sistema. Desde ella se controla y manipula el domain. Por ejemplo, dada una persona se requiere almacenar información de un hijo que acaba de nacer. Esta capa se encargará de: llamar a los repositorios del domainpara obtener la información de esa persona, instanciar los servicios del domain y demás componentes necesarios, y por ultimo persistir los cambios en nuestra base de datos.

En esta capa también crearíamos interfaces e implementaciones para servicios, DTOs, etc, en caso de que fuese necesario.

  1. Domain: En domain podemos ver que hay 3 proyectos:
    3.1   Entities: En el cual tendremos nuestras entidades. Es decir, es una clase donde se definen los atributos de la entidad.

    Una entidad tiene una clave que es única y la diferencia de cualquier otra entidad. Por ejemplo, para una clase Persona, podríamos tener los siguientes atributos: Nombre, Apellidos y fecha de nacimiento, en ellos tendríamos la información para la clase Persona.

    Una entidad no sólo se ha de ver como una simple clase de datos, sino que se ha de interpretar como una unidad de comportamiento, en la cual, además de las propiedades antes descritas, debe tener métodos como por ejemplo Edad(), el cual a través de la fecha de nacimiento tiene que ser capaz de calcular la edad. Esto es muy importante, ya que si las entidades las utilizamos simplemente como clases de datos estaremos cayendo en el antipatrón de modelo de datos anémico.

 3.2  Domain: En este proyecto tendremos los métodos que  no se  ciñen a una entidad, sino que lo hacen a varias. Es decir, operaciones que engloben varias entidades.

3.3  Repositories: Aquí expondremos la colección de métodos que  consumiremos desde nuestra capa aplication. En los repositories se va a instanciar las entidades de nuestro dominio, pero no las implementa. Para eso ya tenemos la capa de infrastructure. Por ejemplo New, Update, Delete

  1. Infrastructure: Esta será la capa donde implementaremos repositorios, es decir, donde estarán las querys que ejecutaremos sobre la base de datos.

Espero haber “introducido” en esta arquitectura a gente que nunca haya trabajado con ella, y sobre todo, haber dejado claro la responsabilidad de cada una de las capas.

Arquitectura DDD y sus capas #MERGE

La importancia de “perder” el tiempo en realizar un correcto analisis de base de datos #MERGE

Como os comenté en la presentación, lo primero que haré será publicar las entradas que tengo en el blog que tenía antes. Estas entradas las marcaré con el tag #MERGE.

Este post va orientado a la importancia que tiene en un proyecto el realizar un buen análisis de la estructura de nuestra base de datos, tablas, naming de campos, claves, índices, etc…

La base de datos, hablando en términos de construcción, son los cimientos de la casa, si no tenemos unos buenos cimientos la casa se puede venir abajo, y tampoco vamos a empezar a construir el tejado sin haber hecho previamente los cimientos. Lo más sencillo para todo developer cuando tiene que crear una base de datos es ponerse a “picar” los create table sin haber realizado un profundo análisis de necesidades, lo cual provoca que en un corto plazo de tiempo tengas que cambiar la base de datos, desencadenando una serie de daños colaterales como pueden ser tener que cambiar las consultas, el modelo de datos de tu arquitectura, etc. Está claro, que la base de datos es una de las partes más vivas en la primera parte de desarrollo un proyecto, y que con el tiempo ésta va cambiando porque surgen nuevas necesidades, o cosas que en primer momento pensaste hacer de una cierta manera y cuando te pones a implementarlas te das cuenta que estabas equivocado.

Otro de los puntos clave en el análisis es ver las tablas que realmente necesitamos para nuestra aplicación. Tendemos a querer meter tablas para todo, muchas veces con un simple Id-Descripción que después consumimos desde una sola tabla, pero que cuando queremos obtener los datos tenemos que hace costosas joins en nuestras consultas. Este punto daría para hablar largo y tendido, ya que si somos “políticamente correctos” meteríamos tablas relacionales para todo, pero que después funcionalmente lo único que provocarían sería un desarrollo de la aplicación más lento y costoso. Así que como en todo, los extremos no son buenos, es decir, ni una tabla con 1000 campos donde está  toda la información, ni 1000 tablas con un solo campo.

El punto más dispar que me he encontrado en mi carrera profesional, es el naming de las tablas y de los campos de la base de datos. He encontrado de todo, pero principalmente 2 modelos:

  1. El equipo de desarrollo decide una nomenclatura para los campos.
  2. Se  ponen los nombres de lo que hace referencia cada cosa, siempre siguiendo unos patrones predefinidos.

El punto 1 está muy bien siempre y cuando la rotación en el equipo sea nula (algo muy difícil por no decir imposible), ya que todo el mundo estará familiarizado con dicha nomenclatura, pero desde mi punto de vista puede tener varios inconvenientes: uno seria la rotación de miembros, ya que a la que se incorporaran nuevos componentes, estos tendrían un tiempo de adaptación a esta nomenclatura. Esto podría solucionarse documentando todos y cada uno de los campos y tablas de la base de datos, pero el proyecto tendría que asumir un coste adicional para crear dicha documentación. Pero no todo es malo, esta manera de hacer los naming en la base de datos es buena si un “tercero” accede a nuestra base de datos, ya que este no sabría a qué hace referencia cada campo (tema complicado ya que se “supone” que los servidores donde se alojan las bases de datos de las aplicaciones “deben” proporcionarnos la seguridad de que nadie puede acceder a ellos. Pero esta es la teoría…).

El punto 2 facilita la compresión de nuestra base de datos, ya que de un simple vistazo se puede identificar cada campo. Pero como dije arriba, siempre hay que seguir unos patrones, y un idioma. No puede ser que haya campos que sean en inglés, otros en castellano, etc. Por ejemplo en cada tabla que tengamos un “ID”, éste debe llamarse de la misma forma, no en unos sitios “id” a secas, en otros “Idxxxx”, “xxxxId”, etc. También otra buena práctica es poner en los campos que sean “foreing key” el nombre de la tabla a la que hace referencia. Por ejemplo si tenemos 2 tablas “Country” y “Currency”, el nombre del campo foreing key de la tabla Country debería de ser “CountryId”.

Otro tema al cual no le solemos prestar mucha atención es los tipos de datos de los campos. Aquí hay que tener varias cosas en cuenta:

  1. Si necesitamos 10 caracteres para almacenar un valor, NO ES NECESARIO utilizar un varchar(MAX). El impacto en el rendimiento es significante si sólo hay un campo de ese tipo, pero puede convertirse en un problema cuando TODOS son así.
  2. Campos índices: SQL Server nos proporciona el tipo “autonumérico”, el cual nos facilita el trabajo a los desarrolladores, pero tiene 2 inconvenientes. Uno que ese ID no es único en nuestra base de datos, con lo que no podríamos decir que un Id identifica un objeto concreto, y en cuanto al rendimiento, es más rápido para la inserción, pero más lento para la lectura (en  esto último tengo mis dudas), con lo que la solución para los campos ID es crearlo del tipo uniqueidentifier.
Una vez tengamos nuestra base de datos creada, hay otros aspectos que debemos tener muy en cuenta si queremos ganar rendimiento en nuestra futura aplicación. El principal  es crear índices en nuestras tablas (no voy a entrar en cómo crearlos, ya q no es el objetivo de este post), ya que con esto se puede ganar muchísimo tiempo al realizar las consultas. Esto es algo que a primera vista piensas que no tiene por qué influir en el tiempo que emplea el motor de base de datos en devolvernos la consulta, pero en realidad tener unos buenos índices creados sobre nuestras tablas puede marcar la diferencia de tu aplicación respecto a otras. Y otro de los puntos donde se puede mejorar el rendimiento es en la manea de crear nuestra programación en la base de datos. Por ejemplo, en los “procedimientos almacenados” todos acostumbramos a crearlos como una query  que hace lo que tenga que hacer y listo, pero si en vez de hacerlo así creamos la query como un string y la ejecutamos con un sp_executesql, esto hace que la primera vez que se ejecute el procedimiento almacenado sí que pueda ser más lento, pero las siguientes ejecuciones irá mucho más rápido ya que la query se quedará cacheada en el plan de ejecución del motos de base de datos. Esto último es muy útil cuando por ejemplo tenemos que ejecutar un procedimiento almacenado varias veces.

En conclusión, se podría decir que una de las principales cosas que hacen que un proyecto vaya bien o vaya mal es el tiempo invertido en el análisis y creación de la base de datos. Una estructuración clara y simple de la base de datos hace que nuestra arquitectura de proyecto sea más simple, con lo que será más fácil de desarrollar y sobre todo de mantener en un futuro.

 

La importancia de “perder” el tiempo en realizar un correcto analisis de base de datos #MERGE

Presentación…

Hello world,

Después de un tiempo apartado del mundo de los blogs, me ha vuelto a picar el gusanillo de volver a escribir. Lo primero que haré será traspasar las entradas de mi viejo blog a este.

Una vez hecho esta breve introducción, me voy a presentar. Soy Nacho Fanjul, Senior developer en tecnología .NET en el departamento de proyectos de Pasiona, llevo en este mundo de la programación casi 10 años y como os podéis imaginar me las he encontrado de todos los colores… No voy a entrar a repasar mi trayectoria profesional, para eso podéis visitar mi “LinkedIn”, sí que resumiré lo que llevo haciendo los últimos tiempos.

Me he especializado en desarrollo de aplicaciones web, desarrollando principalmente con MVC, aunque también me ha tocado “pelearme” con webForms. En cuanto a la parte de “BackEnd”, he ido acumulando experiencia en codeFirst, Entity Framework, arquitecturas DDD, etc…

Últimamente, me estoy introduciendo en el mundillo de azure, donde aún me queda un largo recorrido…

¿Qué encontrareis en este blog?

Esto es simple, iré poniendo las cosillas que me vaya encontrando en el día a día, o simplemente cosas nuevas que vaya aprendiendo.

En fin, no me enrollo más, solo deciros que espero que este blog os resulte útil, y podáis aprender algo y que yo también aprenda algo!

Saludos a tod@s!

 

Presentación…