Portable Class Library (PCL) vs Shared Projects en Xamarin Forms

Si navegamos por la web buscando ejemplos de proyectos o tutoriales de  Xamarin Forms , nos encontraremos  muchos ejemplos usando Shared Projects, por esta razón la mayoría de los recién  iniciados a Xamarin basan sus primeras aplicaciones en estos ejemplos.

Además de los casos de uso heredados, hay razones muy limitadas para usar SharedProjects en aplicaciones Xamarin Forms, las PCL son el método preferido en la mayoría de los escenarios.

En una oportunidad participe en un webinar dictado por el MVP Humberto Jaimes donde toco este tópico, tratare de explicar en este post  lo aprendido y el  research que hice a parte para documentarme.

Shared code

Este al momento de compilar incorpora en cada assembly una referencia al proyecto compartido. Esto puede ser útil cuando deseamos crear assembly por  separados que se orientan a plataformas específicas, pero todavía el código debe ser compartido.

 

Portable Class Library (PCL)

Los proyectos apuntan a perfiles específicos que soportan un conjunto conocido de clases / características BCL. Sin embargo, el lado negativo de PCL es que a menudo requieren esfuerzo arquitectónico adicional para separar el código específico del perfil en sus propias bibliotecas.

Aplicando al mundo real

Con  SharedProject podemos crear las clases como de costumbre, pero si queremos hacer algo específico de la plataforma que estemos trabajando, tenemos que implementar una directiva de compilación en nuestro código.

Por ejemplo.

public string GetTargetPlatform()
{

  var path = "unknown";
  
  #if WINDOWS_PHONE
  path = "windowsphone";
  #else
  
  #if __SILVERLIGHT__
  path = "silverlight";
  #else
  
  #if __ANDROID__
  path = "android";
  #else
  
  #if __IOS__
  path = "iOS";
  #else
  
  
  return path;
}

Estas clases parciales pueden ser buenas para pequeños proyectos o demos.  Sin embargo, si la App tiene varios desarrolladores trabajando en ella  o es  algo más que una aplicación realmente simple o proyecto de demostración, la capacidad de mantenimiento de un proyecto compartido se vuelve menos agradable debido a la falta de control arquitectónico y vamos a estar  luchando por encontrar lo que realmente se está ejecutando en cada plataforma.

Un problema de los shared, es que en un proyecto compartido tiene problemas al definir un nombre de ensamblado. Por ejemplo, en xaml si desea hacer referencia a un control y hacer referencia a un nombre de assembly, cada proyecto nativo tendrá un nombre de assembly distinto, por lo que deberá realizar más ifdefs o OnPlatforms, o nombrar cada proyecto nativo con el mismo nombre de assembly.

las PCLs

No crean que las PCLs no vienen con sus propios  dolores de cabeza pero, proporcionan una asombrosa manera de escribir código fácil  de mantener y probarlo  una vez que la aprendemos a utilizar en múltiples plataformas. Cuando se escribe una PCL, no es necesario insertar directivas de compilación  para cambiar el código en función de cada plataforma, se seleccionan las plataformas que se van a admitir y luego se inicia a escribir el código de nuestra APP. Cuando creamos un PCL, luego podemos ir a Propiedades y establecer los Targets para el proyecto.

targetprofile

PCL son proyectos que pueden dirigirse a diferentes plataformas, podemos elegir cuáles y luego esta nos da acceso a ciertos conjuntos y funciones, dependiendo de cuáles seleccionemos. Las diferentes combinaciones de objetivos para PCL se denominan perfiles y cada perfil tiene su propio número. El perfil más común y recomendado para los proyectos Xamarin Forms es Profile259.

Beneficios

Algunos beneficios del uso de PCL son:
Pruebas de unit testing mas sencillas de aplicar
Código mas facil de leer
Mayor portabilidad
Mejor implementacion  del código

Cual usar ?

