jueves, 9 de marzo de 2017

Pruebas unitarias con Entity Framework Core

Las pruebas unitarias contra base de datos siempre son complicadas. Ya que en muchas ocasiones no podemos crear una base de datos vacía para nuestras pruebas. Si utilizamos Entity Framework esta tarea se hace muy sencilla, con este sencillo truco. En la que creamos una base de datos al inicializar el test y la borramos al terminarlo.

Para ello deberemos utilizar los métodos EnsureCreated y EnsureDeleted, las cuales crean y borran una base de datos de una forma muy sencilla.

[ClassInitialize()]
public static void InitDataBase(TestContext context)
{
    using (var db = new MyDbContext())
    {
        db.Database.EnsureCreated();
    }
}

[ClassCleanup]
public static void DeleteDataBase()
{
    using (var db = new MyDbContext())
    {
        db.Database.EnsureDeleted();
    }
}

lunes, 6 de marzo de 2017

Particionar base de datos con Entity Framework Core

Supongamos que necesitamos dar soporte a varios clientes con una única aplicación. Por ejemplo ofreciendo SAAS (Software as a service). En la que tenemos el mismo software para todos los clientes, pero sus datos son independientes. La forma más sencilla seria crear una instancia de base de datos para cada cliente. Pero esto es costoso y no siempre viable, sobretodo si tenemos muchos clientes con un volumen de datos pequeño por cliente.

Azure nos ofrece la posibilidad de crear grupos elásticos. Pero estos están limitados a un máximo de 500 bases de datos. Aunque parecen muchas, es posible que tengamos más clientes y la mayoría de ellos inactivos. Con lo que está opción no es siempre viable.

Otra forma es marcar cada registro en base de datos con un campo instancia. En el que identificamos a que cliente o instancia pertenece da registro. Teniendo que insertar y meter en todas nuestras consultas la referencia a la instancia.

Si utilizamos Entity Framework Core, estre trabajo se puede automatizar, quedando de una forma transparente para la mayoría de desarrolladores.

Al definir las entidades del modelo. Deberemos introducir un campo en el que indicaremos a que partición pertenece el registro. Para ello crearemos una "propiedad sombra" la cual nos permite enlazar a un registro de base de datos, sin la necesidad de asociarlo a un registro en nuestra entidad.

modelBuilder.Entity<Person>(entity =>
{
   entity.Property<int>("IdPartition");
});

Para hacerlo más trasparente. Nos crearemos una clase PartitionValueGenerator que herede de ValueGenerator, la cual nos permitirá generar un valor automáticamente a nuestra propiedad. Así nos evitaremos la necesidad de darle el valor, cada vez que creamos un objeto.

public class PartitionValueGenerator : ValueGenerator<int>
{
    public override int Next(EntityEntry entry)
    {
        return ((MyDbContext)(entry.Context)).IdPartition;
    }

    public override bool GeneratesTemporaryValues => false;
}

Y se lo asignaremos a nuestra propiedad

modelBuilder.Entity<Person>(entity =>
{
     entity.Property<int>("IdPartition")
         .HasValueGenerator((p, e) => new PartitionValueGenerator(););
});

Con esto ya conseguimos insertar un valor de forma transparente en nuestro registro. Ahora vamos ha definir como hacer las consultas. Para ello necesitamos definirnos una versión personalizada de DbSet. Con la que podremos modificar el objeto Expression antes de lanzar la consulta. Redefinimos la propiedad IQueryable.Expression de la siguiente forma.


