model-view-presenter

Retomando el tutorial respecto al uso del patron de diseño Model View Presenter. En esta tercera parte veremos los objetos y clases que componen la estrucructura de nuestro Proyecto. En la primera parte vimos la creacion de la base de datos y los proyectos que se incluyen en este tipo de solucion.

Los haremos en este orden:

  1. La Entidad que sera utilzada para el envio y recepcion de datos.
  2. La Vista (de usuario, definida en un prototipo de pantalla) que debera ser implementada en la pagina web.
  3. El Presenter que hara uso de la Vista y sera “llamado” por la pagina Web para la ejecucion del proceso.
  4. La implementacion de la Vista en la pagina Web.
  5. Por ultimo las capas de Negocios y Datos (sera la 3ra parte de este tutorial).

ENTIDAD

La entidad tendra los atributos necesarios para manejar los datos del Item de Menu. En el proyecto ENTITY, agregaremos una clase que se llamara MiMenuItem.cs y su codigo sera el que se ve a continuacion:

using System;
using System.Collections.Generic;
using System.Text;

namespace Entity
{
public class MiMenuItem
{
public int MenuId {get;set;}
public string NombreMenu { get; set; }
public string DescripcionMenu { get; set; }
public int PadreId { get; set; }
public int Posicion { get; set; }
public string Icono { get; set; }
public bool Habilitado { get; set; }
public string Url { get; set; }
public string FechaCreacion { get; set; }
public string UsuarioCreacion { get; set; }
public string FechaModificacion { get; set; }
public string UsuarioModificacion { get; set; }
}
}

Imagen de Referencia

mvp-menu-entidad

VISTA

Esta parte es la fundamental, ya que es lo que “vera” el usuario en la pagina. Esto se define en los prototipos de pantalla que se crean en base a la toma de requerimientos y Casos de Uso del sistema que estemos analizando y creando.

En este, contendra una “lista” de entidades del menu. Aqui agregaremos una clase especial del tipo INTERFACE. Como nombre le anteponemos una I mayuscula (por Interface) y un “apellido” que sera View, el nombre sera IMenuView.

mvp-menu-view-agregar

El codigo es el siguiente:


using System;
using System.Collections.Generic;
using System.Text;

using Entity;

namespace Presenter.View
{
public interface MenuView
{
IList ListaItemsMenu { set; }
}
}

Por que solo se usa el SET? porque sera una propiedad de “recepcion de datos”, sera solo “escrita” y no leida.

mvp-menu-view

PRESENTER

Ya que estamos en el mismo proyecto, crearemos el “presenter” que manejara la Vista que recien creamos y hara la comunicacion con la capa de Negocios. Su nombre sera MenuPresenter.

using System;
using System.Collections.Generic;
using System.Text;

using Entity;
using Business;
using Presenter.View;

namespace Presenter
{
public class MenuPresenter
{
private IMenuView vista;

//constructor de la clase donde se "amarra" la vista que se usara al presenter
public MenuPresenter(IMenuView view)
{
vista = view;
}

public void ObtenerMenuItems()
{
MenuNegocio negocio = new MenuNegocio();
IList<MiMenuItem> lista = new List<MiMenuItem>();

//aqui haremos la llamada al metodo del negocio

vista.ListaItemsMenu = lista;
}
}
}

En el constructor de la clase se utiliza la Vista que sera ocupada para trabajar en los metodos.

Imagen de Referencia

mvp-menu-presenter

Ahora bien, la clave de todo este MVP, es que cada Vista sea usada por un unico Presenter (ver constructor de la clase). Esto nos dara modularidad para implementar una Vista en cualquier pagina que se necesite.

IMPLEMENTAR VISTA

El siguiente paso es la “implementacion” de la Vista del Menu en nuestra pagina web. Para esto debemos ocupar la “multi herencia” que nos permite el .NET via Interfaces. Tenemos que agregar a la herencia de la pagina nuestra vista creada para tal proposito. Ver codigo:

public partial class Default: System.Web.UI.Page, IMenuView

Al agregar la Vista a la herencia de la pagina indicamos que propiedades extras tendra. Pero es solo el primer paso, ahora hay que hacer la implementacion que se hace de la siguiente manera:

mvp-menu-view-herencia-vista

Despues de escribir el nombre de la Vista, haremos click con el boton derecho sobre el nombre y tendremos un menu contextual para implementarla (en forma explicita) en nuestra pagina:

mvp-menu-view-implementacion

Despues de hacer click en la opcion Explicita, tendremos el siguiente codigo en nuestra pagina:

mvp-menu-view-implementacion-codigo