Yo en lo personal para grandes proyectos de arquitecturas complejas y una gran necesidad de código portable recomiendo las PCL, en cambio para proyectos pequeños, prototipos y demos recomiendo usar Shared Projects.

 

Si no estas de acuerdo en algo o tienes algo que agregar déjalo en los comentarios ! 🙂

 

 

EntityFramework con repositorios genéricos

computer-1185626_1280
EntityFramework es una herramienta que le permite a los programadores tener una capa más de abstracción entre su aplicación y su base de datos. Con EntityFramework podemos crear tablas ligadas a nuestras clases, y con ello viene la ventaja de poder ir versionando nuestra base de datos. Pero EntityFramework no es el único ORM en el mercado, existen otros entre Dapper, Massive y PetaPoco.

Entre todas las opciones existentes de ORM y de diferentes gestores de bases de datos, viene siendo aún más importante ir creando una capa entre la lógica de la aplicación y la base de datos. Para ello, los programadores suelen utilizar el patrón de repositorios genéricos, con unas cuantas funciones. Estas se mantienen igual, y lo que cambian son sus implementaciones.

Con .NET Core, la situación se vuelve más sencilla, ya que permite “inyectar” el repositorio encargado. La clase (o un controlador) desconoce quien la implementa, simplemente la usa. La forma de implementación no es de su incumbencia y al menos así podemos evitar la cohesión entre clases, que a la larga provocan problemas.

Como se puede observar en el código siguiente, existe una variable llamada “repository”, este se encarga de agregar la entidad/registro en la base de datos. La función Index (que es una acción de un controlador) no conoce ni quién, ni cómo la implementa, simplemente la usa. ¿El beneficio? en cualquier momento podemos cambiar de SqlServer a MySQL o MongoDb, sin necesidad de mover esa función.

Prerequisitos

Este artículo asume que se está usando Visual Studio 2015. Para poder continuar, se requiere de igual forma, modificar el archivo project.json (archivo del proyecto) para incluir los siguientes paquetes.

  • “Jaguar.DataAccess.EntityFramework” es un paquete que contiene el repositorio genérico, es una versión estable, pero que se entrega sin responsabilidad alguna de parte del autor, su código fuente estará pronto en Github.
  • “Microsoft.EntityFrameworkCore.SqlServer” es el paquete que permite conectarse especificamente a SQL Server. Este puede cambiarse de acuerdo a la página oficial.
  • “Microsoft.EntityframeworkCore.Tools” nos permite ir actualizando la base de datos conforme vamos haciendo los cambios.

Crear un modelo

En un ORM, cada modelo es una clase que esta enlazada a una tabla en la base de datos. De tal forma que el programador simplemente crea la clase y -en este caso- EntityFramework se encarga de realizar el resto.

Para el repositorio genérico, cada una de las clases deben implementar una interfaz. De tal manera que todas compartan al menos los requeridos para el repositorio. Esa interfaz en este caso es la de Jaguar.DataAccess.IEntity.

Cada clase debe tener al menos un campo clave que lo identifique. De manera predeterminada los campos llamados Id, o CustomerId son considerados automáticamente “campos claves”. IEntity, utiliza un campo tipo Guid.

Crear un contexto de EntityFramework

Para que EntityFramework pueda identificar que clases creará en la base de datos, estas se deben de poner en un “contexto”, para ello se requiere de crear una clase como la siguiente:

Solía suceder que EntityFramework utilizaba el nombre de la clase para compararlo en el webconfig en busca de una cadena de conexión, sin embargo en este caso (EntityFrameworkCore) las cosas ya no son así.

Es por eso que en la clase se crean como minímo 3 funciones, las primeras dos son constructores y la última es la que configura la cadena de conexión.

En el caso de los constructores, uno es utilizado por el repositorio para obtener la configuración recibida por el DI (inyección de dependencias) de .NET. El segudo, para los comandos de migración que se explica más adelante.

