martes, 22 de septiembre de 2015

Contenedores de Inversión de Control (IoC Containers)

Como vimos en la entrada anterior, hemos conseguido evitar el acoplamiento entre distintas clases de nuestra aplicación utilizando la inyección de dependencias. En nuestro caso, utilizamos inyección por constructor, es decir, en el constructor de nuestro Controller recibimos como parámetro un objeto que implementa la interfaz IUserInterfaz.

Pero si ejecutamos el código sin más, recibiremos un error, porque no hay nadie proporcionando un objeto para esa interfaz. Aquí entran en juego los Contenedores de Inversión de Control (IoC, por sus siglas en inglés).
Haciendo un resumen muy somero, lo que hacen estos contenedores es tener una relación entre una interfaz y una clase que implemente esa interfaz, del tal manera, que cuando haya que "inyectar" una dependencia, sabrá perfectamente qué clase tiene que suministrar. También se encargan del ciclo de vida de estos objetos.

Hay bastantes contenedores de inversión de control (Unity, Ninject, Autofac, ...) y el concepto es el mismo en cada uno de ellos. Yo utilizo Unity (por ser el recomendado por Microsoft, razón por la que cualquier otro lo puede rechazar ;-)) y será el que veremos en los ejemplos. Concretamente he usado Unity.MVC4 que permite una integración sencilla con ASP .NET MVC4.
Ya veremos los detalles de cómo se instala y configura cuando lleguemos a la parte del cliente Web.

Bueno, dejamos estas dos entradas que han sido más de teoría que de práctica y en la próxima entramos un poco más en harina.


Un poco de lectura sobre los princios SOLID: http://www.codeproject.com/Tips/1033646/SOLID-principle-with-Csharp-example

viernes, 11 de septiembre de 2015

Inyección de dependencias

En esta entrada no pretendo dar una clase magistral o completa sobre lo que es la inyección de dependencias. Pero, por si algún intrépido lector ha llegado hasta esta entrada y quiere seguir leyendo las siguientes, recordaré el concepto de inyección de dependencias porque lo utilizaremos más adelante.

Este concepto lo utilizó hace mucho tiempo Martin Fowler y en pocas palabras lo que pretende es evitar los acoplamientos de un objeto con otro. Voy a poner un ejemplo.

Imaginemos que tenemos este controller en nuestra aplicación ASP .NET MVC.

public class LoginController : Controller
{
 public ActionResult Index(UserEntity User)
        {
            UserService UserSer = new UserService();
            UserEntity oUser;
            try
            {
                oUser = UserSer.DoLogin(User.UserName, User.Pass);
                if (oUser != null)
                {                
                    FormsAuthentication.SetAuthCookie(User.UserName, false);
                    SessionHelper.CurrentUser = oUser;
                    return RedirectToAction("Index", "History");
                }
            }
            catch (Exception ex)
            { }

            ModelState.AddModelError("", "Los datos de acceso son incorrectos.");

            return View(User);
        }

 public ActionResult Register(UserEntity User)
        {
            UserService UserSer = new UserService();
            try
            {
                oUser = UserSer.Register(User);
                return RedirectToAction("Index", "History");
            }

            catch (Exception ex)
            { }        

            return View(User);
        }
}


El controller es correcto en cuanto a la funcionalidad. Hace lo que se supone que tiene que hacer, pero podemos observar varias cosas:
- Nuestro controller está acoplado a la clase UserService.
- No cumplimos con el principio DRY (mucho código repetido)
- Difícil poder hacer pruebas unitarias a los métodos.


Vamos a hacer unos pequeños cambios para intentar mejorar la situación
public class LoginController : Controller
{
 private UserService UserSer;
 public LoginController()
{
       UserSer = new UserService();
}
 public ActionResult Index(UserEntity User)
        {          
            UserEntity oUser;
            try
            {
                oUser = UserSer.DoLogin(User.UserName, User.Pass);
                if (oUser != null)
                {                
                    FormsAuthentication.SetAuthCookie(User.UserName, false);
                    SessionHelper.CurrentUser = oUser;
                    return RedirectToAction("Index", "History");
                }
            }
            catch (Exception ex)
            { }

            ModelState.AddModelError("", "Los datos de acceso son incorrectos.");

            return View(User);
        }

