WCF - Gerenciamento de Instância

O conjunto de técnicas empregadas pelo WCF para vincular um conjunto de mensagens (solicitações do cliente) a instâncias de serviço é conhecido como Gerenciamento de Instâncias. O WCF oferece suporte a três tipos de ativação de instância e eles são discutidos neste capítulo.

Serviço por chamada

O serviço por chamada é o modo de ativação de instância padrão do WCF. Quando um serviço WCF é configurado para um serviço por chamada, um objeto CLR é criado para o intervalo de tempo em que uma chamada ou solicitação do cliente está em andamento. CLR significa Common Language Runtime e inclui instâncias de serviço no WCF.

No serviço por chamada, cada solicitação do cliente atinge uma nova instância de serviço dedicada e seu consumo de memória é menor em comparação com outros tipos de ativação de instância.

A propriedade InstanceContextMode deve ser definida como InstanceContextMode.PerCall, a fim de indicar um serviço WCF para atuar como um serviço por chamada. A propriedade InstanceContextMode pertence ao atributo ServiceBehavior. Portanto, um serviço por chamada pode ser configurado da seguinte forma -

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

Um serviço é expresso aqui como IMyContract. A figura a seguir mostra o processo de ativação da instância de serviço por chamada.

Implementando um serviço por chamada

[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() {....}
}

Aqui, Param é o parâmetro de pseudo tipo inventado para o exemplo acima.

Serviço por sessão

Neste modo de ativação do WCF, uma sessão privada ou podemos dizer que uma sessão confidencial é mantida entre as duas entidades, ou seja, o cliente e uma instância de serviço particular. Também conhecido como serviço de sessão privada, o serviço por sessão oferece uma nova instância de serviço que permanece dedicada a cada solicitação do cliente e autônoma de todas as outras instâncias pertencentes a esse serviço ciente de sessão.

Para iniciar um serviço por sessão, a propriedade InstanceContextMode deve ser definida como PerSession. Aqui, a instância do serviço permanece na memória durante toda a duração da sessão.

O modo de ativação sofre de escalabilidade, pois o serviço configurado é incapaz de oferecer suporte a quaisquer clientes pendentes adicionais além de alguns (ou talvez até algumas centenas) devido ao custo envolvido em cada uma dessas instâncias de serviço dedicado.

Um serviço por sessão pode ser configurado como -

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

O processo de serviço por sessão pode ser descrito como mostrado na figura a seguir -

O código a seguir mostra um contrato e serviço configurado para o uso de uma sessão privada. A saída indica que o cliente realmente obteve uma instância de serviço dedicada.

Código de Serviço

[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()"); 
   }
}

Código do cliente

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

Resultado

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

Serviço Singleton

Nesse modo de ativação do WCF, todas as solicitações de cliente independentes umas das outras são conectadas à mesma instância única bem conhecida, independentemente de sua conexão com os terminais de serviço. O serviço singleton é descartado apenas quando o host é encerrado.

Este serviço é criado apenas uma vez quando o host é criado. Caso o host não tenha nenhuma instância singleton, o serviço retorna como NULL. O modo de ativação é melhor quando a quantidade de trabalho em cada chamada de método é pequena e não há operações pendentes em segundo plano.

A propriedade InstanceContextMode é necessária para definir como InstanceContextMode.Single para iniciar este serviço Singleton.

Portanto, um serviço Singleton pode ser configurado como -

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

O processo de serviço Singleton é mostrado na figura a seguir -

O código a seguir é usado para inicializar e hospedar uma instância singleton.

Código de Serviço

[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);
   }
}

Código de host

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

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

Código do cliente

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

Resultado

Counter = 43