RIA Services: Cómo compartir código entre el cliente y el servidor

En este post seguiremos profundizando en algunas de las características que nos ofrece RIA Services.

En este caso vamos a ver, cómo de una manera muy sencilla, podemos compartir código entre el cliente y el servidor.

Pues es tan fácil como establecer el nombre del fichero con la nomenclatura XXXX.shared.cs, por ejemplo ShareEntity.shared.cs.

Al compilar los ficheros con esta nomenclatura se copian al proyecto cliente, para que se compilen también con este proyecto.

En esta imagen podéis ver cómo el fichero que he creado en el servidor, se ha copiado al cliente.

image 

 

Y aunque no es necesario, también podemos usar el atributo Shared para dejar claro, que esta clase se comparte.

using System.Web.Ria.Data;

namespace SilverlightApplicationDemo.Web
{
    [Shared]
    public class SharedEntity
    {
        public string MyProperty { get; set; }
    }
}

En futuros post veremos algún ejemplo dónde esta funcionalidad nos vendrá muy bien, como a la hora de definir validadores personalizados para las entidades…pero eso, será otro post 🙂

Roadmap de RIA Services

Últimamente he escrito varios post hablando de esta tecnología y ya sois varios los que me habéis preguntado por el estado de esta tecnología.

Comentaros que de momento lo único que hay es una preview, la última de mes de mayo, y que al menos yo no haría nada real con esta versión.

Me parece un poco temprano y todavía le queda bastante por evolucionar, aunque lo que hay hasta ahora tiene buena pinta y dan ganas de tenerlo ya mismo. A partir de la versión beta podría ya plantearme usarla…

El roadmap de esta tecnología lo podéis ver aquí. Una de las características que me parece más interesante es la integración con ADO.NET Data Services para poder exponer los dominios.

Os hago un copy-paste para los que os dé pereza pinchar en el enlace :-).

July 2009 CTP

  • This is a preview, not the V1 release. We plan to drop go-live restriction from EULA – still use it at your own risk.

  • Try to get significant known breaking changes (the ones we don’t know about will come later)

  • Feature enhancements (e.g. code-gen hookpoints to add your custom code, improved library support, better shared code support, query for singletons, cleaner user model and better extensibility support for Application Services etc.)

  • Usual fare of bug fixes, API improvements etc

  • Enable a first set of better together experiences with  ADO.NET Data Services (add a DomainService to Data Service for writing app logic / expose DomainService as DataService)

PDC 2009 Beta

  • Additional core feature work (list TBD, under consideration – hierarchy support, presentation model)

  • Work on Visual Studio 2010 / .NET 4 support

    • Drag-drop support for databinding

    • Run in medium trust

  • Move to ADO.NET Data Services as the underlying protocol

First part of 2010: RTW

  • Polish beta release (bugs, perf, stress, security, localization, …)

  • Small design changes / tweaks

  • Keep up with changes in other products

RIA Services y DomainDataSource

Seguro que ya todos conocéis los DataSources que tenemos actualmente disponibles en ASP.NET (XmlDataSource, SqlDataSource, ObjectDataSource, EntityDataSource etc…) y lo mucho que nos facilitan el desarrollo.

Pues bien, con RIA Services tendremos uno nuevo; DomainDataSource. Este componente es muy similar al resto de DataSources (la idea es la misma) y nos va permitir trabajar de una manera bastante cómoda y sencilla contra servicios de dominio que se exponen con RIA Services.

Usando este componente que nos ofrece RIA Services y otros que se incluyen dentro de Silverlight 3 el desarrollo de aplicaciones guiadas por datos se va agilizar enormemente en este tipo de aplicaciones.

En este post vamos a ver un ejemplo usando Silverlight aunque tened en cuenta que el componente DomainDataSource también se puede usar en aplicaciones ASP.NET tradicionales o para montar aplicaciones con Dynamic Data, no es algo sólo para Silverlight.

Continuaremos con un ejemplo que vimos en un post anterior. En ese post creábamos una aplicación Silverlight que mostraba un grid con los datos de la tabla de proveedores.

Haciendo uso de Entity Framework y RIA Services exponíamos la entidad Suppliers de la base de datos Northwind y la consumíamos desde un cliente RIA.

EL código que empleaba para enlazar el componente dataGrid con el servidor era el siguiente:

13

