Archive for the '10673' Category

Ejemplo ASP.NET usando Mere Mortals Framework

Wednesday, July 15th, 2009

Estuve trabajando, como un spike dentro del proyecto Medusa, para reproducir el ejemplo ASP.NET que viene descripto en el Mere Mortals Framework Developer’s Guide, que usa la base de datos MS SQL Northwind. Lo escribí usando VB.NET como lenguaje (en la guía de Mere Mortals, que pueden bajar del sitio del framework, se describe también en C#).

El sitio del framework es

Oak Leaf Products

Pueden bajar la guía de:

DOWNLOAD the MM .NET Developer’s Guide

Lo que escribí pueden bajarlo de mi Skydrive:

MMNorthwind.zip

Pueden cargar la solución en VS 2008 (tienen que tener las DLLs del Mere Mortals framework en su máquina).

La página que busca las órdenes de compra por código de cliente es CustomerOrders.aspx:

The first column is a link, that points to OrderEdit.aspx, where you can edit

Si necesitan cambiar la conexión a la base, pueden modificar el web.config:

Diferencias: no estoy usando procedimientos almacenados para todos los Business Objects, como hace el ejemplo original, sólo en los lugares que necesito. Se puso entonces que el tipo de comando asumido a enviar al framework es .Text, en vez de .StoredProcedures. Tampoco puse la misma master page del ejemplo.

En el proyecto Medusa, el equipo está trabajando para mejorar la validación de campos y reglas de negocios, y mensajes de error, generando una aplicación web completa, usando AjGenesis, partiendo de un modelo que nace de la base de datos.

Espero poder escribir y publicar templates y tareas de AjGenesis, para generar algo como el ejemplo de arriba: una aplicación web, pero desde un modelo como el que uso en mis otros ejemplos de AjGenesis. Keep tuned! 🙂

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/
http://twitter.com/ajlopez

Generando y regenerando texto y código con AjGenesis

Friday, June 26th, 2009

En estos días de Junio, se ha desarrollado el interesantísimo congreso de generación de código (digamos, “el mundial” del Code Generation), con un programa envidiable:

Code Generation 2009 – Daily Event Programme

Encuentro en Twitter

(uso TweetDeck, con search “code generation”)

el enlace a este post de Steven Kelly (de MetaCase) sobre

Code Generation 2009 round-up

donde levanta y comenta impresiones sobre la conferencia. Curiosamente (o no, ya a esta altura), Kelly también usa Twitter para tomar feedback:

EelcoVisser: keynote by @markusvoelter and Steven Kelly at #cg2009: great overview of issues in model-driven development

 

HBehrens: Steven Kelly at #cg2009 keynote: “wizard based generators create a large legacy application you’ve never seen before”

 

A esta última referencia, Kelly comenta y responde:

The reference was to vendor-supplied wizards, often found in IDEs or SDKs, that create skeleton applications for you based on your input. Since the vendors take pride in just how much boilerplate they can spew out, you’re left with a mass of generated code that you’ve never seen before, but must extend with your own code. Worse, you’re responsible for maintaining the whole ensuing mixture, and there’s no chance of re-running the wizard to change some of the choices — at least not without losing or invalidating the code you’ve added. That’s in sharp contrast with generation in DSM, where your input is in the form of a model which you can edit at any time. You get the speed of generation but can remain at a high level of abstraction throughout

Con DSM se refiere a Domain Specific Model. Pueden ver mis enlaces en http://delicious.com/ajlopez/dsm

Más info visitando el DSM Forum

Mi proyecto de código abierto AjGenesis está basado en modelo, en modelos de libre definición, justamente, orientados al dominio que uno quiera modelar. No son modelos gráficos, que son más “fancy”, pero hasta ahora, me han resultado útiles y flexibles. Traduciendo la cita de arriba, una de las quejas de Kelly es que hay herramientas que generan código, como un wizard dentro de un entorno de desarrollo, pero luego, cuando trabaja agregando código propio en la solución, ya no puede volver a regenerar código. Y que él ve una solución si partimos de un modelo específico de dominio. El modelo a partir puede ser la base de datos, un modelo abstracto de entidades, un modelo más orientado al sistema que estamos tratando de construir (me imagino modelos dedicados a CRM, o a mercados aún más verticales).

Bueno, el tema da para discutir. Prácticamente, ningún modelo produce todo lo que queremos, así que tenemos que dejar en nuestra aplicación, lugares, puntos de extensibilidad manual, forma de agregar código nuestro, sin que tengamos que perder lo generado. Y que sigamos teniendo la posibilidad, al cambiar el modelo inicial, de volver a generar la parte automática, sin perder lo agregado manualmente.

Desde hace algunos años, incluyo este “slide” en mis charlas sobre el tema. Explico que uno no genera todo, y que tiene que estar claro, cuales archivos de texto son generados, y luego regenerados desde el modelo cuantas veces uno quiera, cuáles son generados de una sola vez, y cuáles son agregados manualmente:

Uno tiene que decidir qué genera desde el modelo, y qué genera o agrega manualmente. Me encontrado con gente que utilizó AjGenesis sólo para generar los procedimientos almacenados. En el proyecto Medusa (que mencioné en mi post

Generación de código con AjGenesis para Mere Mortals Framework

)

estamos adoptando una solución en el sentido de la figura. Cuando lanzamos la generación automática desde el modelo, que incluye:

– Generación de scripts de generación de las tablas
– Generación de los procedimientos almacenados
– Generación de un proyecto de Business Objects (como pide el Mere Mortals Framework)
– Generación de una aplicación web ASP.NET (usando nuevamente el Mere Mortals Framework, por ejemplo, sus controles web)

hemos codificado las tareas, de tal forma que:

– Hay archivos que siempre se generan (se “pisa” la anterior versión, pero solamente si la nueva tiene un contenido distinto)
– Hay archivos que no se generan si ya existen (pocos archivos, que se han decidido ser “one shoot”, generados de una sola vez, y no más)
– Hay archivos que se respetan y no se generan (archivos que vamos agregando a los proyectos que vamos armando)

Estamos usando .NET. En el caso 2, caen las clases parciales, que es una forma de seguir especificando una clase, en un archivo adicional al original. En otras tecnologías, podríamos generar un archivo ClaseBase generado automáticamente, y un ClaseReal donde pudiéramos luego poner todo nuestro código manual.

Con esta estrategia, hemos alcanzado hasta ahora, gran parte de lo que imaginaba en la figura de arriba: poder generar siempre desde el modelo, sin tener que perder lo que ya tenemos.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Generación de código con AjGenesis para Mere Mortals Framework

Monday, June 22nd, 2009

En un proyecto en el que estoy trabajando, el equipo ágil del que soy miembro está desarrollando una aplicación completa de salud (es el Medusa Project), usando Mere Mortals framework como base para objestos de negocios, persistencia, y presentación en WinForm y ASP.NET. Pueden bajarse una versión de prueba de este framework en:

http://www.oakleafsd.com/

Hay una lista de características en

http://www.oakleafsd.com/MMNetFeatures/pgMMNetFeatures.htm

Pueden bajarse la guía de desarrollo de

MM .NET Developer’s Guide

El framework fue desarrollado por Kevin McNeish, Microsoft MVP, presidente y arquicecto jefe de Oak Leaf Enterprise. El framework soporta entidades tipadas, pero por abajo, está basado en datasets. Podemos generar un proyecto de business objects con templates de VS que vienen con el framework, y tiene un generador de código provisto por el producto, podemos generar las clases de objetos de negocios, derivadas desde la base de datos.

En mi equipo, alimentamos metadata leyendo información de la base de datos, y con esa información, generamos una aplicación web completa en ASP.NET, un librería de objetos de negocios, procedimientos almacenados, y DDL para regenerar la base. Todo usando AjGenesis, mi proyecto abierto de generación de código. Espero escribir algún post sobre esa experiencia. Las tareas y plantillas que usamos, han sido derivadas del ejemplo:

AjGenesis- Generating the model from the database
AjGenesis- Modelo desde la Base de Datos

En esto post, uso otra aproximación, más clásica en los ejemplos de AjGenesis: partir de un modelo abstracto, generando desde allí:

– Scripts para crear la base de datos
– Business Objects a la Mere Mortals en una librería de clases
– Proyecto WinForm con formularios de mantenimiento

Escribí sobre generación de aplicaciones en distintas tecnologías, desde un modelo abstracto, en:

Application Generation using AjGenesis
Generando aplicaciones con AjGenesis

pero recuerden: AjGenesis se basa en modelos de libre definición. Podemos modelar lo que querramos. Como ejemplo trivial:

Code Generation with AjGenesis- A Hello World application
Generando Código- Hello World con AjGenesis

El modelo

Pueden bajar el ejemplo desde la página de ejemplos del proyecto, en Codeplex:

MereMortalsExamples200906.zip

Contiene:

El modelo resido en el archivo Projects/AjFirstExample/Project.xml

<Project>

    <Name>AjFirstExample</Name>

    <Description>First Example using AjGenesis</Description>

    <Prefix>AjFE</Prefix>

    <Domain>com.ajlopez</Domain>

    <CompanyName>ajlopez</CompanyName>

    <Model>

        <Entities>

            <Entity Source="Entities/Customer.xml"/>

            <Entity Source="Entities/Supplier.xml"/>

        </Entities>

        <Lists>

            <List Entity="Customer"/>

            <List Entity="Supplier"/>

        </Lists>

        <Forms>

            <Form Entity="Customer"/>

            <Form Entity="Supplier"/>

        </Forms>

        <Views>

            <View Entity="Customer"/>

            <View Entity="Supplier"/>

        </Views>

    </Model>

</Project>

Referencia a dos entidades, Customer and Supplier. La entidad Customer:

<Entity>

    <Name>Customer</Name>

    <Description>Customer Entity</Description>

    <SetName>Customers</SetName>

    <Descriptor>Customer</Descriptor>

    <SetDescriptor>Customers</SetDescriptor>

    <SqlTable>Customers</SqlTable>

    

    <Properties>

 

        <Property>

            <Name>Id</Name>

            <Type>Id</Type>

        </Property>

 

        <Property>

            <Name>Name</Name>

            <Type>Text</Type>

            <SqlType>varchar(200)</SqlType>

        </Property>

 

        <Property>

            <Name>Address</Name>

            <Type>Text</Type>

            <SqlType>text</SqlType>

        </Property>

 

        <Property>

            <Name>Notes</Name>

            <Type>Text</Type>

            <SqlType>text</SqlType>

        </Property>

 

    </Properties>

</Entity>

 

Hay un modelo que describe la tecnología que vamos a usar en Projects/AjFirstExample/Technologies/VbNet3.xml:

<Technology>

    <Programming>

        <Dialect>VbNet3</Dialect>

    </Programming>

    <Database>

        <Dialect>MsSql</Dialect>

        <Name>AjFirstExampleMM</Name>

        <Host>(local)</Host>

    </Database>

</Technology>

Puede cambiar el host a .\SQLEXPRESS si no tiene un servidor MS SQL. Puede agregar <Username> y <Password> si quiere usar la seguridad de SQL. Si no están, el ejemplo usa seguridad integrada de Windows.

Generando la aplicación

Debe bajarse la versión liberada actual de AjGenesis, la 0.5, desde http://ajlgenesis.codeplex.com. Agregue el directorio bin a su lista de directorios en PATH. Hecho esto, podemos ejecutar desde el directorio del ejemplo:

GenerateProject.cmd AjFirstExample VbNet3

El primer parámetro es el nombre del proyecto, el segundo es la tecnología a usar. El comando invoca

AjGenesis.Console Projects\%Project%\Project.xml tasks\BuildProject.ajg  Projects\%Project%\Technologies\%Technology%.xml tasks\BuildTechnology.ajg tasks\BuildProg.ajg tasks\BuildSql.ajg

Esto lee el modelo de proyecto, ejecuta la tarea BuildProject, carga el modelo de tecnología, ejecuta la tarea de BuildTechnology. Finalmente, la tarea BuildProg genera el código, y BuildSql genera el DDL necesario para crear la base de datos.

Se crea un nuevo directorio, Build, que contiene el resultado:

En el directorio Sql, encontramos el comando ExecuteAll.cmd que crea la base de datos

Podemos ejecutarlo con un parámetro, especificando ahí el servidor:

ExecuteAll.cmd Bombadil

Si ejecutamos el comando sin parámetro, usa el host especificado en el modelo de tecnología.

En directorio Src encontraremos recién generada una solución .NET completa, con dos proyectos:

Podemos levantarla en Visual Studio 2008, y compilarla (necesitamos tener una versión de Mere Mortals Framework instalada).

La librería de clases contiene definiciones de objetos de negocios de Mere Mortals (usando clases parciales, clases de acceso a datos usando procedimientos almacenados, reglas….)

El proyecto WinForm tiene dos formularios de mantenimiento, para Customers y Suppliers:

Bueno, no será “uy que bruto, que aplicación”…. :-)… pero ejecuta:

Si no quieren seguir estos pasos, pueden bajarse la solución generada, de mi Skydrive

AjFirstExampleMereMortals.zip

Conclusiones

Usando un modelo abstracto, podemos generar los artefactos de textos que requiere el framework de Mere Mortals (o cualquier otro framework o tecnología como describí en Generación de código, AjGenesis, y Dunga dunga a la tecnología). Con clases parciales, y archivos separados, podemos regenerar código desde el modelo, sin perder el código manual que hayamos agregado. Podemos extender el código generado agregando validaciones automáticos, nuevas reglas, y cualquier estándar de codificación que estemos usando.

Pero el punto principal, para mí, es que usando un modelo abstracto, estamos separando el núcleo importante de nuestra aplicación, de los detalles técnicos´. Podemos regenerar la aplicación usando otro framework, otros lenguajes, otras tecnologías, y nuestro modelo podría ser el mismo. El modelo describe lo que queremos. Tareas, y plantillas terminan siendo un sistema experto, que conoce COMO obtener lo que queremos como aplicación.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com/en
http://twitter.com/ajlopez