La última propiedad, es la interesante, básicamente ahí decimos que se creará una tabla de “Customer”.

Configurar DI

La inyección de dependencias es algo muy útil, y en este caso la usaremos en el archivo Startup.cs para poder crear la relación con el repositorio.

En este punto, existe una extensión que permite configurar ese contexto, para que sirva como el repositorio. A ese repositorio se le debe pasar la cadena de conexión, así que para ello, se debe configurar el archivo “appsettings.json”.

La base de datos que se usa en la cadena de conexión ha sido creada previamente, y asignado los permisos requeridos al usuario.

Creando las tablas (migración)

Con EntityFrameworkCore, los comandos cambiaron. Entre los paquetes que se instalaron en el proyecto se encuentra “Microsoft.EntityframeworkCore.Tools”, el cual es el encargado de crear los comandos necesarios para las migraciones.

Primero se debe generar las rutinas que se cargaran a la base de datos, corra los siguientes comandos para crear las tablas.

cd "srcmiapp"
dotnet ef migrations add inicial
dotnet ef database update

Al finalizar, las tablas fueron creadas en la base de datos. Considere correr esos comandos en el directorio principal de la aplicación donde esta el archivo “project.json”.

Haciendo uso del repositorio genérico

La inyección de dependencias (DI) es un concepto sencillo de comprender. El programador elabora un contrato, que tiene ciertas claúsulas. Todas esas cláusulas son obligatorias, de tal manera que al “contratar” a alguién, este debe de cumplir con dichas cláusulas. El contrato es una interfaz, que contiene las funciones que se ejecutará, pero no la implementación.

De tal manera, que en el paso anterior se especificó a .NET que el encargado del repositorio será la clase DataContext. Esta clase es la que ya se hizo anteriormente, es posible que al observar se de cuenta que la clase extienda la clase “Jaguar.DataAccess.EntityFramework.RepositoryContext” al mismo tiempo implementa la interfaz IRepository.

Con ello, .NET es capaz de inyectar en el constructor de la clase (HomeController), una instancia de DataContext con los métodos que tiene la interfaz IRepository.

Como se puede observar en el código anterior, existe un controlador que recibe el repositorio. Este lo asigna a una variable para que pueda ser usada dentro de ese ámbito. En la función Index, se agrega un cliente, usando la función AddEntity.

La interfaz Jaguar.DataAccess.IRepository contiene la lista de todas las funciones.

Recomendaciones

En conclusión, EntityFrameworkCore viene mejorando mucho en rendimiento y compatibilidad con diferentes proveedores. Utilizar un patrón de repositorio genéricos se vuelve aún más importante. Independientemente si se utiliza el repositorio genérico descrito aquí, así como cualquier otro, es importante adquirir la práctica de hacerlo bajo ese patrón.

Codigo fuente de la App Demo #Charla gratuita de Conceptos Fundamentales de #Xamarin en #MundoSQL

Mi buen amigo el MVP Juan Carlos de  MundoSQL me invito a dar una charla online sobre Xamarin,  aqui les dejo el codigo fuente de la demo.

El codigo de main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/listView1" />
</LinearLayout>

El codigo del MainActivity.cs

using Android.App;
using Android.Widget;
using Android.OS;
using System.Collections.Generic;

namespace dfdd
{
	[Activity(Label = "Lista", MainLauncher = true, Icon = "@mipmap/icon")]
	public class MainActivity : Activity
	{
		private List<string> mItem;
		private ListView mListView;

