in

DotNetSide

Dot Net South Italy Developers User Group

Articoli

Articoli pubblicati dagli iscritti a .netSide

Un Windows Service come hosting di servizi Windows Communication Foundation

Autore: Fabio Cozzolino


I servizi creati con Windows Communication Foundation (WCF), grazie alla sua architettura, possono essere messi in hosting su diversi tipi di applicazione, in base alle specifiche esigenze. Se vogliamo, infatti, ottenere qualcosa di simile ai classici servizi asmx, possiamo utilizzare come hosting IIS creando una semplice applicazione ASP.NET.  Se, tuttavia, non vogliamo o non possiamo utilizzare un web server, allora possiamo utilizzare applicazioni Windows Forms, Console o Windows Service per creare degli hosting di servizi WCF. Proprio i Windows Service sono oggetto di questo articolo, nel quale vedremo come creare un servizio windows che espone servizi applicativi tramite WCF, ricreando una situazione del tutto simile a quella di un web server come IIS.

 

CREAZIONE DEL CONTRATTO

Prima di procedere con l’implementazione del servizio, è necessario stabilire quali sono le informazioni scambiate ed in che modo saranno esposte i consumer. Creiamo innanzitutto una soluzione di tipo Blank Solution ed aggiungiamo un progetto WinFx Service Library. Nel progetto andremo a definire una classe che espone sia il servizio windows sia il servizio WCF, ma prima dobbiamo definire il contratto come interfaccia. In linea con gli esempi trattati durante le sessioni del workshop Workflow & Communication Foundation  realizzeremo un servizio in grado di restituire info dettagliate su un libro che stiamo cercando. il contratto potrebbe essere espresso attraverso l’interfaccia IBookSearch così implementata:

 

    [ServiceContract(Namespace = "http://www.dotnetside.org/2006/06/BookSearch")]

    public interface IBookSearch

    {

        [OperationContract()]

        BookInfo FindByName(string bookName);

    }

 

Decorando l’interfaccia IBookSearch con l’attributo ServiceContract, ed il metodo FindByName con l’attributo OperationContract stiamo comunicando al runtime WCF che l’interfaccia definisce un contratto di servizio e che i metodi esposti sono quelli da noi indicati.

 

DEFINIZIONE DEL SERVIZIO

Dopo la definizione dell’interfaccia, dobbiamo ora implementare il servizio e sfruttare l’architettura dei servizi windows per fornire l’hosting su cui poi ci appoggiamo.  Iniziamo con l’aggiungere i riferimenti agli assembly necessari:

  • System.ServiceModel: l’assembly di base per la creazione di servizi WCF. Si trova nella cartella c:\WINDOWS\WinFX\v3.0\Windows Communication Foundation;
  • System.ServiceProcess: è l’assembly incluso nel .NET framework che contiene le classi base per la creazione di servizi windows;
  • System.Configuration.Install:  contiene le classi che consentono di scrivere programmi di installazione personalizzati per i componenti;

La nostra classe deve ereditare dalla classe astratta System.ServiceProcess.ServiceBase ma contemporaneamente deve implementare l’interfaccia IBookSearch per realizzare il servizio WCF. Aggiungiamo, quindi, al nostro progetto un nuovo elemento Windows Service e lo chiamiamo BookWinService.cs. Modifichiamo la classe inserendo il seguente codice:

 

    partial class BookWinService : ServiceBase, IBookSearch

    {

        ServiceHost host;

 

        public BookWinService()

        {

            InitializeComponent();

        }

 

        protected override void OnStart(string[] args)

        {

            host = new ServiceHost(typeof(BookWinService));

            host.AddServiceEndpoint(typeof(IBookSearch), new NetTcpBinding(), "net.tcp://localhost:9001/BookService");

            host.Open();

        }

 

        protected override void OnStop()

        {

            host.Close();

        }

 

        #region IBookSearch Members

 

        public BookInfo FindByName(string bookName)

        {

            Books books = new Books();

            books.Populate();

            return books.FindByName(bookName);

        }

 

        #endregion

    }


come anticipato, la classe BookWinSearch eredita dalla classe base ServiceBase e contemporaneamente implementa l’interfaccia IBookSearch. Nell’evento Start crea l’instanza dell’hosting definendo un endpoint composto dal contratto IBookSearch, dal tipo di binding NetTcpBinding() e un address in ascolto sulla porta 9001. Infine apre l’hosting per metterlo in ascolto. Seguendo questi pochi, semplici passi abbiamo creato un servizio windows in grado di esporre un servizio WCF.

 

INSTALLAZIONE DEL SERVIZIO WINDOWS

