Hace dos semanas, terminé de dar un curso de ASP.NET, con máquinas, en el laboratorio del Microsoft User Group de Argentina, en Buenos Aires, contando con diez asistentes, con los que tuvimos 30 horas explorando el desarrollo de sitios dinámicos con .NET. Los ejemplos que fuimos desarrollando y otros que bajamos de ejemplos míos, están disponibles para bajarse desde:
Material del Curso de ASP.NET en el MUG
(Siempre pueden bajar lo que tratamos en mis cursos, desde
ya sea ASP.NET, .NET, arquitectura, Java, JSP, Spring, Struts, etc… así como las presentaciones que se usaron)
Hay varios ejemplos para estudiar, que podría explicar más en detalle en algún post, pero vaya ahora una introducción:
En este ejemplo
tenemos una base de datos, que pueden instalar usando cualquiera de los dos directorios Sql, y dos soluciones, una en VB.NET y otra en C#.
En el directorio Sql, tenemos:
Podemos lanzar la creación de la base con el comando ExecuteAll.cmd, que contiene
@REM -------------------------------------------------------------
@REM You can change server.
@REM -------------------------------------------------------------
SET sqlServer=%1%
if "%1%"=="" set sqlServer=(local)
call CreateDatabase %sqlServer%
rem TBD:
rem call LinkData %sqlServer%
rem call InsertData %sqlServer%
goto end
:end
Si lo invocamos sin parámetros, va a conectarse con nuestro MS SQL Server (local). Si queremos ir contra otra instancia, por ejemplo, contra .\SQLEXPRESS, hay que invocarlo como:
ExecuteAll.cmd .\SQLEXPRESS
Crea una base simple, AjFirstExample, con dos tablas, clientes y proveedores, y procedimientos almacenados:
El ejemplo sigue algunos linemamientos de Patterns & Practices, de Microsoft, como tener separados Business Entities de Business Components. La solución tiene varios proyectos:
WebClient es el sitio web. AjFirstExample.Services es una capa de servicios lógicos (no tecnológicos, como podría ser un Web Service), que es un .DLL que se invoca directamente de el sitio web. Es lo que en patrones llamamos una Service Layer. AjFirstExample.Entities contiene entidadas simples, con datos, sin conducta ni persistencia. Está muy orientada al ejemplo, que apenas es un CRUD (Create Read Update Delete) de entidades, fragmento:
Imports System.Collections.Generic
Imports AjFirstExample.Entities
Imports AjFirstExample.Business
Imports AjFramework.Data
Public Class SupplierService
Private Shared mSupplierComponent as new SupplierComponent
Public Shared Sub Insert(entity as Supplier)
mSupplierComponent.Insert(entity)
End Sub
Public Shared Sub Update(entity as Supplier)
mSupplierComponent.Update(entity)
End Sub
Public Shared Sub Delete(id as Integer)
mSupplierComponent.Delete(id)
End Sub
Public Shared Function GetById(id as Integer) as Supplier
return mSupplierComponent.GetById(id)
End Function
AjFirstExample.BusinessComponents tiene lógica de validación antes de grabar o insertar una entidad, y AjFirstExample.Data termina encargándose de la persistencia, usando un DataService, que yo había codificado dentro de algo que uso en mis cursos, AjFramework.
En las páginas web, es común conversar con el servicio, para tomar y enviar datos a ese proyecto:
Public Partial Class Admin_CustomersPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Load
'Put user code to initialize the page here
If Not IsPostBack Then
gvwData.DataSource = CustomerService.GetList
gvwData.DataBind()
End If
End Sub
End Class
Este ejemplo lo tienen también en ese mismo .zip implementada en C#. Van a ver que ha sido generada directamente por AjGenesis, el generador de código que uso para armar gran parte de mis ejemplos y del desarrollo del día a día que emprendo:
'
' File generated using AjGenesis
' http://www.ajlopez.com/ajgenesis
' http://www.ajlopez.net/ajgenesis
' Open Source Code Generation Engine
'
Si tienen que cambiar el string de conexión, deben modificar el web.config del proyecto web, en el sector:
<AjFramework>
<Parameters>
<Parameter Name="ConnectionString" Value="server=.\SQLEXPRESS;database=AjFirstExample;Integrated Security=true"/>
</Parameters>
</AjFramework>
Hay otro ejemplo para bajarse e instalar de la misma manera:
Con las mismas ideas:
pero con más entidades:
Cada departamento contiene empleados. Los proyectos contienen tareas, y las tareas se pueden asigna a empleados. Cada empleado tiene "Skills”, competencias, y cada competencia tiene empleados. Desde las páginas de administración, pueden ingresar los datos de estas entidades.
Sin embargo, la relación entre estas entidades, no está en la entidad misma, sino en cómo recuperamos los datos necesarios desde el servicio. En vez de tener dentro de Department una lista de Employee, los empleados de un departamento se obtienen desde código, ejemplo:
protected void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack) {
IdEntity = Convert.ToInt32(Request["Id"]);
Entity = DepartmentService.GetById(IdEntity);
dtgDataEmployees.DataSource = EmployeeService.GetByDepartmentEx(IdEntity);
DataBind();
}
}
Un ejemplo, donde usamos una base similar, pero en el código establecemos las relaciones, está en:
Acá usamos Linq2Sql
donde las entidades, generadas por el wizard de Linq2Sql, ya tienen las relaciones incorporadas. Entonces, una vez obtenido un Deparment, podemos pasar a Employees en una simple propiedad que tiene el objecto departamento:
protected void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!IsPostBack) {
LinqDepartmentsService service = new LinqDepartmentsService();
IdEntity = new Guid(Request["Id"]);
Entity = service.GetDepartment(IdEntity);
dtgDataEmployees.DataSource = Entity.Employees;
DataBind();
}
}
Un último ejemplo más, para este post rápido:
En este caso, seguimos usando Linq, lo que viaja a la presentación, son mensajes Windows Communication Foundation, hay un sitio web que expone servicios WCF, y de la parte del cliente, código de gateway para llegar a esos servicios:
En vez de llegar a la presentación las entidades de .Data, de Linq, pasamos mensajes de Data Contract de WCF:
namespace AjFirstExample.Services.Contracts
{
using System;
using System.Runtime.Serialization;
[DataContract]
public class Customer
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Notes { get; set; }
}
}
Bueno, espero que puedan sacar algo útil de estos ejemplo, vean también los archivos de ejemplos que fuimos desarrollando en cada clase.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com