A continuación vamos a ver otra alternativa, que es usar el control DomainDataSource, que además de enlazar el datagrid con el servidor nos va a dar, de una manera sencilla, funcionalidades tan típicas como la ordenación, el filtrado o la paginación.

El primer paso es añadir el control DomainDataSource a la caja de herramientas (Choose Toolbox Items>Silverlight Components). Este componente se encuentra en el ensamblado System.Windows.Ria.Controls.dll, que estará úbicado en %ProgramFiles%Microsoft SDKsRIA Servicesv1.0LibrariesSilverlight.

image

Una vez que lo tenemos incluido, ya podemos arrastrarlo a nuestro código XAML.

Añadimos xmlns:ds="clr-namespace:SilverlightApplicationDemo.Web para hacer referencia al dominio que vamos a usar e incluimos el siguiente código, dónde incluimos el control DomainDataSource y el control dataGrid.

<riaControls:DomainDataSource x:Name="suppliersDataSource" LoadSize="20" 
    LoadMethodName="LoadSuppliers" AutoLoad="True" >
    <riaControls:DomainDataSource.DomainContext>
        <ds:SuppliersContext/>
    </riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
            
<data:DataGrid Name="gridRiaDemo" Width="Auto"
    ItemsSource="{Binding Data, ElementName=suppliersDataSource}">
</data:DataGrid>

Al dataGrid le indicamos que debe usar el DomainDataSource a través de la propiedad ItemSource y al DomainDataSource le indicamos el dominio que debe usar, en nuestra caso SuppliersContext. También fijaros que en el DomainDataSource indicamos el método al que debe llamar.

Como veis, el control DomainDataSource se comporta y se configura de manera muy similar al resto de DataSources. Por ejemplo, al usar un ObjectDataSource se debe indicar la clase y el método al que hay que llamar….pues en este caso, lo único que cambia es que hay que en lugar de especificar la clase que contiene el método, se indica el DomainContext.

image

Una vez que ya tenemos la funcionalidad básica, podemos ir añadiendo alguna otra.

Si queremos añadir paginación a nuestro grid lo podemos hacer de una manera muy sencilla, haciendo uso del control DataPager de Silverlight:

<dataControls:DataPager PageSize="5" 
    Source="{Binding Data, ElementName=suppliersDataSource}">                    
</dataControls:DataPager>

image

Y si queremos incluir la posibilidad de ordenar nuestro grid cuando pinchamos sobre las columnas? Pues también muy sencillo, ya que el DomainDataSource nos ofrece esta funcionalidad.

Dentro del tag DomainDataSource, justo debajo de la definición del DomainContext añadimos el siguiente código, con la cuál ya soportamos ordenación por cualquiera de las columnas del grid.

<riaControls:DomainDataSource.SortDescriptors>
    <riaData:SortDescriptor PropertyPath="City" Direction="Ascending" />
</riaControls:DomainDataSource.SortDescriptors>

Y ahora toca añadir la funcionalidad de filtrado. Por ejemplo, podríamos tener un textbox para poder indicar el nombre de la ciudad por la que queremos filtrar y en función de las letras que vamos introduciendo, que se vaya filtrando.

image

Dentro del tag DomainDataSource podemos añadir el siguiente código XAML, dónde indicamos que queremos filtrar por el campo City y que queremos buscar las ciudades que empiecen por las letras que introduzcamos en el control cityText.

<riaControls:DomainDataSource.FilterDescriptors>
    <riaData:FilterDescriptorCollection>
        <riaData:FilterDescriptor 
                PropertyPath="City" 
                Operator="StartsWith">
            <riaData:ControlParameter 
                ControlName="cityText"  
                PropertyName="Text" 
                RefreshEventName="TextChanged" />
        </riaData:FilterDescriptor>
    </riaData:FilterDescriptorCollection>
</riaControls:DomainDataSource.FilterDescriptors>

Por si estáis interesado en repetir los ejemplos que os estoy mostrando, recordad que tendréis que añadir alguna definición extra en al inicio del XAML. Aquí os pongo todas las que he usado yo en los ejemplos:

<UserControl 
    xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm"  
    xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"  
    xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  
    x:Class="SilverlightApplicationDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ds="clr-namespace:SilverlightApplicationDemo.Web">

RIA Services: Sobre la generación de código…

