Il tutorial che vi propongo oggi è ben esplicato dal suo titolo: alla fine di queste pagine sarete in grado di creare un WCF, pubblicare con un’applicazione ad hoc scritta da voi stessi e consumarla con una vostra applicazione client.
Nella vita reale probabilmente non scrivere mai una vostra applicazione per fare l’host di un WCF, probabilmente utilizzere IIS che fa egregiamente questo lavoro, ma in alcuni casi potrebbe essere necessario farlo e sicuramente sapere che esiste questa possibilità oltre che saperla implementare è cosa buona e giusta.
Introduzione
Windows Communication Foundation o più brevemente WCF è un framework in cui la Microsoft fa confluire in un modello di programmazione unico tutte le precedenti tecnologie di comunicazione tra processi: WebServices, MSMQ, .Net Remoting ecc. ecc.
Cambiare la tecnologia con cui comunicare non significherà più, con WCF, riscrivere l’applicazione o il servizio, ma “semplicemente” riconfigurare WCF (tramite il file di configurazione dell’applicazione: in breve l’App.Config o il Web.Config a seconda dei casi) in modo tale da cambiarne il comportamento.
I mattoncini che compongono un WCF sono i seguenti: ServiceContract con i suoi OperationContract ovvero un’interfaccia (il ServiceContract) che descriverà cosa il WCF dovrà fare tramite i metodi da implementare (gli OperationContract). Il DataContract ovvero i dati che il servizio WCF e l’applicazione chiamante potranno scambiare e il connesso MessageContract ovvero come la struttura dati rappresentata da un DataContract può essere serializzata in un messaggio SOAP.
Importantissimo è poi il concetto di EndPoint che a sua volta è formato da tra elementi: Address ovvero l’indirizzo cui le applicazioni che devono inoltrare chiamate al servizio devono puntare, il Binding ovvero la modalità in cui il servizio viene esposto (Soap tramite basicHttpBindig/wsHttpBindig, oppure NetTCP, NetNamedPipe, MSMQ ecc. ecc.) e il Contract l’interfaccia che il WCF deve implementare.
Il bello di WCF, come accennato, è che per cambiare il suo comportamento in senso più esteso, quindi l’indirizzo cui può essere raggiunto, la modalità in cui il servizio espone i suoi metodi ecc. ecc. può essere cambiato a runtime, senza intervento dello sviluppatore semplicemente variando il file di configurazione dell’applicazione, dove tra i tag <System.ServiceModel>…</System.ServiceModel> vengono configurati i vari binding (e non solo…)
Parte I: Creazione del WCF
Avviare Visual Studio 2008 e creare un nuovo progetto del tipo “Class Library”, ovvero una semplice libreria DLL. Aggiungiamo un riferimento al componente System.ServiceModel e creiamo un nuovo file C# in cui andremo a dichiarare la nostra interfaccia chiamata IGTService:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace GTService
{
[ServiceContract]
interface IGTService
{
[OperationContract]
String getHello();
}
}
La descrizione dell’interfaccia è ben poca cosa: si “decora” la sua dichiarazione con la parola chiave [ServiceContract], e questo permetterà a WCF di capire che quest’interfaccia è quella del “contratto”, ovvero conterrà la definizione dei metodi che il WCF esporrà. Ogni metodo che dovrà essere esposto dovrà essere segnato come [OperationContract].
A questo punto possiamo aggiungere al progetto un nuovo file C# che conterrà una classe che implementerà l’interfaccia appena creata:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GTService
{
public class GTService : IGTService
{
#region IGTService Members
public string getHello()
{
System.Console.WriteLine("Ho ricevuto una richiesta per \"getHello\"");
return "Hello World!";
}
#endregion
}
}
L’implementazione dell’interfaccia del WCF non ha bisogno di ulteriori commenti: il “cuore” del nostro WCF è così completato.
Parte II: applicazione host
Quello che faremo ora è creare un’applicazione che esponga il servizi precedentemente creato: ciò avverrà attraverso la creazione di un’applicazione console. Come anticipato, ben difficilmente nella vita reale andremo ad esporre un WCF attraverso un’applicazione console, probabilmente lo faremo attraverso IIS o in casi più particolari attraverso un servizio di Windows: tuttavia in questo contesto l’applicazione host fa perfettamente il suo dovere e non ci fa perdere tempo si aspetti che esulano dallo scopo di questo breve tutorial.
In Visual Studio 2008 aggiungiamo alla soluzione precedentemente creata un nuovo progetto di tipo “Console Application”: come fatto per la libreria aggiungiamo un riferimento al componente System.ServiceModel ed aggiungiamo al main il codice seguente:
using (ServiceHost service = new ServiceHost(typeof(GTService.GTService)))
{
service.Open();
System.Console.WriteLine("Premi per terminare il servizio");
System.Console.ReadLine();
service.Close();
}
Le operazioni compiute da questo programma sono molto semplici: un’istanza della classe ServiceHost permette di “ospitare” il nostro servizio. La comunicazione verrà aperta invocando il metodo Open. Com’è facilmente intuibile il servizio rimarrà in ascolto fin quando non verrà premuto un tasto ovvero fin quando non verrà invocato il metodo Close.
Parte III: Configurazione del servizio
Aggiungiamo alla nostra applicazione host il suo file di configurazione ed editiamolo, aggiungendovi la sezione System.ServiceModel come segue:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="GTService.GTService" behaviorConfiguration="GTServiceBehaviorConfiguration">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/GTService.svc"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="GTService.IGTService"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="GTServiceBehaviorConfiguration">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</system.serviceModel>
</configuration>
Vediamone velocemente il significato: nella sezione Services vengono aggiunti tutti i servizi esposti dal WCF, nel nostro caso è uno. Ogni tag Service descrive il servizi: gli viene dato un nome (che poi è quello che viene chiamato dal costruttore di ServiceHost) e viene specificato il behaviorConfiguration, ovvero la sezione di App.Config in cui verrà configurato il comportamento del servizio stesso.
Si aggiungono i baseAddress ovvero la base comune a tutti gl’indirizzi dei vari endpoint (per indirizzi s’intende proprio l’indirizzo del servizio).
Si aggiunge un entpoint il cui address è vuoto proprio perché non si vuole aggiungere null’altro al baseAddress, si specifica un binding, in questo caso il basicHttpBindig (assimilabile al vecchio web service .asmx di .Net 2.x e precedenti) e l’interfaccia che definisce il contratto.
Aggiungiamo poi un serviceBehaviors, ovvero un comportamento in cui semplicemente si dice al WCF di pubblicare il WSDL.
A questo punto avviando il servizio ed aprendo con un browser l’indirizzo dell’endpoint possiamo verificare che il tutto venga effettivamente esposto se otterremo qualcosa di simile a quanto visibile a seguito:

Guardando bene la risposta del browser abbiamo già le istruzioni per creare un semplice client per il nostro servizio, cosa che andremo a fare nella sezione seguente.
Parte IV: creazione dell’applicazione client
Per prima cosa, così come specificato dalla risposta del browser precedentemente ottenuta, dobbiamo generare le classi e il file di configurazione che permetteranno alla nostra applicazione client d’invocare il servizio: apriamo un prompt dei comandi di Visual Studio e digitiamo il comando:
svcutil.exe http://localhost:8888/GTService.svc?wsdl
al seguito dell’esecuzione di questo comando verranno generati due file: GTService.cs e App.Config. Creiamo una nuova Console Application ed aggiungiamola alla nostra soluzione in Visual Studio ed aggiungiamo questi due file al progetto appena creato.
Editiamo come segue il main della nuova Console Application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestClient;
namespace TestClient
{
class Program
{
static void Main(string[] args)
{
using (GTServiceClient client = new GTServiceClient())
{
client.Open();
String str = client.getHello();
client.Close();
System.Console.WriteLine("Messaggio : " + str);
System.Console.ReadKey(true);
}
}
}
}
La descrizione di quanto fatto è molto semplice: nel file GTService.cs è dichiarata una classe GTServiceClient che permette d’iniziare la comunicazione con il servizio e fra le tante altro cose, c’è la dichiarazione al metodo del servizio getHello. Mandando in esecuzione quest’applicazione otterremo l’output su console del messaggio ritornato dal metodo getHello.
Ci sarebbero tantissime altre cose da dire sull’argomento, ma andrebbero fatte in una sede diversa da quella di un tutorial introduttivo come questo.