Dopo le parole vorrei passare ai fatti :-)
Immaginiamo sia necessario avere un servizio che registri un nuovo contatto e assegni un codice univoco al contatto (uno use case molto semplice). Immaginiamo anche che il servizio possa essere usufruito sia nella nostra intranet, sia attraverso internet, sia sul server locale.
Iniziamo con la definizione del contratto, cioè i messaggi, le operazioni ed il servizio. Dovendo utilizzare questo contratto in più ambiti, decidiamo di creare una class library che contenga solamente il contratto (ed eventualmente la logica di dominio e di persistenza)
Creamo il progetto, aggiungiamo la referenza a System.ServiceModel.dll (contiene le definizioni per il contratto) e implementiamo la classe messaggio, rappresentata da una entità Contact:
using System;
using System.Xml.Serialization;
namespace PEWay.Contract
{
[XmlRoot(Namespace = "http://peway.com/contact")]
[XmlType(Namespace ="http://peway.com/contact")]
public class Contact
{
public string FirstName;
public string LastName;
public string EMail;
public string HomePhoneNumber;
public string MobilePhoneNumber;
}
}
A questo punto passiamo all'interfaccia del servizio definendone i namespace e l'operation:
using System;
using System.ServiceModel;
namespace PEWay.Contract
{
[ServiceContract(Namespace = "http://peway.com/contactmanagement",
FormatMode = ContractFormatMode.XmlSerializer)]
interface IContactService
{
[OperationContract(Style = ServiceOperationStyle.DocumentBare)]
string SubmitContact(Contact contact);
}
}
Ci sono due aspetti importanti dell'interfaccia appena definita: la serializzazione verrà eseguita attraverso l'XmlSerializer per mantenere il massimo della compatibilità con l'XSD type system e l'operation style è di tipo DocumentBare (in ASP.NET sarebbe stato SoapParameterStyle.Bare) così il messaggio (per noi l'elemento Contact) discenderà direttamente dal body del messaggio SOAP.
A questo punto l'implementazione dell'interfaccia è desiamente banale:
using System;
namespace PEWay.Contract
{
public class ContactService : IContactService
{
public string SubmitContact(Contact contact)
{
// TODO: Implementare il collegamento alla BLL
return "CN0672634";
}
}
}
Compiliamo ed abbiamo pronto all'uso il nostro assembly che contiene il contratto. Dobbiamo ora renderlo 'visibile'. Iniziamo con proporlo come web service standard all'interno di IIS. Per questo è sufficiente creare un file ContactService.svc contenente il riferimento al servizio:
<%@ Service Class="PEWay.Contract.ContactService, ContactContracts" %>
e definire una configurazione minimale per IIS (web.config):
http://schemas.microsoft.com/.NetConfiguration/v2.0">
Nella configurazione troviamo il puntatore al contratto (sia la classe servizio che la sua relativa interfaccia) e il tipo di binding da utilizzare. Questo binding fa parte di una serie di bindings standard con delle caratteristiche ben definite(ce ne sono 9 definiti). Nel nostro caso abbiamo scelto il binding conforme a WS-I.
Il servizio è pronto all'uso. Basta aprire il browser e richiamare il servizio su http://localhost/ContactService.svc (ammesso che abbiate copiato il tutto nel default web site) per vederne la documentazione generata automaticamente (come succede per ASP.NET puntando al file *.asmx). Per ora è tutto, la prossima volta ci costruiamo un piccolo client.