En dos anteriores veíamos un ejemplo de cómo funciona RIA Services y de cómo nos puede facilitar la creación de aplicaciones RIA.

En el ejemplo veíamos cómo al crear el DomainService usando la entidad Suppliers se generaba el código que pongo a continuación y cómo de manera automática se generaban las clases proxys en el cliente que posibilitan que se puede acceder fácilmente desde el cliente al servidor.

[EnableClientAccess()]
public class SuppliersService : LinqToEntitiesDomainService<NorthwindEntities>
{
    public IQueryable<Suppliers> GetSuppliers()
    {
        return this.Context.Suppliers;
    }

    public void InsertSuppliers(Suppliers suppliers)
    {
        this.Context.AddToSuppliers(suppliers);
    }

    public void UpdateSuppliers(Suppliers currentSuppliers, Suppliers originalSuppliers)
    {
        this.Context.AttachAsModified(currentSuppliers, originalSuppliers);
    }

    public void DeleteSuppliers(Suppliers suppliers)
    {
        if ((suppliers.EntityState == EntityState.Detached))
        {
            this.Context.Attach(suppliers);
        }
        this.Context.DeleteObject(suppliers);
    }
}

El atributo EnableClientAccess que lleva la clase y el hecho de que ambos proyectos “estén unidos” hace que al crear o cambiar los servicios del servidor ( DomainService ) se creen los proxys necesarios en el cliente ( DomainContext ).

El proceso de generación de código automático es capaz de examinar todos los ensamblados del proyecto servidor buscando las clases marcadas con el atributo EnableClientAccess y buscar dentro de esta clase las entidades y operaciones expuestas.

Una cosa que no habíamos mencionado hasta ahora, es que el nombre de los métodos que se incluyen no es un nombre al azar y siguen una nomenclatura fija. En el código superior se puede ver cómo es el código.

A continuación pongo las reglas que sigue:

  • Operación Select.
    • IQueryable<Entity> GetXXX ( )
    • Debe empezar con los prefijos Get, Fetch, Find, Query, Retrieve o Select.
    • En el cliente cualquiera de los prefijos se cambia a Load.
  • Operación de inserción.
    • InsertXXX ( NewEntity )
    • Debe empezar con prefijos Insert, Add o Create.
    • NewEntity es el tipo de la entidad nueva que se añade.
    • Siempre devuelve void.
  • Operación de actualización.
    • UpdateXXX ( changedEntity, originalEntity )
    • Debe empezar con los prefijos Update, Change o Modify.
    • changedEntity es la entidad con los cambios y originalEntity la original.
  • Operación de borrado.
    • DeleteXXX ( Entity )
    • Debe empezar con los prefijos Update o Remove.
    • Entity es el tipo de la entidad sobre la que realiza la operación.

En el caso de la operación Select al generar el proxy cliente ya veíamos en el ejemplo anterior cómo los método cambian el prefijo por la palabra Load.

[LoadMethod(typeof(Suppliers))]
public void LoadSuppliers()
{
    this.LoadSuppliers(null, MergeOption.KeepCurrentValues, null);
}

Si queremos que no haga ninguna modificación y que mantenga el nombre que ponemos en el servidor, podemos conseguirlo usando el atributo PreserveName.

[Query(PreserveName=true)]
public IQueryable<Suppliers> GetSuppliers()
{
    return this.Context.Suppliers;
}

¿Y qué pasa si quiero usar mis propios nombres? Pues que también puedes, pero usando atributos para indicar la operación que ofrece el método.

Los atributos que se usan son Get, Insert, Update o Delete. De esta manera, aunque el método se llama diferente, el generador de código sabrá de qué operación se trata y que tiene que hacerla accesible desde el cliente.

[Query]
public IQueryable<Suppliers> MyMethodGet()
{
    return this.Context.Suppliers;
}
[Insert]
public void MyMethodInsert(Suppliers suppliers)
{
    this.Context.AddToSuppliers(suppliers);
}

RIA Services: Paso a paso (II)

En un post anterior hablaba sobre RIA Services y empecé con un ejemplo sencillo de cómo crear una aplicación con RIA Services.

En este post toca explicar en más detalles algunas de las cosas que vimos en ese post anterior.

Al crear el DomainService aparecía un diálogo como este:

9_thumb1

Si una vez generado el DomainService, vamos al fichero SuppliersService.cs veremos que el código que se ha generado es el siguiente:

[EnableClientAccess()]
public class SuppliersService : LinqToEntitiesDomainService<NorthwindEntities>
{
    public IQueryable<Suppliers> GetSuppliers()
    {
        return this.Context.Suppliers;
    }

    public void InsertSuppliers(Suppliers suppliers)
    {
        this.Context.AddToSuppliers(suppliers);
    }

    public void UpdateSuppliers(Suppliers currentSuppliers, Suppliers originalSuppliers)
    {
        this.Context.AttachAsModified(currentSuppliers, originalSuppliers);
    }

    public void DeleteSuppliers(Suppliers suppliers)
    {
        if ((suppliers.EntityState == EntityState.Detached))
        {
            this.Context.Attach(suppliers);
        }
        this.Context.DeleteObject(suppliers);
    }
}
 
Es una clase que deriva de LinqToEntitiesDomainService y como característica especial destacar que está decorada con el atributo EnableClientAccess, que es la manera de decir que esta clase tiene que estar accesible desde el proyecto cliente.
 
También observar que se han generado los método típicos de cualquier aplicación guiada por datos. Se han creado los métodos y las llamadas necesarias al modelo de Entity Framework para realizar las opciones CRUD ( Create/Read/Update/Delete).
En este caso, las llamadas son llamadas directas al modelo, pero en esta clase podríamos incluir toda la lógica que consideremos para cubrir la funcionalidad que necesitemos en la aplicación.
 
Por cierto, si en el diálogo de creación del servicio no hubiéramos seleccionado la opción “Enable Editing”, sólo se hubiera creado el método GetSuppliers.
 
Después de generar el servicio y compilar la solución, veremos cómo automáticamente se ha creado el proxy en el cliente. Para poder verlo es necesario seleccionar la opción “Show All Files”.
 
11
 
El atributo EnableClientAccess y el hecho de que ambos proyectos “estén unidos” hace que al crear o cambiar los servicios del servidor ( DomainService ) se creen los proxys necesarios en el cliente ( DomainContext ).
 
RIA3
 
Fijaros cómo en el cliente se accede a través de SupplierContext y cómo en lugar de llamarse el método GetSuppliers, como está en el DomainService, se llama LoadSuppliers. Este cambio lo hace RIA Services y en un post posterior veremos por qué lo hace.
 
 
 13_thumb3
 
Por completar el ejemplo anterior, vamos a hacer que en el grid de datos sólo se muestren los proveedores que de una determinada ciudad.
 
Para ello, vamos a añadir un nuevo parámetro al método GetSuppliers del servicio de dominio. También añadiremos la sentencia de LINQ to Entities necesaria para obtener la información que nos interesa del modelo.
 
public IQueryable<Suppliers> GetSuppliers(string city)
{
    return (from c in this.Context.Suppliers
            where c.City == city
            select c);
}
 
Una vez realizado este cambio en el cliente tendremos ya accesible el nuevo método con el parámetro, sin hacer nada más.
 
SuppliersContext context = new SuppliersContext();
gridRiaDemo.ItemsSource = context.Suppliers;
context.LoadSuppliers("London");

17

En esta solución hemos modificado el servidor, para que exponga un método con el parámetro por el que queremos filtrar, pero sin cambiar el método GetSuppliers, sin añadir el parámetro, también podríamos usar una sobrecarga que se genera en el proxy cliente para obtener el mismo resultado:

18

Esto es posible porque al generarse el proxy en el cliente no se genera única y exclusivamente el método que exponemos. Por cada método se crean tres sobrecargas distintas en el cliente, que nos permiten cosas como las que acabamos de ver.

Si vemos el código generado veremos lo siguiente:

#region LoadSuppliers method overloads
/// <summary>
/// Invokes the server-side method 'GetSuppliers' and loads the result into <see cref="Suppliers"/>.
/// </summary>
[LoadMethod(typeof(Suppliers))]
public void LoadSuppliers()
{
    this.LoadSuppliers(null, MergeOption.KeepCurrentValues, null);
}

/// <summary>
/// Invokes the server-side method 'GetSuppliers' and loads the result into <see cref="Suppliers"/>.
/// </summary>
[LoadMethod(typeof(Suppliers))]
public void LoadSuppliers(IQueryable<Suppliers> query, object userState)
{
    this.LoadSuppliers(query, MergeOption.KeepCurrentValues, userState);
}