L’installazione del servizio windows non è per nulla differente alla procedura normale. Ci posizioniamo nel designer del file BookWinService.cs e clicchiamo con il tasto destro del mouse. Nel menu contestuale apparirà la voce Add Installer che, una volta cliccata, aggiungerà al progetto una nuova classe che eredita da Installer contenente due componenti ServiceInstaller e ServiceProcessInstaller. Qui è possibile definire alcune proprietà per identificare e meglio definire il servizio windows. Posizioniamoci sul designer del ProjectInstaller e nelle proprietà del componente serviceInstaller1 impostiamo:

  • (Name) = installer
  • Description = BookService host a WinFx Service
  • DisplayName = BookService

Nella property windows del componente processInstaller1 impostiamo, invece, le seguenti proprietà:

  • (Name) = process
  • Account = NetworkService

In questo modo  impostiamo l’account NetworkService come l’account sotto il quale deve girare il processo simulando, quindi, una situazione del tutto simile a quella di un web server IIS dove, per impostazione predefinita, i processi ASP.NET vengono eseguiti con l’account NetworkService.

Dopo aver effettuato correttamente tutte le impostazioni, possiamo ora compilare il progetto. Se la compilazione va a buon fine proviamo ad installare il nostro servizio windows utilizzando l’utility da riga di comando installutil.exe con questi parametri:

installutil.exe <nome assembly>

se l’installazione non restituisce alcun errore allora vedremo il nostro servizio in funzione tra i servizi windows.

 

CREAZIONE DEL CLIENT

Il codice per la creazione del client utilizza la classe ChannelFactory per creare un canale di comunicazione con il servizio sulla base delle impostazioni riportate nel file di configurazione, nella sezione BookSearchEndpointConfig:

 

// creo il channel

ChannelFactory<DotNetSide.WinFx.EnterpriseService.Library.IBookSearch> channel = new

                ChannelFactory<DotNetSide.WinFx.EnterpriseService.Library.IBookSearch>("BookSearchEndpointConfig");

 

// creo il proxy

DotNetSide.WinFx.EnterpriseService.Library.IBookSearch proxy = channel.CreateChannel();

 

// eseguo il servizio

DotNetSide.WinFx.EnterpriseService.Library.BookInfo book = proxy.FindByName(this.txtBookName.Text);

 

Provando ad eseguire l’applicazione client, il cui codice complete è allegato all’articolo, otterremo un risultato simile a questo:

 

CONCLUSIONI

Abbiamo visto come è relativamente semplice unire l’infrastruttura di servizi fornita da WinFx attraverso WCF con l’infrastruttura dei servizi windows. Nell’articolo abbiamo realizzato un semplice servizio WCF che espone le sue funzionalità attraverso un windows service, ricreando uno scenario molto simile a quello fornito da IIS, ma con in più il vantaggio di poter utilizzare, almeno fino all’uscita di WAS (Windows Activation Services), protocolli differenti dall’http. Nell’allegato all’articolo potete trovare l’applicazione di esempio completa. Good coding.

 

Riferimenti

Windows Communication Foundation – http://www.windowscommunication.net
WinFx – http://msdn.microsoft.com/winfx


Only published comments... May 30 2006, 04:32 PM by Fabio.Cozzolino
Filed under: ,

Comments

 

Weblog di Fabio Cozzolino said:

B&#232;....l'unione fa la forza .
Nel mio primo articolo su .netSide ho voluto parlare dell'unica tipologia...
May 31, 2006 12:43 AM
 

Mighell's blog said:

Oggi girovagavo un po’ senza meta tra i settaggi di Community Server (su cui gira .netSide) e sono andato...
June 4, 2006 1:05 PM
 

Mighell's Blog said:

June 4, 2006 1:06 PM
 

Mighell's blog said:


Oggi girovagavo un po’ senza meta tra i settaggi di Community Server (su cui gira .netSide) e sono...
June 4, 2006 1:09 PM
 

Weblog di Fabio Cozzolino said:

B&#232;....l'unione fa la forza .
Nel mio primo articolo su .netSide ho voluto parlare dell'unica tipologia...
June 20, 2006 12:38 AM

About Fabio.Cozzolino

Fabio Cozzolino inizia la sua carriera da sviluppatore quando riscopre quello strano libricino blu con la scritta "BASIC" dato a corredo del suo Commodore 64. Da allora un susseguirsi di linguaggi, tra cui COBOL e Visual Basic, lo ha accompagnato fino alla conoscenza di .NET Framework. Dopo un periodo passato a dedicarsi allo sviluppo di applicazioni Windows, si è poi concentrato e appassionato al Web, approdando infine alla progettazione e realizzazione di applicazioni distribuite. E' MCAD.net e scrive regolarmente per la rivista italiana ioProgrammo. E' co-fondatore e Presidente di .netSide e ha scritto il libro Windows Communication Foundation uscito nel mese di novembre 2007 in allegato alla rivista ioProgrammo.

Powered by Community Server (Commercial Edition), by Telligent Systems