public class PartitionalDbSet<TEntity, TIdPartition> : DbSet<TEntity>,
            IQueryable<TEntity>, IAsyncEnumerableAccessor<TEntity>, Infrastructure<IServiceProvider>
        where TEntity : class
{
..... 

Expression IQueryable.Expression
{
    get
    {
        Expression dbExpression = ((IQueryable)mDbSetBase).Expression;
        TIdPartition idPartition = mIdPartition;

        Expression<Func<TEntity, bool>> expresionFuncFilter = b => EF.Property<TIdPartition>(b, "IdPartition").Equals(idPartition);

        IQueryable<TEntity> source = null;
        Expression<Func<TEntity, bool>> predicate = null;

        var meth = GetMethodInfo<IQueryable<TEntity>, Expression<Func<TEntity, bool>>,
                    IQueryable<TEntity>>(new Func<IQueryable<TEntity>, Expression<Func<TEntity, bool>>, IQueryable<TEntity>>
                        (Queryable.Where<TEntity>), source, predicate);

         Expression expression = Expression.Call(null, meth, dbExpression, expresionFuncFilter);

    return expression;
    }
}

Ya solo nos queda definir los DbSet en nuestra contexto.

private DbSet<Person> mPersons;

public DbSet<Person> Persons
{
    get
    {
        if (mPersons == null)
        {
           mPersons = new PartitionalDbSet<Person, int>(base.Set<Person>(), mIdPartition);
        }
        return mPersons;
    }
}
Con esto podremos definir diferentes instancias del contexto de base de datos, para diferentes clientes o subconjuntos de datos, de una forma muy sencilla y trasparente.

using (var db = new MyDbContext(1))
{
    Person person = new Person()
    {
         Name = "Name 1",
         Description = "Description 1"
    };

    db.Persons.Add(person);
    await db.SaveChangesAsync();
}

using (var db = new MyDbContext(1))
{
     var person = await db.Persons.Where(p => p.Name.StartsWith("Name")).ToListAsync();
     Assert.IsTrue(person.Count() > 0);
}

Si os interesa este tema lo podéis explorar con más detenidamente descargado un ejemplo en:
https://github.com/andrechi1/Blog-Examples/tree/master/PartitionEFCore

lunes, 6 de febrero de 2017

Buenas practicas con Async/Await

Con la aparición de los procesadores con varios núcleos se ha vuelto critico el saber manejar la multitarea. Desde la primera versión del Framework de .Net existe el espacio de nombre System.Threading, el cual se puede considerar un wrappear para acceder a las directivas de sincronización del sistema, acceder al pool de hilos o crear nuestros propios hilos.

Posiblemente con System.Threading se puede realizar cualquier tarea. Pero la dificultad de su uso y mantenimiento han invitado a crear otro tipo de librerías más sencillas.

Primero se abordo la multitarea de CPU. Con una nueva clase para manejar tareas que es Task, un controlador llamado Parallel y una serie de clases para manejar colecciones de forma asíncrona. Esto nos permite aprovechar los diversos núcleos de los procesador actuales. Permitiendo lanzar tareas en paralelo y sincronizarlas de una forma sencilla.

Pero había un escenario que seguia siendo complicado. Y con la aparición de los entornos táctiles se empezó a ver la importancia de esto. Me refiero a la posibilidad de no bloquear ciertos recursos de la máquina.

Es importante entender la diferencia entre los dos escenarios de los que hablo. No es lo mismo la multitarea de CPU que la multitarea de IO. Y es importante entenderla bien.En este articulo nos centraremos en la multitarea de IO, o como no bloquear recursos de la máquina. Para esto a partir del Framework 4.5 se introdujeron Async/Await, que nos facilitan menormente el trabajo.

Otro concepto que hay que entender bien es el contexto de dispositivo. Los contextos de dispositivos los crea Windows y nos permiten pintar sobre la pantalla u otro dispositivo. Tanto en WinForm como WCF solo disponen de un contexto de dispositivo por aplicación. Esto significa que solo puede pintar un hilo determinado sobre la pantalla.

Una forma de invocar al contexto de dispositivo es mediante los eventos comunes, como OnClick, OnMouseMove. Todos los eventos y sobrecargas de la clase Form (en WinForm) o Window en (WPF) se invocan a traves del contexto de dispositivo. Otra forma de invocarlo es mediante el método Invoke (en WinForm) o a traves de la clase  Dispatcher en (WPF). En todos los casos hay que seguir una regla de oro. Mantener el hilo ocupado el menor tiempo posible.

Una casa que hay que entender de Async/Await, es que en principio nuestra aplicación no va a funcionar más rápido. Ya que Async/Await creará hilos y bloqueos por nosotros y estos consumen recursos del sistema. Así que solo usarlo donde sea necesario y se produzcan bloqueos de IO, como acceso a base de datos, a disco u servicios Web.

Async/Await hay que llevarlo hasta el final. Por ejemplo, desde la captura de nuestro evento, hasta el acceso a la base de datos.

No utilizar Async/Await para realizar tareas costosas en las que interviene el procesador. Por ejemplo, eso es una manera muy sencilla de no bloquear nuestra aplicación con una tarea costosa. Pero hay otra formas más elegante, creando una buena arquitectura Modelo Vista ViewModel.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await Task.Run(() =>
    {
       // Tarea costosa.
    });
}
Si tenemos una clase intermedia que no va a gestionar ningún tipo de bloqueo no utilizar Async/Await. Recordar que el compilador meterá mucho código por nosotros que conlleva sobrecarga en el sistema.

private Task AccesoADatos()
{
   int i = 54;
   return MiDDBB.CreateQueryAsync(i);
}
en vez de

private async Task AccesoADatos()
{ 
     int i = 54;
     await MiDDBB.CreateQueryAsync(i);
}

jueves, 2 de febrero de 2017

WCF con Async/Await

Con el Framework 4.5 se introdujo un mecanismo para evitar los bloqueos de una forma sencilla. Aunque la principal motivación de esta mejora han sido los entornos táctiles en aplicaciones de cliente, también se pueden utilizar para no bloquear el pool de hilos de un web servicie.