/// <summary>
/// Invokes the server-side method 'GetSuppliers' and loads the result into <see cref="Suppliers"/>.
/// </summary>
[LoadMethod(typeof(Suppliers))]
public void LoadSuppliers(IQueryable<Suppliers> query, MergeOption mergeOption, object userState)
{
    base.Load("GetSuppliers", null, query, mergeOption, userState);
}
#endregion

Y hasta aquí este post, espero poder escribir algún otro prontito para seguir explicando algunos detalles interesantes de RIA Services.

RIA Services: Paso a paso (I)

Es un post anterior hablaba de RIA Services y de cómo esta nueva tecnología nos puede ayudar a simplificar el desarrollo de aplicaciones RIA

En este post toca empezar con la práctica y enseñar paso a paso un ejemplo básico de lo que es. Vamos a hacer un ejemplo muy sencillo usando la base de datos Northwind. Crearemos una aplicación Silverlight que muestre en un grid la lista de proveedores.

Si queréis repetir los ejemplos que aquí os enseño necesitareis tener instalado Silverlight 3 y la preview de mayo de RIA Services.

Lo primero será crear una nueva aplicación Silverlight; Silverlight Application.

1

Una seleccionado este tipo de proyecto os aparecerá un cuadro de diálogo, que sólo os aparecerá si tenéis instalado RIA Services.

2.1

Para que la aplicación sea una aplicación que haga uso de la funcionalidad de RIA Services, es necesario seleccionar la opción  “Link to ASP.NET server project”. Si no se selecciona esta opción la aplicación será una aplicación Silverlight normal y corriente.

Una vez seleccionada esta opción, se generarán dos proyectos dentro de la solución que se acaba de crear; un proyecto que contiene la aplicación Silverlight, la aplicación que hará de cliente, y una aplicación web, que contendrá el código de servidor.

Este segundo proyecto es el que se ejecutará en el servidor y el que contendrá toda la lógica de negocio y acceso a datos que necesite la aplicación. El primer proyecto es la parte cliente, la que se ejecuta en el navegador de cliente y la que tiene que consumir los servicios que el servidor le ofrezca.

3

Si ya tenemos nuestra aplicación Silverlight creada o la hemos creado sin la opción de unirla a un proyecto web no te preocupes, a posteriori también se puede hacer a través de las opciones del proyecto.

4

Una vez que tenemos creada la estructura de nuestra aplicación, en el proyecto servidor, vamos a crear todo lo necesario para exponer al cliente la lista de proveedores.

Para el ejemplo vamos a usar un diagrama de ADO.NET Entity Framework, pero tenemos que tener en cuenta que para usar RIA Services no tenemos por qué hacer uso de una base de datos ni de Entity Framework.

Eso sí, si necesitamos hacer uso de una base de datos, Entity Framework puede ser el complemento perfecto.

Agregamos un nuevo elemento al proyecto; ADO.NET Entity Data Model. Al nuevo diagrama le llamamos Northwind.

5

Una vez creado nos aparecerá un asistente que nos permitirá crear el diagrama de Entity Framework. Para este ejemplos seleccionaremos únicamente la tabla Suppliers.

En los ejemplos que veremos haremos uso de Entity Framework pero no entraremos lo pasaremos sólo por encima sin entrar a explicar todas las posibilidades que nos ofrece. Para ello, os recomiendo el libro “ADO.NET Entity Framework”, un libro en castellano de Unai Zorrilla, Octavio Hernández y Eduardo Quintás y que la editorial Krasis ha publicado. Un libro fantástico y además en castellano!

6

7

Una vez creado nuestro modelo de datos, tenemos que crear el servicio encargado de exponer nuestro dominio, para que el cliente pueda consumirlo. Este es el componente DomainServices del que hablábamos en el post anterior.

Añadiremos un nuevo elemento de tipo “Domain Service Class” y le llamaremos SuppliersService. Esta plantilla es una de las que incorpora RIA Services.

8

Una vez seleccionado este elemento, nos aparecerá este cuadro de diálogo desde el cual podemos configurar la parte del modelo de datos que queremos exponer. En este caso la cosa es sencilla, ya que sólo tenemos la entidad Suppliers.

9

