Introduzione a WCF 4.0: Hosting dei servizi
Scritto da
Pietro Libro
il
mercoledì 3 novembre 2010
Linguaggio:
•
Framework:
•
Livello: 100
Download sorgenti
In quest'ultimo articolo dedicato alla
tecnologia WCF 4, vedremo le diverse soluzioni che possono essere
adottate per eseguire l'hosting (dall'inglese to host, ospitare)
del nostro servizio WCF Calculator implementato nelle
puntate precedenti.
Il primo tipo di hosting che andiamo ad analizzare è relativo ad
ASP.NET Development Server.
ASP.NET Development Server Hosting
Apriamo la solution contenente il progetto del nostro servizio e
nel Solution Esplorer di Visual Studio 2010 visualizziamo il menu
contestuale (attivabile a partire dal nome della soluzione) e
scegliamo Add |New Web Site

Nella dialog visualizzata
scegliamo Empty Web Site e denominiamo il
progetto in CalculatorAspNetService.

A questo punto nel Solution Explorer
dovremmo avere un progetto Web Site contenente il solo file
Web.Config. Rendiamo il progetto CalculatorAspNetService
di avvio (Startup Project): selezioniamo il progetto nel
Solution Explorer e con il tasto destro visualizziamo il menu
contestuale e scegliamo Set As Startup Project:

A questo punto dobbiamo aggiungere un
riferimento al nostro servizio, per cui, tasto destro su
CalculatorAspNetService e dal menu contestuale scegliamo
Add Reference. Nella dialog References dalla
lista dei progetti presenti nella scheda Projects
scegliamo Domus.WCF.CalculatorService (il file
Domus.WCF.CalculatorService.dll verrà aggiunto nella
cartella Bin del progetto Web Site).
I passi fino a questo punto eseguiti non sono sufficienti per
eseguire l'hosting del servizio, mancano ancora un paio di
passaggi. ASP.NET Development Server è presente in
Visual Studio dalla versione 2005 ed è un Web Server pensato per
essere utilizzato dagli sviluppatori con funzioni simili a quelle
fornite da IIS (Internet Information Server), ma rispetto
a quest'ultimo ASP.NET Development Server ha molte
limitazioni. Di default ASP.NET Development Server utilizzata
una porta dinamica ogni volta che viene eseguito, ma in questo modo
i client che devono utilizzare il nostro servizio avrebbero delle
difficoltà ad usarlo (ovvero non lo troverebbero non conoscendo
l'address esatto a cui puntare). E' necessario
cambiare il comportamento del Web Server impostando nella finestra
delle proprietà relative al progetto Web Site il valore di Use
Dynamic Ports a False e di Port su un numero
di porta valido (dipendente dalla configurazione del computer su
cui viene eseguito l'hosting del servizio). Ad esempio sul mio PC
un valore valido è 8081.

Normalmente ASP.NET Development
Server viene eseguito quando si esegue il debugging o
l'Unit Testing di un progetto, ma può essere anche avviato
da riga di comando in questo modo:
C:\Program Files
(x86)\Common Files\microsoft shared\DevServer\10.0>start /B
webdev.webserver40.exe /port:8081
/path:"C:\Users\Pietro\Documents\Visual Studio
2010\WebSites\CalculatorAspNetService"
/vpath:/CalculatorAspNetService
Il quale una volta lanciato avvierà
una nuova istanza dell'ASP.NET Development Server come
mostrato nella figura seguente:

Per rendere il nostro servizio
funzionante mancano ancora due cose: aggiungere un file con
estensione ".svc" e modificare il file Web.Config. Aggiungiamo il
file CalculatorAspNetService.svc: dal solito menu
contestuale visualizzabile nel Solution Explorer tramite click del
tasto destro sul nome del progetto, scegliamo la voce Add New
Item e nella finestra visualizzata Text File specificando
il nome precedentemente indicato.

Dopo aver premuto "Add", Visual Studio
aprirà direttamente il file per poter scriverne il contenuto:
<%@ ServiceHost Service="Domus.WCF.CalculatorService.Calculator" %>
Modifichiamo il contenuto del
Web.Config in questo modo:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehaviors">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Domus.WCF.CalculatorService.Calculator" behaviorConfiguration="CalculatorServiceBehaviors">
<endpoint address="" binding="wsHttpBinding" contract="Domus.WCF.CalculatorService.ICalculator"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
</system.serviceModel>
</configuration>
Prima di eseguire impostiamo come
pagina di partenza del Web Site il file .svc creato. Premendo F5
dovrebbe essere visualizzata la finestra di dialogo corrente:

Lasciamo il flag impostato sulla
posizione di default per abilitare il debugging del sito web e
premiamo "OK". Se tutto è stato eseguito in modo corretto nel
browser dovremmo visualizzare la seguente pagina:

Premendo il link in alto nella
finestra visualizzeremo il wsdl del servizio (su IE9 bisogna
abilitare il Compatibility View)
Abbiamo così visto il primo modo di eseguire l'hosting di un
servizio WCF, ma l'hosting può essere eseguito anche all'interno di
applicazioni managed come un'applicazione web, un'applicazione
Windows Forms o command-line. Questa metodologia di hosting
consente agli sviluppatori il pieno controllo sul ciclo di vita del
nostro servizio WCF soprattutto per quanto concerne il
debugging ed il testing, ma ci sono forti
limitazioni quali ad esempio l'avvio automatico del servizio,
limitato supporto ad alta disponibilità, gestione, robustezza e
distribuzione.
Console Hosting
Proviamo ad eseguire l'hosting della nostro servizio in
un'applicazione console. Come al solito, aggiungiamo un nuovo
progetto, questa volta di tipo Console (i passi da seguire sono gli
stessi dell'hosting per ASP.NET Development Server, solo
che dobbiamo scegliere Add New Project invece di Add
New Web Site). Nella finestra di dialogo Add New
Project selezioniamo il template Console Application
e lo denominiamo come CalculatorConsoleHosting e premiamo
"OK".

Aggiungiamo un riferimento al progetto
Domus.WCF.CalculatorService ed impostiamo il progetto come
d'avvio (Startup Project). Aggiungiamo inoltre un riferimento al
System.ServiceModel e System.Configuration dalla
lista nella scheda ".NET" presente nella dialog "Add
References" visualizzabile nello stesso modo in cui abbiamo
aggiunto un riferimento al progetto con il nostro servizio WCF.

Prima di procedere è necessario
aggiungere un file di configurazione al progetto. Nel Solution
Explorer, tasto destro su CalculatorConsoleHosting,
poi dal menu Add |New Item. Nella finestra
visualizzata scegliamo Application Configuration File e
premiamo "Add". Modifichiamo il contenuto del file in questo
modo:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="HTTPBaseAddress" value="http://localhost:8082/HostingConsole/CalculatorService"/>
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.0"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehaviors">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Domus.WCF.CalculatorService.Calculator" behaviorConfiguration="CalculatorServiceBehaviors">
<endpoint address="" binding="wsHttpBinding" contract="Domus.WCF.CalculatorService.ICalculator"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
</system.serviceModel>
</configuration>
Modifichiamo il contenuto di
Program.cs . Aggiungiamo due statement Using:
using System.ServiceModel;
using System.Configuration;
e modifichiamo il contenuto del
Main:
static void Main(string[] args)
{
Type calculatoServiceType = typeof(Domus.WCF.CalculatorService.Calculator);
string httpBaseAddress = ConfigurationManager.AppSettings["httpBaseAddress"];
ServiceHost host = new ServiceHost(calculatoServiceType, new Uri[] { new Uri(httpBaseAddress) });
host.Open();
Console.WriteLine("CalculatorService is now running...");
Console.WriteLine("Press any type to stop the service.");
Console.ReadKey();
host.Close();
}
Non ci resta che premere F5 per
eseguire il nostro servizio:

E' sufficiente copiare ed incollare
l'indirizzo
http://localhost:8082/HostingConsole/CalculatorService?wsdl
nel browser per testarne il funzionamento.
L'hosting del servizio in
un'applicazione Windows Form o Windows Service è
un'operazione del tutto analoga a quanto descritto per il tipo
console. Passiamo quindi ad Internet Information
Server.
Hosting In Internet
Information Server
IIS è la migliore delle opzioni per
eseguire l'hosting di un servizio WCF perché fornisce tutte le
proprietà necessario ad un corretto funzionamento dei servizi:
gestione, robustezza, sicurezza, efficienza ecc … Uno dei
principali svantaggi nelle versione precedenti a IIS 7.0 è il forte
accoppiamento tra ASP.NET e Web Services che limitava l'utilizzo ai
protocolli HTTP e HTTPS. Con IIS 7.0 e superiori abbiamo invece la
possibilità di utilizzare TCP, Pipe e MSMQ, oltre ad http e HTTPS.
Anche se non è oggetto di questo articolo, è importante
sottolineare che secondo della configurazione del Web Site in cui
viene eseguito l'hosting del servizio (ad esempio in un ambiente
load-balanced) potrebbero esserci dei problemi con la session di
WCF che viene persistita in memoria (in questo caso è necessario
utilizzare SQL Server o ASP.NET State Server). Ora invece vediamo
quali sono i passi necessari ad eseguire l'hosting del nostro
servizio in IIS.
Per prima cosa creiamo una cartella nel File System, ad esempio
C:\Domus\WCF\CalculatorService.
In questa cartella dobbiamo copiare i file:
- Domus.WCF.CalculatorService.dll (Nella sottodirectory Bin)
- CalculatorAspNetService.svc
- Web.Config
Gli ultimi due file sono stati creati quando abbiamo sviluppato
il progetto Web Site per eseguire l'hosting tramite ASP.NET
Development Server. Supponendo che IIS sia installato e configurato
correttamente:
- Tramite il prompt dei comandi in modalità amministratore,
lanciamo il manager di IIS attraverso il comando start inetmgr
;
- Nella struttura ad albero a sinistra della finestra
visualizzata espandiamo i nodi fino a rendere visibile la voce
Default Web Site. Selezioniamo il nodo e visualizziamo il menu
contestuale con il tasto destro e scegliamo Aggiungi applicazione
…;
- Nella finestra visualizzata nel campo Alias specifichiamo il
valore IISCalculatorService e specifichiamo come percorso fisico
C:\Domus\WCF\CalculatorService. Se necessario, dobbiamo specificare
il valore dell'Application Pool sulla versione 4.0 del .Net.

Dopo aver premuto "OK" il nostro
lavoro è terminato (in teoria, secondo dei requisiti bisognerebbe
modificare le varie impostazioni di IIS per l'autenticazione,
Esplorazione Directory, pagina iniziale ecc …). Supponendo che le
impostazioni di default siano sufficienti, digitando o copiando ed
incollando l'indirizzo
http://localhost/iiscalculatorService/CalculatorAspNetService.svc
dovremmo visualizzare la pagina web del servizio.
Non ci resta che creare un client che
ci permetta di testare il comportamento dell'servizio nelle sue
"varie forme di hosting".
Al solito, aggiungiamo alla nostra
soluzione un nuovo progetto di tipo Console che denominiamo
CalculatorConsoleClient e aggiungiamo i soliti References
a System.ServiceModel , System.Configuration e
System.Runtime.Serialization. Invece di utilizzare Visual
Studio per la creazione delle classi proxy necessarie per
interfacciarsi con il servizio, questa volta utilizzeremo l'utility
a riga di comando ScvUtil.exe aprendo una nuova finestra
dal prompt dei comandi di Visual Studio 2010 in modalità
amministratore (Start | Tutti i programmi | Microsoft Visual Studio
2010 | Visual Studio 2010 Tools) e digitando quanto segue:
C:\Windows\system32>svcutil.exe
http://localhost/iiscalculatorService/CalculatorAspNetService.svc?wsdl
/out:"C:\Users\Pietro\Documents\Visual Studio
2010\Projects\Domus.WCF.CalculatorService\DomusCalculatorClient\CalculatorService.cs"
/config:"C:\Users\Pietro\Documents\Visual
Studio2010\Projects\Domus.WCF.CalculatorService\DomusCalculatorClient\App.config"
Alcune osservazioni:
- Abbiamo utilizzato il servizio WCF "hostato" su IIS;
- Con il parametro /out indichiamo il percorso dove salvare
il file con estensione .cs generato (e' possibile cambiare il
linguaggio specificando il parametro /language);
- Con il parametro /config indichiamo il percorso dove salvare il
file di configurazione App.Config.
Maggiori informazioni sul tool SvcUtil.exe e sul suo utilizzo
all'indirizzo http://msdn.microsoft.com/it-it/library/aa347733.aspx.
A questo punto nella root del progetto CalculatorConsoleClient
dovremmo trovare i due file generati attraverso SvcUtil.exe, ma
questi non sono presenti nel Solution Explorer di Visual Studio:
affinché siano visualizzati è necessario selezionare il progetto
CalculatorConsoleClient e premere il bottone Show All Files
presente nella toolbar di Solution Explorer.

A questo punto per includere i file nel progetto è necessario
selezionarli (entrambi o uno alla volta) e dal menu contestuale
scegliere Include In Project. Prima di eseguire il nostro client
modifichiamo il codice di Program.cs in questo modo:
static void Main(string[] args)
{
CalculatorClient calculator = new CalculatorClient();
Console.WriteLine("2^3={0}", calculator.Pow(2, 3));
Console.ReadKey();
}
Premendo F5 visualizzeremmo una schermata console simile alla
seguente:

Se volessimo eseguire la chiamata verso un altro Hosting è
sufficiente cambiare l'indirizzo esposto dall'Endpoint in questo
modo:
static void Main(string[] args)
{
CalculatorClient calculator = new CalculatorClient();
calculator.Endpoint.Address = new EndpointAddress("http://localhost:8082/HostingConsole/CalculatorService");
Console.WriteLine("2^3={0}", calculator.Pow(2, 3));
Console.ReadKey();
}
In questo esempio la chiamata viene eseguita sul servizio
"hostato" in IIS. Qualche osservazione prima di concludere: quando
abbiamo generato le classi proxy tramite SvcUtil.exe non abbiamo
specificato il parametro /async che ci permettere di generare i
metodi per l'esecuzione asincrone delle chiamate verso il servizio,
in più avremmo potuto generare dinamicamente queste classi
direttamente da codice utilizzando la classe
System.ServiceModel.ChannelFactory (http://msdn.microsoft.com/it-it/library/system.servicemodel.channelfactory%28VS.95%29.aspx)
.
Siamo così giunti alla fine di quest'articolo e della mini
serie dedicata a WCF 4: abbiamo introdotto i concetti principali,
abbiamo visto come creare un semplice servizio, come gestire gli
errori ed infine come eseguirne l'hosting e creare un semplice
client che possa consumare il servizio. Sono molteplici gli aspetti
che dovrebbero essere approfonditi e che in questi quattro articoli
abbiamo appena accennato, come ad esempio sicurezza, utilizzo delle
transazioni, ambienti distribuiti, il session state di WCF ecc …
Argomenti che saranno prenderemo in considerazione in modo
approfondito nei prossimi articoli dedicati a questa fantastica
tecnologia.
Tags: WCF 4,Hosting