Cuando se habla de multitarea se puede referir a dos conceptos diferentes que hay que tener bien claros.
  • Multitarea de CPU o multithreading, que consiste en particional una tarea para aprovechar los diferentes núcleos que dispone la máquina. Este tipo de multitarea no es la que vamos a tratar en este artículo, y no es recomendable utilizarla en una máquina dedicada a dar servicio a traves de la red.
  • Multitarea asyncronica IO, que consiste en no bloquear el procesador mientras se realizan tareas de entrada y salida de datos. Un tiempo en el que nuestra máquina no hace nada. Los casos típicos de estos bloqueos son el acceso a disco, consultas a bases de datos, comunicación con otras máquinas.
Los servidores de aplicaciones como el IIS, nos abstraen de la tarea de gestionar los hilos necesarios para contestar a las diversas llamadas que se realizan a nuestro servicio. Estos disponen de un pool de hilos que van contestando a las diversas llamadas. Pero cuando no hay hilos disponibles en el pool bloquean las llamadas entrantes dejándolas en espera.

Se puede modificar la capacidad del pool. Pero estos parámetros vienen ajustados de fabrica y se adaptan a nuestra maquina en función de su velocidad y número de hilos. Así que no es recomendable modificar estos parámetros. Aun así, os dejo una referencia de como escalar el pool de aplicación.

Una forma de hacer llamadas asíncronas a un servicio web, de la que no vamos a entrar en detalle, es crear un método que devuelva un objeto IAsyncResult, con un parámetro AsyncCallback. Con esto se consigue no bloquear al cliente. Pero el hilo del Pool del servidor se mantiene en uso en todo momento. Además hay que capturar eventos en el cliente, creando un código más confuso.

Otra forma muy sencilla y elegante de que se introdujo en el Framewokr 4.5 es mediante programación asíncrona con async/await. Esto nos permite liberar el hilo del pool para hacer ciertas tareas de entrada y salida y luego recuperarlo de una forma muy sencilla.

Vasta con definir nuestro método de servicio como async y devolver un objeto Task. Exactamente igual que se definen cual otro tipo de métodos asíncronos.

[ServiceContract]
public interface IOperacioens
{
     [OperationContract]

     Task AddObjet(object x);


     [OperationContract]
     Task<int> CountObjets();}

public class OperacioensNetService : IOperacioen
{
     public async Task AddObjet(object x);
     {
     }


     public async Task<int> CountObjets()
     {
         ....
         return number;
     }
}
De esta forma tan simple tendremos creado nuestro método asíncrono para poder ser consumido remotamente.

A la hora de invocarlo desde el cliente es igual de sencillo. Solo tendremos que utilizar await para invocarlo.  Lo que nos permitirá no dejar bloqueado el objeto Dispacher encargado de dibujar en la pantalla, mientras se espera a que conteste el método remoto.


lunes, 23 de enero de 2017

Introducción a las llamadas asincronas con WCF

Cada vez es más importante no bloquear nuestra interface de usuario, para conseguir una mayor fluidez en nuestras aplicaciones. Cuanto menos tiempo utilicemos un recurso, más fluido funcionarán nuestra aplicaciones.

Una forma sencilla que ofrece WCF desde su aparición es simplemente no esperar al resultado de una llamada. Para ello existe el parámetro IsOneWay del atribute OpeatonContractAttribute. Con esto el cliente no esperará a recibir una respuesta del servidor.

[OperationContract(IsOneWay = true)]
void Echo();

Como es de esperar, al especificar IsOneWay, nuestro método no puede devolver nada y hay que definirlo como void.

En una próxima entrada explicaré como usar asyn/await. Una forma más avanzada de hacer llamadas asíncronas sin bloquear los recursos de la máquina tanto en el cliente como en el servidor.

jueves, 12 de enero de 2017

Traducir al ingles mensages de excepciones

Cuando se produce una excepción que no conocemos su causa una forma de obtener informaciones es utilizar google o bing para buscar información. La cual suele ser mucho más abundante en ingles que en cualquier otro idioma. Una forma de obtener estos mensajes en ingles es utilizar un Windows en ingles o cambiar la configuración regional. Pero hay una forma más sencilla de obtener este mensaje sin necesidad de estar cambiando la configuración de nuestra maquina. Y es introduciendo un nuestro código un cambio de idioma.


Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");           Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

Tras esta líneas todas las excepciones aparecerán en ingles.

No olvidéis eliminar las líneas tras solucionar el problema, ya que no solo se cambia el idioma en el que aparecen las excepciones, si no toda la configuración regional, como hora, formato moneda, puntuación de decimales, ...

lunes, 9 de enero de 2017

Introducción a WCF

