WCF - Gestione delle istanze

L'insieme di tecniche utilizzate da WCF per associare un insieme di messaggi (richieste client) alle istanze del servizio è noto come Gestione delle istanze. WCF supporta tre tipi di attivazione dell'istanza e vengono discussi in questo capitolo.

Servizio per chiamata

Il servizio per chiamata è la modalità di attivazione dell'istanza predefinita di WCF. Quando un servizio WCF viene configurato per un servizio per chiamata, viene creato un oggetto CLR per il periodo di tempo in cui è in corso una chiamata o una richiesta client. CLR sta per Common Language Runtime e include istanze del servizio in WCF.

Nel servizio per chiamata, ogni richiesta del client raggiunge una nuova istanza di servizio dedicata e il suo consumo di memoria è inferiore rispetto ad altri tipi di attivazione dell'istanza.

La proprietà InstanceContextMode deve essere impostata su InstanceContextMode.PerCall, al fine di indicare un servizio WCF che funge da servizio per chiamata. La proprietà InstanceContextMode appartiene all'attributo ServiceBehavior. Quindi, un servizio per chiamata può essere configurato come segue:

[ServiceContract]
interface IMyContract
{...}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}

Un servizio è qui espresso come IMyContract. La figura seguente mostra il processo di attivazione dell'istanza del servizio per chiamata.

Implementazione di un servizio per chiamata

[DataContract]
class Param {....}

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod(Param objectIdentifier);
}
class MyPerCallService : IMyContract, IDisposable {
   public void MyMethod(Param objectIdentifier) {
      GetState(objectIdentifier); 
      DoWork();
      SaveState(objectIdentifier);
   }
   
   void GetState(Param objectIdentifier) {....}
   void DoWork() {....}
   void SaveState(Param objectIdentifier) {....}
   public void Dispose() {....}
}

Qui, Param è il parametro di tipo pseudo inventato per l'esempio precedente.

Servizio per sessione

In questa modalità di attivazione di WCF, viene mantenuta una sessione privata o, possiamo dire, riservata tra le due entità, ovvero il client e una particolare istanza del servizio. Conosciuto anche come servizio di sessione privata, il servizio per sessione offre una nuova istanza di servizio che rimane dedicata a ciascuna richiesta del client e autonoma da tutte le altre istanze relative a quel servizio sensibile alla sessione.

Per avviare un servizio per sessione, è necessario che la proprietà InstanceContextMode sia impostata su PerSession. In questo caso, l'istanza del servizio rimane in memoria per tutta la durata della sessione.

La modalità di attivazione soffre di scalabilità poiché il servizio configurato non è in grado di supportare altri client in sospeso oltre a pochi (o forse fino a qualche centinaio) a causa del costo coinvolto in ciascuna di questa istanza di servizio dedicata.

Un servizio per sessione può essere configurato come:

[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{...}

Il processo di servizio per sessione può essere descritto come mostrato nella figura seguente:

Il codice seguente mostra un contratto e un servizio configurato per l'utilizzo di una sessione privata. L'output indica che il client ha effettivamente ottenuto un'istanza di servizio dedicata.

Codice di servizio

[ServiceContract(Session = true)]
interface IMyContract {
   [OperationContract]
   void MyMethod();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable {
   int m_Counter = 0; MyService() {Console.WriteLine("MyService.MyService()"); }
   
   public void MyMethod() {
      m_Counter++;
      Console.WriteLine("Counter = " + m_Counter);
   }
   public void Dispose() { 
      Console.WriteLine("MyService.Dispose()"); 
   }
}

Codice cliente

MyContractProxy proxy = new MyContractProxy(); proxy.MyMethod(); proxy.MyMethod(); 
proxy.Close();

Produzione

MyService.MyService() Counter = 1 Counter = 2 MyService.Dispose()

Servizio Singleton

In questa modalità di attivazione di WCF, tutte le richieste client indipendenti l'una dall'altra vengono connesse alla stessa singola istanza ben nota, indipendentemente dalla loro connessione agli endpoint del servizio. Il servizio singleton viene eliminato solo quando l'host viene chiuso.

Questo servizio viene creato solo una volta quando viene creato l'host. Nel caso in cui l'host non sia fornito con alcuna istanza singleton, il servizio restituisce NULL. La modalità di attivazione è ottimale quando la quantità di lavoro in ciascuna chiamata al metodo è bassa e non sono presenti operazioni in sospeso in background.

La proprietà InstanceContextMode deve essere impostata su InstanceContextMode.Single per avviare questo servizio Singleton.

Quindi, un servizio Singleton può essere configurato come:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}

Il processo del servizio Singleton è mostrato nella figura seguente:

Il codice seguente viene utilizzato per inizializzare e ospitare un'istanza singleton.

Codice di servizio

[ServiceContract]
interface IMyContract {
   [OperationContract]
   void MyMethod( );
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : IMyContract {
   int m_Counter = 0;
   
   public int Counter {
      get {
         return m_Counter;
      }
      set {
         m_Counter = value;
      }
   }
   public void MyMethod( ) {
      m_Counter++;
      Trace.WriteLine("Counter = " + Counter);
   }
}

Codice host

MySingleton singleton = new MySingleton( );
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open( );

//Do some blocking calls then
host.Close( );

Codice cliente

MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( );
proxy.Close( );

Produzione

Counter = 43