		protected override void OnCreate(Bundle savedInstanceState)
		{
			base.OnCreate(savedInstanceState);

			// Set our view from the "main" layout resource
			SetContentView(Resource.Layout.Main);

			mListView = FindViewById<ListView>(Resource.Id.listView1);

			mItem = new List<string>();
			mItem.Add("Naiomi");
			mItem.Add("Jose Miguel");
			mItem.Add("Juan carlos");
			mItem.Add("Luis");
			mItem.Add("Frank ac");
			mItem.Add("JLuis Perez");
			mItem.Add("Jordi");
			mItem.Add("Jose Miguel");
			mItem.Add("Naiomi");
			mItem.Add("Jose Miguel");
			mItem.Add("Juan carlos");
			mItem.Add("Luis");
			mItem.Add("Frank ac");
			mItem.Add("JLuis Perez");
			mItem.Add("Jordi");
			mItem.Add("Jose Miguel");
			ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, mItem);

			mListView.Adapter = adapter;

		
  }
	}
}


Aqui el video de la demo !

Esto es todo por el momento alguna duda, comentario o sugerencia no duden en escribirme.

Errores en Xamarin “Unzipping failed”

En mis inicios con Xamarin, utilice por primera vez Xamarin.Droid y durante la compilación del proyecto recibí errores que casi hacen que tire la toalla, similares a estos :

Error      2             Unzipping failed. Please download https://dl-ssl.google.com/android/repository/android_m2repository_r22.zip and extract it to the C:\Users\User\AppData\Local\Xamarin\Xamarin.Android.Support.Design\23.0.1.3\content directory.                DemoForms.Droid

Error      3             Reason: C:\Users\User\AppData\Local\Xamarin\zips\96659D653BDE0FAEDB818170891F2BB0.zip is not a valid zip file            DemoForms.Droid

 

 Porque sucede esto ?

Cuando compilamos por primera vez nuestro proyecto se descargan de algunas librerías propias de Android, estas librerías se descargan en ficheros  .zip y luego estos  son descomprimidas durante el proceso de compilación. Estas librerías se almacenan en el directorio “%LOCALAPPDATA%\Xamarin\zips”.

Todos sabemos Visual Studio no es muy explícito acerca de lo que está haciendo mientras compila y dependiendo de la velocidad  nuestra conexión a Internet  este proceso puede ser muy lento, esto provoca que en muchas ocasiones esta lentitud causa que cancelemos el proceso de compilacion pensando en que Visual Studio ya no está haciendo nada, sin embargo, lo que logramos es que las descargas queden a medias y esos archivos se mantienen dañados en el directorio “%LOCALAPPDATA%\Xamarin\zips”.

Solución !

Eliminar de manera manual los archivos dañados en el directorio “%LOCALAPPDATA%\Xamarin\zips”. y re-compilar la solución ahora si con paciencia esperando a que se descargue todo.

#Charla gratuita de Conceptos Fundamentales de #Xamarin en #MundoSQL

Saludos en esta entrada los invito a participar de este Webinar “Xamarin 101 Conceptos Fundamentales” que me a invitado mi amigo el MVP Juan Carlos Gilaranz de Mundo SQL

Este es el póster del evento.

20161022

Esta es la URL para entrar al Skype:

 

https://meet.lync.com/carlosgilaranz/carlos/W0MQFZVN

Recuerden es este sábado 22 obture 9 am de mi pais Rep. Dominicana

Este es el evento en Facebook.

https://www.facebook.com/events/578559605665508/

 

Cualquier duda escribir en Tiwtter a @yhorbymatias o @_Juankar_

Hilos en C#

etSq-1Saludos en esta entrada les hablare sobre los hilos en C#:

  •  Que son ?
  • Como funciona.
  •  Cuando usarlos.

Si somos nuevos en la programación o estamos aprendiendo C# debemos saber que, C# soporta la ejecución paralela de código a través de múltiples hilos.

Pero que es un hilo ?

Un hilo es una ruta independiente de ejecución, capaz de ejecutarse simultáneamente con otros hilos, es decir que podemos ejecutar cuantos hilos sean necesarios para realizar nuestra tarea.

Debemos tener claro que un programa C#, arranca en un hilo principal creado automáticamente por el CLR y el sistema operativo y puede estar compuesto de múltiples subprocesos mediante la creación de hilos adicionales.

