WCF RIA Services. Resumen

Después de echar la bronca a un “mal” compañero por no leerme y preguntarme sobre RIA Services, he decidido poneros un pequeño recopilatorio de los post que he escrito sobre WCF RIA Services y así el que quiera pueda ponerse un poco al día en esta tecnología.

Algunos post está hechos con las versiones previews pero en esencia es lo mismo. Espero que os sea de utilidad!

Destripando la comunicación de WCF RIA Services

Ya un post anterior hablaba de cómo RIA Services se ha integrado dentro de WCF. En ese post anterior lo poníamos a prueba y veíamos cómo realmente es WCF, que no nos engañaban!

En este post toca ver en detalle algunas cosas sobre cómo se produce esta integración.

Una de las cosas que vimos es cómo al crear la aplicación, el DomainService crea un servicio WCF implícito, que el cliente es capaz de instanciar y usar para realizar las peticiones, siendo la estructura del servicio la siguiente:

http://[hostname]/[namespacename]-[classname].svc

Por ejemplo, http://localhost:XXX/BusinessAplication1-Web-OrganizationService.svc (BussinessApplication1-Web es el nombre del namespace,cambiando el punto por un guión )

WCF RIA Services implementa su propio ServiceHost ( DomainServiceHost ), el cual expone tres endpoints; WebHttpBinding (REST + JSON), BasicHttpBinding (SOAP+XML) y BinaryHttpBinding (SOAP+Binario), siendo éste último el que se usa por defecto.

Si queremos cambiar el endpoint que se utiliza en la comunicación cliente-servidor, simplemente tenemos que indicar la dirección del endpoint que queremos usar al crear el DomainContext en el cliente:

OrganizationContext ctx = OrganizationContext(new Uri("BusinessApplication1-Web-OrganizationService.svc/soap", UriKind.Relative)));
 
Aunque el servicio se crea de forma implítica, comentaros que también lo podemos crear de forma explícita. Es tan fácil como crear un nuevo fichero llamando [namespacename]-[classname].svc, con el siguiente contenido:
 

<%@ ServiceHost Service="BusinessAplication1.Web.OrganizationService" Factory="System.Web.Ria.Services.DomainServiceHostFactory,

System.Web.Ria, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>

De esta manera, tendremos un fichero svc creado físicamente, pero el funcionamiento de la aplicación no se ve alterado; por tanto, da igual crearlo que no crearlo. ¿Entonces?
 
Pues si nos vale con la funcionalidad que ofrece, pues no nos vale para nada, pero si queremos aprender cómo funciona o por qué no, personalizar el funcionamiento por defecto, sí que nos puede venir bien.
 
Como veis en el contenido del fichero svc, RIA Services usa un DomainServiceHostFactory, que no es más que una clase que extiende la clase ServiceHostFactory, y que lo que hace es proporcionar la funcionalidad que RIA Services necesita, por ejemplo, la de exponer los tres endpoints que comentábamos anteriormente.
 
Si quisiéramos crear nuevo propio comportamiento podría ser “tan fácil” como crearnos una nueva clase hija de ServiceHostFactory y ala, a personalizar todo lo que queramos 🙂
 
El fichero svc quedaría algo así:
 

<%@ ServiceHost Service="BusinessAplication1.Web.OrganizationService"

Factory="BusinessAplication1.Web.CustomDomainServiceHostFactory" %>

Otra forma de hacerlo, en lugar de extender ServiceHostFactory, puede ser hacerlo de DomainServiceFactory. Por ejemplo, si quisiéramos hacer que nuestro servicio siempre funcione en binario y que no exponga los dos otros endpoints, ésta podría ser la solución más adecuada.
 
Los métodos que se usan dentro del método AddEndpoints para crear los endpoints los proporciona la clase base DomainServiceHostFactory.
 
public class CustomDomainServiceHostFactory:DomainServiceHostFactory
{

protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new CustomDomainServiceHost(serviceType, baseAddresses);
}
}


public class CustomDomainServiceHost:DomainServiceHost
{
public CustomDomainServiceHost(Type domainServiceType, params Uri[] baseAddresses)
: base(domainServiceType, baseAddresses)
{

}

protected override void AddEndpoints()
{
foreach (Uri uri in this.BaseAddresses)
{
//AddSoapWithBinaryEndpoint(uri);
AddRestWithJsonEndpoint(uri);
//AddSoapWithXmlEndpoint(uri);

}
}
}