Seleccionamos también la opción de permitir edición y la opción de generar las clases de metadatos asociadas. En los siguientes post entraremos a explicar para que sirve cada opción y efectos tiene seleccionar o no la opción.

Una vez realizada esta opción ya tenemos creado nuestro DomainService que expone la entidad Suppliers del model Northwind. Ahora vamos a ver cómo lo consumimos desde el cliente.

En el proyecto, en el el fichero Main.xaml vamos a añadir un componente DataGrid, que será el que muestre el listado de proveedores.

12

Una vez que tenemos el grid, en el codebehind añadiremos el código necesario para cargar en el grid el listado de proveedores.

13

Fijaros que en ningún momento he creado un proxy al servicio que expone el modelo Northwind, pero aún así, lo tenemos accesible!

Y si ejecutamos este código tendremos la lista de proveedores..

14 

y se acabó, ya tenemos nuestra aplicación RIA funcionando!

En el próximo post entraré a explicar con más detalle algunos de los aspectos que hoy he mencionado pero que no he entrado a explicar, como el código generado al crear el DomainService o cómo el cliente puede hacer uso del servicio sin haber creado un proxy previamente.

Pruebas unitarias: Resumiendo.

Aquí os dejo un resumen actualizado de una serie de post que pueden ser muy útiles para aquellos que estéis interesados en pruebas unitarias:

Otros post relacionados:

Webcast:

Más post interesantes de otros compañeros de geeks:

Y alguno de el Bruno sobre VStudio 2010:

¿Qué son los RIA Services?

Las aplicaciones RIA  (Rich Internet Application) están cada vez más de moda, ya que entre otras nos permiten ofrecer una mejor experiencia de usuario. (pero pagando un coste….)

A lo largo de este post voy a intentar explicar, de una manera resumida y simplificada, los principales conceptos de RIA Services y para qué nos puede servir. Vamos a ver si lo consigo…

La arquitectura de una aplicación Web tradicional sería la siguiente:

RIA

Exceptuando ciertas funcionales Ajax que pueden suponer una parte “menor” del total, en las aplicaciones web tradicionales las diferentes capas lógicas (lógica de presentación, lógica de negocio, acceso a datos..) de las que está compuesta se distribuyen generalmente en dos capas físicas que se encuentran en el servidor.

En la parte cliente lo que tenemos es el código HTML que el servidor nos devuelve.

Una aplicación RIA sería algo así:

RIA2

El desarrollo de una aplicación RIA supone desplazar una de las capas lógicas de la aplicación, la capa de presentación, a la parte cliente, convirtiéndole a éste en un “cliente pesado”…En el cliente tenemos parte de la aplicación, no sólo HTML.

Por ejemplo, en el caso de crear una aplicación Silverligth éste sería el caso dónde nos encontraríamos. La aplicación corre en el cliente y en éste dónde se ejecuta.

Pero claro, llevar esta parte al cliente no es gratis, ya que se complican las comunicaciones entre la lógica de presentación y la lógica de negocio.

En el caso de aplicaciones web tradicionales la lógica de presentación y de negocio suelen estar dentro de la misma capa física, por lo que la comunicación entre ambas no supone ninguna complejidad.

Si entre ambas capas metemos “internet”, la comunicación ya no se puede hacer de manera directa y tendremos que pensar en desarrollar una capa de servicios en el servidor que el cliente pueda consumir, lo que complica el desarrollo, aumentando los tiempos y problemas con los que nos podemos encontrar: Crear la capa de servicios, exponer los métodos que necesita, crear proxys, validación, autenticación…

¿Cuál es el objetivo de RIA Services? 

Pues el objetivo de RIA Services es simplificar el desarrollo de aplicaciones RIA, para que podemos desarrollar aplicaciones de este tipo como si fuesen aplicaciones web tradicionales, sin tener que preocuparnos de los aspectos que mencionaba en el párrafo anterior.

Beneficiarnos de todas las bondades de tener aplicaciones RIA pero sin pagar un coste por ello (al menos no uno excesivo), pudiendo hacerlo de una manera similar al que si hiciésemos aplicaciones web tradicionales.

En algunos sitios he visto que definían RIA Services como las herramientas RAD de Microsoft para la construcción de aplicaciones RIA…no sé si será para tanto 🙂

RIA Services nos va a servir de pegamento entre la lógica de presentación y la lógica de negocio para simplificar la comunicación entre ambas, permitiéndonos centrarnos en el desarrollo de la aplicación propiamente dicha.