Nota:El CLR es un entorno de ejecución para los códigos de los programas que corren
 sobre la plataforma Microsoft .NET. El CLR es el encargado de compilar una forma 
de código intermedio llamada Common Intermediate Language 
(CIL, anteriormente conocido como MSIL, por Microsoft Intermediate Language), 
al código de maquina nativo, mediante un compilador en tiempo de ejecución. 

Como funciona

Los hilos son manejados internamente por un programador o “gestor” de hilos, una función que el CLR típicamente delega en el sistema operativo.

Un programador de hilos asegura que a todos los hilos se les asigna un tiempo de ejecución apropiado y que todos aquellos hilos que estén bloqueados o pausados no consuman tiempo de CPU. En un ordenador con un solo procesador, un programador de hilos gestiona una alternancia rápida entre los hilos activos, derivando en un comportamiento entrecortado. Desde Windows XP, la asignación de tiempo para cada hilo está en el orden de las decenas de mili-segundos.

Donde se encuentran ?

Todos los hilos dentro de una aplicación están dentro de un proceso. Pero no confundamos un Hilo con un Proceso, la diferencia entre estos es que  los procesos están completamente aislados unos de otros, mientras que los hilos no, estos tienen la cualidad de  compartir memoria con otros hilos que pertenecen al mismo proceso, es decir que un hilo puede estar generando datos en un segundo plano mientras que otro hilo muestra los datos que van llegando.

¿Cuándo usar hilos?

Normalmente se utilizan para realizar trabajos en un segundo plano que vayan a consumir mucho tiempo hasta que se completen, por ejemplo, operaciones masivas con bases de datos, operaciones de cálculo, reportes…, mientras que la interfaz de usuario queda libre para que el usuario pueda trabajar en otra cosa aumentando la productividad.

De otra manera, ésta no respondería, se vería bloqueada,es decir le saldría la coqueta literatura no responde en la aplicación que se este ejecutando , esto  aumentaría la insatisfacción del usuario. También es posible que desde dicha interfaz pueda ofrecerse al usuario la posibilidad de cancelar este tipo de operaciones u ofrecer incluso información acerca del estado o porcentaje de operación completado. Una clase que puede resultar muy útil para este tipo de situaciones es la clase BackGroundWorker.

No todo son ventajas manejando hilos.

La interacción entre hilos puede ser compleja y sin son usados en exceso o inadecuado, conllevan una penalización en el rendimiento de la CPU, así que cuidadin con el manejo de hilos.

Ahora viene la DEMO !!

Abrimos Visual Studio -> Creamos un nuevo proyecto C# consola.

a1

Manos al código, lo primero que haremos es crear una clase en mi caso yo la nombre tasks y escribiremos el siguiente código.

a2

Este es el código de la clase:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace hilos
{
    class tasks
    {
        private String name;
        private int time;
        // estos son los atributos de la clase

        //este es el metodo constructor, debe llamarse igual que la clase

        public tasks(String name, int time)
        {
            this.name = name; // el dato que este en el parametro name se lo vamos a almacenar a el atributo
            this.time = time;
            // de esta forma quedan inicializados los artibutos

        }
        //creamos un nuevo metodo
        public void tasks1()
        {
            Console.WriteLine(name +"Este hilo solo durara"+ time+"segundos"); // mensaje que saldra en consola

            Thread.Sleep(time * 1000); //aqui como dijimos en la teoria estamos calculando en base a milisegundos, asi que determinanos que tiempo tomara el hilo
            // tambien es el tiempo que se suspendera el subproceso actual hasta que se termine

            Console.WriteLine("Hilo terminado "+ name); // mensaje para saber cuando termino el hilo

        }
        //aca solo copie y pegue para tener dos hilos
        public void tasks2()
        {
            Console.WriteLine(name + "Este hilo solo durara" + time + "segundos"); // mensaje que saldra en consola

            Thread.Sleep(time * 1000); //aqui como dijimos en la teoria estamos calculando en base a milisegundos, asi que determinanos que tiempo tomara el hilo
            // tambien es el tiempo que se suspendera el subproceso actual hasta que se termine

            Console.WriteLine("Hilo terminado " + name); // mensaje para saber cuando termino el hilo

        }
    }
}