En alguna ocasiones me ha tocada mantener aplicaciones que utiliza las Windows Communication Foundation como herramienta de comunicación y siempre he tenido que sufrir lo complicado que es su mantenimiento, debido a la utilización de asistentes. Estos asistentes suelen funcionar muy bien para crear el servicio, ya que te crea todos los objetos de intercambio de datos. Pero complican terriblemente su mantenimiento. Desaprovechan la capacidad de .Net de funcionar en cualquier plataforma y compartir código. Y es muy complicado implementar pruebas unitarias.

Con esta entrada voy a iniciar una serie en la que trataré de explicar cual es la forma de sacar toda la potencia que tiene WCF.

Lo primero que hay que hacer para definir un servicio es crear una interfase que lo defina. Para que WCF la entienda se deberá marcar la interface con el atributo ServiceContractAttribute y cada propiedad con OperationContractAttribute.

[ServiceContract]
public interface IOperacioens
{
   [OperationContract]
   double Plus(double x, double y);
}


Y definimos la clase en el servidor que implementa la interfase.

public class OperacioensNetService : IOperacioen
{
   public double Plus(double x, double y)
   {
      return x + y;
   }
}
Construimos nuestra clase de servicio heredando de ServiceHost. En la que utilizamos la clase BasicHttpBinding para definir un servicio SOAP sobre Http.

public sealed class OperationsServiceHost : ServiceHost
{
   public OperationsServiceHost(Uri baseAddresses)
        :this(typeof(OperationsNetService), baseAddresses)
   {
   }

   public OperationsServiceHost(Type serviceType, params Uri[] baseAddresses)
        :base(serviceType, baseAddresses)
   {
        CreateBinding();
   }

   private void CreateBinding()
   {
        Binding binding = new BasicHttpBinding();
        base.AddServiceEndpoint(typeof(IOperations), binding, string.Empty);
    }
}

Creamos la clase de conexión en la parte del servidor, la cual nos creará el canal de comunicaciones.


public class OperationsConnection : IDisposable
{
    private ChannelFactory<IOperations> mFactory = null;

    public ChannelFactory<IOperations> Factory
    {
       get { return mFactory; }
    }

    private IOperations mChannel;

    public IOperations Channel
    {
       get
       {
           if (mChannel == null)
           {
              mChannel = Factory.CreateChannel();
           }
           return mChannel;
       }
    }

    public OperationsConnection(string service)
    {
        Binding binding;

        binding = new BasicHttpBinding();
        ContractDescription contract = ContractDescription.GetContract(typeof(IOperations));

        ServiceEndpoint endpoint = new ServiceEndpoint(
                    contract,
                    binding, new EndpointAddress(service));

        mFactory = new ChannelFactory<IOperations>(endpoint);
    }

    #region IDisposable
    public void Close()
    {
        if (mFactory != null)
        {
            mFactory.Close();
        }
     }

     public void Dispose()
     {
        Dispose(true);
        GC.SuppressFinalize(this);
     }

     protected virtual void Dispose(bool disposing)
     {
         if (disposing)
         {
             this.Close();
         }
     }
     #endregion
    }

Ya tenemos todas las piezas. Ahora solo nos queda montarlas. Para ello tenemos dos opciones en el lado del servidor. Montar nuestro propio Host auto hospedado. Lo cual nos permitirá crear un servidor con cualquier tipo de aplicación, ya sea aplicación de consola, servicio NT o una aplicación Windows. Utilizaremos la clase OperationsServiceHost anteriormente creada. En nuestro ejemplo se expondrá un servicio que escucha por el puerto 9085.

using (var operationsService = new OperationsServiceHost(
        new Uri("http://localhost:9085/OperationsService.svc")))
{
     operationsService.Open();
     Console.ReadLine();
}

Otra forma es hospedar nuestro servicio en un servidor IIS. Lo que nos permitirá aprovechar el del Pool de conexiones y el reciclaje de servicios de los que dispone el IIS. Para montar el servicio tendremos que crear un fichero con extensión svc, en el que se define el ServiceHost y una clase HostFactory que se encargará de crear la instancia del ServiceHost. Se definirá de la siguiente manera.



<%@ ServiceHost
     Service="OperacionesWCF.Server.OperationsNetService"
     Factory="OperacionesWCF.Server.OperationsServiceHostFactory" %>

Ya solo nos queda hacer las llamadas a nuestro servicio desde una aplicación cliente. Lo cual aremos con la clase anteriormente creada OperationConnection. La cual tiene una propiedad Channel, la cual nos devolverá una instancia virtual al servicio en el servidor.




using (OperationsConnection connection =

                new OperationsConnection(url))

{
    IOperations operations = connection.Channel;
    Console.WriteLine(operations.Plus(345, 23));
}


Podéis descargar un ejemplo en:
https://github.com/andrechi1/Blog-Examples/tree/master/OperationsWCF