En la arquitectura que se presenta a continuación podéis ver dos nuevos componentes que aporta RIA Services, uno en la parte cliente ( DomainContext ) y otro en la parte servidora ( DomainService ). RIA3

Seguro que ya todos conocéis los DataSources que tenemos actualmente disponibles en ASP.NET (XmlDataSource, SqlDataSource, ObjectDataSource, EntityDataSource etc…) y lo mucho que nos facilitan el desarrollo.

Pues bien, con RIA Services tendremos uno nuevo; DomainDataSource. Este componente es muy similar al resto de DataSources (la idea es la misma) y nos va permitir trabajar de una manera bastante cómoda y sencilla contra servicios de dominio que se exponen con RIA Services.

Por ejemplo, en una aplicación RIA hecha con Silverlight podemos tener los típicos formularios de lista/detalles, con las operaciones de selección, inserción, actualización, borrado, filtrado y ordenación como si de una aplicación web tradicional se tratase.

Por cierto, aunque menciono Silverlight, el componente DomainDataSource también se puede usar en aplicaciones ASP.NET tradicionales o para montar aplicaciones con Dynamic Data, no es algo sólo para Silverlight.

RIA4

Bueno, no me voy a extender mucho más, porque considero que lo mejor para entender qué es y cómo funciona RIA Services va a ser mediantes ejemplos, así que en los próximos post intentará ir publicando algunos ejemplos que puedan mostrar cómo funciona.

[Evento] SecondNUG. La historia continua…pruebas unitarias II

El pasado 2 de junio debuté en Second Nug hablando sobre cómo hacer pruebas unitarias con Visual Studio Team System.

Como ya habíamos avisado, el tema da para mucho y dos horas es un tiempo muy limitado. Por este motivo, decidimos orientar la charla desde un punto de vista “básico” para que gente que quisiera iniciarse en este temática pudiera hacerlo.

Ahora ha llegado el momento de seguir profundizando en la materia.

El día 16 de junio tendremos otras dos horas para continuar con la charla anterior y abordar aspectos que no se han tratado en la primera charla.

La sesión será totalmente práctica e intentará explicar los recursos que nos ofrece el framework de Visual Studio para poder hacer pruebas unitarias sobre los diferentes componentes que nos podemos encontrar en una arquitectura típica de una aplicación; acceso a datos, procedimientos almacenados, lógica negocio, interfaz ASP.NET, servicios web etc..

 

pruebas_unitarias_2

Para aquellos que estéis interesados en el evento os pongo unos enlaces que os resultarán útiles:

Para aquellos que no hayáis podido estar en la primera charla y que estéis interesados en el tema, recordad que desde la página de Second NUG pueden descargarse las sesiones.

Otra de la versión GDR: No se genera el fichero .sql al compilar el proyecto

Hace unos días comentaba que al migrar a la versión GDR de Visual Studio Database Edition me había encontrado con un problema en la migración de los proyectos de la versión anterior.

Ahora me encuentro con otra situación inesperada y que me ha implicado algo más de trabajo.

Con la versión anterior de Database Edition, al compilar el proyecto de base de datos se generaba el script de despliegue, el fichero .sql.

A mí este comportamiento me resultaba muy útil, porque en las compilaciones automática que tengo, después de compilar estos tipos de proyectos obtenía estos ficheros de despliegue, que son los que uso para desplegar la base de datos en mis entornos de pruebas y producción.

Pues con la versión GDR el comportamiento ha cambiado. Con la opción “Build” no se genera este fichero. Sólo se genera al hacer la acción “Deploy”.

Si como yo necesitas poder obtener este fichero en la compilación diaria tienes varias alternativas.

Si usas Team Build para automatizar tus compilaciones puedes usar una tarea como esta:

<Target Name="AfterCompileConfiguration">   
  <MSBuild Projects="$(SolutionRoot)MyProjectMyProjectMyProject.dbproj"  
   Properties="Configuration=$(Configuration);   
                    OutDir=$(BinariesRoot)$(Configuration)"   
   Targets="Deploy" />  
</Target>  

Y si no usas Team Build tienes otra alternativa que es lanzar desde línea de comandos la siguiente sentencia:

MSBuild /t:Deploy PathDatabaseProject.dbproj