En el program.cs tendremos el siguiente codigo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace hilos
{
    class Program
    {
        static void Main(string[] args)
        {
            tasks objeto1 = new tasks("hilo-1", 16); // a la clase tarea le estamos pasando los datos nombre y tiempo
            tasks objeto2 = new tasks("hilo-2", 24);

            Thread hilo1 = new Thread(objeto1.tasks1);// de esta forma llamamos a los metodos que tenemos en la clase tarea
            Thread hilo2 = new Thread(objeto2.tasks2);

            //para iniciar estos dos procesos o hilos
            hilo1.Start();
            hilo2.Start();
            Console.ReadKey(); //con esto estatodo listo para ejecutar nuestros hilos de la clase tasks
        }
    }
}

Este seria la consola de salida con el resultado:

a3

Resumen

El DEMO que realizamos ejecutaba dos hilos al mismo tiempo y notifico cuando se terminaron de realizar, optimizando y automatizando las tareas y experiencia de usuario, genial no, en una próxima entrega haremos hilos que se ejecuten luego que otro termine.

Si conoces algo que no se trato en la entrada o quieres agregar algo no dudes en comentar, compártelo con tus amigos 🙂 !!!

 

Obtener tabla de multiplicar C#

etSq-1Para los que hemos estudiado en la universidad o en algún instituto nos hemos encontrado con una famosa hoja práctica de ejercicios y entre los ejercicios hemos encontrado el sensual Obtén la tabla de multiplicar de X o Y números, hahaha en ese momento apelamos a nuestra defensa pero si este profe no nos ha enseñado nada !!!

Resultado de imagen para meme pensando con el pie
C#

En esta entrada les compartiré el código fuente como obtener las tablas de multiplicar del 1 al 9, jojoj si dirán que básico, pero que es mejor ? que nos den el pescado o que nos enseñen a pescar, pues yo personalmente prefiero la ultima opción.

 

Para ello antes debemos saber que es el Try Catch la referencia aquí , y la referencia de FOR aquí

 

Dicho esto, Manos al Código !! 🙂

Abre visual studio y crea un nuevo proyecto C# en Consola. 

A continuación el código

static void Main(string[] args)
        {
            int numero;
            Console.WriteLine("Ingrese un numero del 1 al 9");
            try
            {
                numero = Int32.Parse(Console.ReadLine());
                if ( numero >= 1 && numero <= 9 )
                {
                    for (int i = 1; i <= 10; i++)
                    {                        
                        Console.WriteLine("{0} x {1} = {2}", numero, i, numero * i);
                    }
                }else {
                    Console.WriteLine("El número esta fuera de rango comprendido");
                }

            }
            catch {
                Console.WriteLine("ERROR: debe ingresar un numero entero que comprenda del 1 al 9");                
            }

            Console.WriteLine("Presione cualquier tecla para terminar el programa");
            Console.ReadKey();
        }

Esto es todo por el momento alguna duda, comentario o sugerencia no duden en escribirme.

Serie tutorial Xamarin Forms 101 #3

Saludos en esta entrada les compartiré el video donde continua la serie tutorial sobre Xamarin.forms la cual se denomina Xamarin Forms 101
Donde aprenderemos los diferentes modelos de desarrollo de Xamarin.


Si te ha gustado esta Entrada, por favor, compartir y dejar su comentario a continuación. Si tienes alguna pregunta, no dudes en enviar aquí. Voy a responder a todas las preguntas! 🙂 .