Empezaremos detallando la parte principal de la aplicación: la capa de dominio. Aunque el ejemplo que nos ocupa consta simplemente de dos míseras clases, es importante que interioricemos algunos conceptos.
Diseñar un modelo de dominio es una tarea altamente compleja: definir las entidades que formaran parte de los agregados, el límite de éstos, qué entidad será el agregado raíz, distinguir value objects, etc. y, curiosamente, es la parte que menor relación tiene con CQRS.
Como siempre, la recomendación principal que puedo dar es la de leerse y empaparse del libro Domain-Driven Design de Eric Evans.
Muchas veces cuando se habla de Command-Query Responsibility Segregation (CQRS) empiezan a surgir conceptos tales como: Event Sourcing, 2-Phase Commit, Snapshots, mensajería asíncrona, eventual consistency y multitud más que hacen que mucha gente piense que CQRS es una arquitectura compleja y que solo se puede utilizar para desarrollar aplicaciones tipo Amazon, Twitter y Facebook (vamos, los proyectos que nos surgen cada día…).
Por el contrario, soy de la opinión de que el uso de este patrón nos permite implementar de forma exitosa una aplicación basada en Domain-Driven Design (DDD). Y es que no se entiende CQRS sin DDD.
Es decir, no hace falta implementar Amazon para utilizar DDD y CQRS pero tampoco vayamos a implementarlo en la web de la panadería de nuestro cuñado en Villaconejo del Monte.
En el pasado mes de Junio se publicó el artículo “Enrutamiento con WCF 4 y Routing Service” en la revista dotNetMania en el que se hablaba del patrón Intermediate Routing y de su implementación mediante WCF 4.
El artículo lo podéis leer en el nuevo sitio web de dNM+ en el siguiente enlace:
El próximo día 5 de mayo voy a estar con los chicos de SecondNug realizando un evento acerca de Command-Query Responsibility Segregation (CQRS) en el que hablaremos de:
Domain-Driven Design
Problemáticas en aplicaciones típicas n-layer
CQRS y conceptos: Commands, Events, Task based UI, etc.
Event Sourcing
Demo
Si queréis asistir sólo tenéis que registraros en el siguiente enlace:
NServiceBus es una implementación de Enterprise Service Bus (ESB) para .NET y que se apoya en Microsoft Message Queue Server (MSMQ) como transporte y persistencia de colas.
Enterprise Service Bus es una arquitectura que nos permite el intercambio de mensajes entre aplicaciones y servicios de manera desacoplada entre los mismos proporcionando la fiabilidad y manejo de errores que éste tipo de aplicaciones requiere.
Las diferencias entre Enterprise Service Bus y Enterprise Application Integration (EAI) como BizTalk y cuando usar uno u otro daría lugar a muchas discusiones y está fuera del alcance de éste humilde artículo.
NServiceBus proporciona varios patrones de mensajería OOB como One-Way, Request/Response y Publish/Subscribe aunque nos permite extenderlo según nuestras necesidades.
Ejemplo con mensajería One-Way
En este ejemplo veremos la comunicación asíncrona punto a punto. Aunque parezca a priori que podríamos conseguir los mismos resultados con netMsmqBinding y WCF, y en cierta manera así es, la verdad es que NServiceBus nos abstrae de muchas configuraciones que deberíamos realizar a mano: creación de las colas en MSMQ, habilitar permisos necesarios, etc.
Primero vamos a crear el proyecto Messages (Class library) con una referencia a la librería NServiceBus.dll. A continuación definiremos nuestro mensaje:
1
2
3
4
5
6
7
8
9
10
namespaceMessages
{
///<summary>
/// Esta clase será enviada por NServiceBus
///</summary>
publicclassMyMessage : IMessage
{
publicstring SomeString { get; set; }
}
}
La interface IMessage no obliga a implementar ningún método, simplemente se usa como marcador para NServiceBus.
En el artículo de hoy vamos a ver qué fácil es alimentar mediante Ajax y objetos JSON componentes jQuery desde ASP.NET MVC.
Para empezar, vamos a usar la CDN de google para importar las librerías que necesitamos: jQuery y jQuery UI más los ficheros de estilos para jQuery UI:
El código cliente para enlazar la extensión de jQuery a la caja de texto es la siguiente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/javascript">
$(document).ready(function () {
$("#txtTitulos").autocomplete({
minLength: 3,
source: getData
});
});
functiongetData(request, response) {
$.ajax({
url: '/Home/GetData',
type: 'GET',
dataType: 'json',
data: { words: request.term },
success: function (data) {
response(data);
}
});
}
</script>
Como podemos ver, inicializamos la opción source con nuestro propio callback getData. En que realizamos la consulta a la action GetData del controller Home. Para más opciones y eventos del componente autocomplete mirad la documentación en la página de jQuery UI.
Finalmente nuestra action GetData queda de la siguiente manera:
Si os fijáis en el segundo parámetro de Json, indicamos que admitimos peticiones de tipo GET. Esto se debe indicar para evitar problemas de seguridad. Para más información consultad este post de Phil Haack.
Los datos de ejemplo los he sacado del rss de la página de ASP.NET. Os dejo el código para que no es creáis que miento:
1
2
3
4
5
6
7
8
9
10
11
12
private IEnumerable<SyndicationItem> GetData()
{
string feed = "http://www.asp.net/rss/news";
var req = WebRequest.Create(feed);
using (var reader = XmlReader.Create(req.GetResponse().GetResponseStream()))
Obtenemos una referencia al formulario con la instrucción: $(this).parent(“form”) y a continuación cambiamos los atributos action y method del formulario. De esta forma, hacemos submit a la acción que nos interesa en cada momento utilizando GET o POST según convenga.
El propósito de este post es ver cómo podemos paginar de forma óptima en servidor mediante el objeto DetachedCriteria. El objetivo es evitar que nuestros controles de presentación hagan el trabajo sucio paginando en memoria los resultados al obtener todos los elementos de la base de datos en cada petición.
Por trivial que parezca, para poder mostrar los resultados de forma amigable al usuario en, por ejemplo un grid, la consulta debe devolver los elementos de la página en cuestión y el número total de elementos. Para ello se requieren dos consultas, una para los elementos y otra para el total, pero no suena muy práctico realizar dos consultas separadamente no? La gracia aquí está en agrupar las dos consultas en una y así optimizar el rendimiento.
Nota: En caso de utilizar directamente un objeto de tipo ICriteria podríamos hacer uso directamente de las clausulas Future y FutureValue que hacen internamente hacen uso de Multi Queries como haremos aquí. Más información en éste post de Ayende.
Antes de nada… Que es DetachedCriteria? Pues no deja de ser un objeto criteria que definimos sin tener acceso a ISession. Esto nos permite definir nuestras consultas y poderlas ejecutar más tarde en cualquier otra parte dentro de un contexto de ISession.
A continuación vemos una declaración típica para DetachedCriteria:
1
2
3
4
5
6
7
8
9
// Creamos el objeto DetachedCriteria
var detachedCriteria = DetachedCriteria.For<Customer>("c");
En este pequeño post hemos visto como con IMultiCriteria y NHibernate podemos hacer paginaciones optimizadas en servidor para que nuestros controles de presentación no tengan que hacer los cálculos en memoria obteniendo todos los datos de la base de datos en cada petición.