 public ActionResult Register(UserEntity User)
        {
            try
            {
                oUser = UserSer.Register(User);
                return RedirectToAction("Index", "History");
            }

            catch (Exception ex)
            { }        

            return View(User);
        }
}


Bueno; hemos mejorado un poco quitando la instanciación de la clase UserService de cada método y llevándolo sólo al constructor del controller.
Pero seguimos teniendo el controller acoplado al objeto UserService y seguimos teniendo difícil el realizar pruebas unitarias debido a este acoplamiento.

Inyección de Dependencias.
Para evitar este acoplamiento utilizaremos la Inyección de Dependencias y el uso de interfaces.
Lo primero que deberemos hacer es extraer la interface de la clase UserService.
En este caso, sería algo así

public interface IUserService
    {

        UserEntity DoLogin(string Username, string Pass);
        UserEntity Register(UserEntity User);
}

Una vez hecho esto, lo que hay que decirle a la clase UserService, es que implementa esta interface.

 public class UserService : IUserService
{
/// Codigo propio de esta clase
}


Y cómo afecta esto a nuestro controller? Bien, veamos

public class LoginController : Controller
{
 private IUserInterface UserSer;
 public LoginController(IUserInterface UserServInyectado)
{
       UserSer = UserServInyectado;
}


Si nos fijamos, no queda ningún rastro de la clase UserService. Ahora solo utilizamos interfaces. Cualquier clase que implemente la interface IUserInterface será válida como parámetro del constructor de nuestro controller.

Este sistema se llama inyección de dependencias por constructor, ya que es en el constructor de nuestro objeto cuando inyectamos el "comportamiento" deseado.

¿Y quién proporciona las dependencias a nuestro controller?. Bueno eso lo veremos en la próxima entrega de Contenedores de Inversión de Control.

jueves, 10 de septiembre de 2015

Base de datos

La base de datos utilizada es SQL Server 2014. El modelo E/R es muy sencillo; se pretende guardar los movimientos que genera el usuario y poder mostrar el saldo en cada movimiento.


Este es el modelo propuesto.
Un usuario podrá generar N movimientos; los movimientos tendrán un determinado concepto que a su vez pertenece a un grupo.
Los usuarios tendrán un usuario y contraseña para acceder al sistema y serán un tipo determinado (Administrador, usuario, …)
Por ejemplo: Un usuario puede insertar un gasto en gasoil para una fecha determinada y un gasto en un restaurante para esa misma fecha.
Gasoil se podría incluir en el Grupo de Coche y la cena en el Grupo de Ocio. Es simplemente una agrupación superior de la información para hacer un estudio general.

CLAUSULA OVER
El saldo se recalcula automáticamente, bien a la hora de hacer acceder a la aplicación o bien a la hora de insertar un movimiento.
En concepto de cálculo es muy sencillo; habría que recorrer los movimientos y calcular su saldo, ya que podemos insertar movimientos en cualquier fecha.
Se podría implementar un procedimiento recursivo que fuera leyendo los importes de los movimientos anteriores.
Desde la versión de SQL Server 2005 tenemos la posibilidad de hacer sumas acumulativas utilizando la cláusula OVER con la función SUM
Este es el código que utilizamos en nuestro proyecto:
create procedure dbo.RecalculaSaldo(
       @UserName nvarchar(10))

AS
BEGIN
declare @SaldoInicial decimal(18,2);

Select @SaldoInicial = SaldoInicial From Users Where UserName = @UserName;
WITH Saldo_CTE (Id,Saldo) as (
--Recalculamos el saldo de cada movimiento
select Movimientos.id
       , @SaldoInicial + sum(importe) over (order by fechamovimiento,id) saldo
from movimientos
WHERE username =@UserName
)
--Actualizamos el saldo de cada movimiento
Update Movimientos Set Saldo = Saldo_CTE.Saldo
From Movimientos
inner join Saldo_CTE ON Saldo_CTE.Id = Movimientos.Id

END

Lo que estamos haciendo es filtrar los datos por username y ordenando por fecha e Id de movimiento. Conseguimos que la función se evalúe para cada username basándonos en la fecha y el id del movimiento.
La cláusula OVER tiene varios argumentos, pero el que más uso, junto con order by, es PARTITION, que nos permite particionar la información por una o varias columnas. En el ejemplo que vemos, no aplica porque estamos filtrando por username, pero si quisiéramos recalcular el saldo de todos los movimientos de cada uno de los usuarios, podríamos particionar la información de esta manera
select Movimientos.id
       , sum(importe) over (partition by username order by fechamovimiento,id) saldo
from movimientos

Y obtendríamos una suma acumulativa del saldo de cada usuario.


Arquitectura

Voy a dar unas breves pinceladas de la arquitectura que voy utilizar.
Voy a utilizar una arquitectura N-Capas que me permita desacoplar cada una de ellas y me dé la flexibilidad de utilizar distintos clientes en la parte de presentación.
Un esquema básico sería el de esta imagen:

Como se puede apreciar,cada capa "habla" con la inmediatamente superior o inferior utilizando Business Entitites como "idioma" común a ellas.
1. DAL
Se encarga de la persistencia y acceso a los datos. En este caso, me estoy apoyando en un ORM como EntityFramework v6.0 Code First.
Además, en esta capa se implementan Unit of Work y los repositorios
2. Services
Es la capa que tiene la lógica de la aplicación. Validaciones y reglas de negocio están aqui.
3. WebAPI
Esta capa se "superpone" a la capa de servicios para poder ofrecer una REST API que pueda ser consumida por clientes de terceros. En este caso, será consumida por una aplicación para Windows Phone 8.1
4. UI
Capa que se encarga de interactuar con el usuario. En este caso tendremos dos variables:
4.1 ASP .NET MVC4
4.2 Windows Phone
5. Business Entities
En esta capa se incluyen la entidades que serán usadas por la capa de presentación y que se usan para que ésta "hable" con la capa de servicios.
6. Infraestructura
Aquí incluyo elementos comunes (que pueden ser consumidos por cualquiera de las capas), como por ejemplo, logging, gestión de excepciones, ...

Comienzos

He decido hacer esta serie de posts para mostrar que las tecnologías, técnicas, ... que tengo en mi CV corresponden con mi experiencia. Que no lo tengo puesto para rellenar.
La solución que muestro aquí solo pretende eso y en ningún caso quiere ser una guía de cómo implementar cierta arquitectura, cómo aplicar cierta metodología o porqué usar uno u otro framework del lado de cliente, por poner varios ejemplos.
Pues al lío.
Pretendo desarrollar un sistema que te permita llevar tus cuentas. Vale, que no es muy original, que ya te da la información del banco,... pero bueno, se puede ver cómo crear acciones CRUD en una sola vista.
Puestos a poner requerimientos, que se pueda trabajar desde un dispositivo móvil; en principio, solo estará disponible para Windows Phone, pero según vaya avanzando .... veremos.
Pues para realizar este proyecto voy a usar .NET. Concretamente:
  • Unit of Work
  • Repository Pattern
  • ASP .NET MVC 4
  • C#
  • WebAPI
  • MVVM con Knockout
  • jQuery 1.9.1
  • jQueryUI 1.11.4
  • jQuery Validation Plugin
  • Toastr 
  • Bootstrap 3.3.5
  • Entity Framework 6 Code First
  • SQL Server 2014

En la siguiente entrada publicaré la arquitectura que he usado.