Si ven el codigo generado, dice algo asi como que no esta implementada la propiedad. Y es verdad, en este punto hay que indicarle a esta propiedad que Objeto sera el encargado de recibir, en este caso, una Lista de Entidades. Para esto agregaremos el codigo del Menu NET que trae el Visual Studio:

<asp:Menu ID=”MenuPrincipal” MaximumDynamicDisplayLevels =”20″ Runat=”server” Height=”20px”
Orientation=”Horizontal” BackColor=”#b1c3d9″ ForeColor=”#336699″ Font-Names=”Arial”
Font-Size=”11px” StaticSubMenuIndent=”” DynamicHorizontalOffset=”2″ Font-Bold = “True”
BorderStyle=”Solid” BorderColor=”#336699″ BorderWidth=”1px”>
<DynamicMenuStyle BackColor=”#B1C3D9″ BorderWidth=”1px” BorderColor=”#336699″ Width=”130px” />
<DynamicMenuItemStyle HorizontalPadding=”5px” VerticalPadding=”2px” />
<DynamicHoverStyle ForeColor=”White” Font-Bold=”True” BackColor=”#336699″/>
<StaticMenuStyle BackColor=”#B1C3D9″ BorderWidth=”1px” BorderColor=”#336699″/>
<StaticMenuItemStyle HorizontalPadding=”5px” VerticalPadding=”2px” Width=”130px”/>
<StaticHoverStyle ForeColor=”White” Font-Bold=”True” BackColor=”#336699″/>
</asp:Menu>

Ahora, para trabajar esta propiedad, nos apoyaremos en una variable del tipo de la Entidad que viene en la Lista:

    private MenuItem mnuMenuItem;

    IList<MiMenuItem> MenuView.ListaItemsMenu
    {
    set
    {
    foreach (MiMenuItem item in value)
    {
    if (item.PadreId == 0)
    {
    mnuMenuItem = new MenuItem();
    mnuMenuItem.Value = item.MenuId.ToString();
    mnuMenuItem.Text = item.NombreMenu;
    mnuMenuItem.ImageUrl = item.Icono;
    mnuMenuItem.NavigateUrl = item.Url;

    //agregar al menu principal de la pagina html
    MenuPrincipal.Items.Add(mnuMenuItem);

    //hacemos un llamado al metodo recursivo encargado de generar el arbol del menu.
    AddMenuItem(mnuMenuItem, value);
    }

    }
    }
    }

    //metodo recursivo oara crear los items del menu
    private void AddMenuItem(MenuItem mnuMenuItem , IList<MiMenuItem> lista)
    {
    MenuItem mnuNewMenuItem;

    foreach (MiMenuItem menuSubItem in lista)
    {
    if (menuSubItem.PadreId.ToString().Equals(mnuMenuItem.Value)
    && !menuSubItem.MenuId.ToString().Equals(menuSubItem.PadreId.ToString()))
    {
    mnuNewMenuItem = new MenuItem();

    mnuNewMenuItem.Value = menuSubItem.MenuId.ToString();
    mnuNewMenuItem.Text = menuSubItem.NombreMenu;
    mnuNewMenuItem.ImageUrl = menuSubItem.Icono;
    mnuNewMenuItem.NavigateUrl = menuSubItem.Url;

    mnuMenuItem.ChildItems.Add(mnuNewMenuItem);

    //llamada recursiva para ver si el nuevo menu item aun tiene elementos hijos.
    AddMenuItem(mnuNewMenuItem, lista);
    }
    }
    }

    //evento del page load para llamr al metodo del presenter que cargara el menu
    protected void Page_Load(object sender, EventArgs e)
    {
    if (!this.IsPostBack)
    {
    //instancio objeto del presenter.
    //El this le pasa la vista que usa la pagina
    MenuPresenter presenter = new MenuPresenter(this);
    presenter.ObtenerMenuItems();
    }
    }

La parte importante del codigo anterior, aparte de la implementacion misma de la propiedad de la vista (para usar la la lista de entidades que viene en el objeto value), es la instancia del presenter a usar. Si ven el codigo del Page Load, se hace la referencia e intstancia de la clse presenter a ocupar, pero el el new se asigna el “this” y esto le indica que tomara las propiedades de las pagina entre las cuales hay una “Vista” que es la que esta esperando el presenter para usarla.

Con esto cerramos la tercera parte de este tutorial.

En la cuarta parte, terminaremos la parte de negocio y datos que traeran los datos del menu dinamico.

TYDW.-

Como crear Menús Dinámicos con ASP .NET usando patron Model View Presenter (1ra Parte)