Olá!
Esse post será sobre o último objetivo do capítulo de WCF, Host and manage services.
Esse objetivo cobre como gerenciar simultaneidade, escolher um Instance Mode, criar hosts, escolher um mecanismo de hosting, criar serviços transacionais e hostear em um Azure Worker Role.
Gerenciando Simultaneidade
É bem provável que seu serviço seja consumido por mais de um consumidor ao mesmo tempo. Com isso, é necessário tentar prever e gerenciar a simultaneidade que seu serviço suportará.
Dentro de ServiceBehavior, você pode definir o ConcurrencyMode: [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)]
O enum ConcurrencyMode possui 3 valores:
- Single: em qualquer momento, somente 1 request tem acesso ao serviço WCF por vez. Caso vários requests sejam feitos simultaneamente, todos vão esperar até que o anterior complete seu processamento;
- Multiple: como o nome sugere, múltiplos requests podem ser feitos simultaneamente em threads separadas;
- Reentrant: funciona como o Single, mas se você fizer uma chamada a outro serviço, o lock é liberado para que o próximo request seja processado.
Escolhendo um Instance Mode
Tratando ainda sobre simultaneidade, a configuração InstanceContextMode especifica o número de instâncias do serviço para processar os requests. Também tem 3 valores e, junto com ConcurrencyMode, dão 9 possíveis combinações.
Assim como ConcurrencyMode, você pode setar essa propriedade no atributo ServiceBehavior. Os 3 valores são:
- Single: uma única instância do serviço é usada para todos os requests;
- PerSession: cria uma ou mais instâncias para cada client. É a configuração padrão;
- PerCall: cria uma ou mais instâncias para cada request.
Esse é um assunto bem complexo e o comportamento de cada combinação aparentemente está fora do escopo do exame. Se quiser ir a fundo no tema, há um bom artigo no codeproject.
Criando Hosts
Há várias opções de host para um serviço WCF. Vamos passar pelas opções disponíveis (ou prováveis de estar no exame) resumindo os pontos positivos e negativos.
Self Hosting
Serviços WCF podem ser hospedados em qualquer aplicação .NET. Você especifica a configuração do serviço em um arquivo de configuração ou no código em conjunto com instâncias da classe ServiceHost.
Há vários benefícios dessa forma. Como você pode facilmente trocar de hosts, se sua aplicação não estiver performando bem, você pode fazer upgrade para outro host ou habilitar outros bindings. Fazer debug da aplicação também fica facilitado.
A principal desvantagem é que você deve gerenciar todo o host, consertando quaisquer bugs que apareçam. Mover o host para outra máquina ou fazer um upgrade de hardware, se for necessário, também é doloroso. Por isso são geralmente usados para ambiente de desenvolvimento, e não produção.
Managed Windows Services
Não muito diferentes de outras aplicações .NET, Managed Services são parecidos com Self Hosting, mas com mais poder. Se a máquina reiniciar, por exemplo, o serviço pode startar automaticamente, sem a necessidade de um usuário logado. Também não é necessário usar IIS ou WAS para rodar na máquina.
Como desvantagens, você ainda precisa escrever código para criar o host com a classe ServiceHost e existe limitação para scale up e scale down. Services também tendem a ser mais difíceis para debug.
Internet Information Services (IIS)
O IIS, conhecido por hospedar aplicações ASP.NET, também pode ser usado para hospedar um serviço WCF.
As vantagens são todas as features que o IIS tem, como isolamento de pools de aplicações, recycling, desligamento por ociosidade, monitoramento, etc. Se o serviço precisar de alta disponibilidade e ser escalável, IIS é a escolha ideal.
A desvantagem que pode deixá-lo inutilizável para alguns serviços é que ele só suporta bindings que fazem o transporte por HTTP.
Windows Activation Service (WAS)
WAS, apesar de presente na maioria das grandes organizações, não é tão conhecido como o IIS.
Ele provê todos os benefícios do IIS e suporta outros tipos de transporte, como TCP, named pipes e MSMQ.
A desvantagem é que, por ser uma tecnologia nova, há pouco suporte e material sobre ela.
Windows Azure
Hospedar seu serviço na nuvem possui várias vantagens. A principal é que toda a dor de cabeça de manter um servidor com um serviço rodando fica com a Microsoft, e não com você.
Por enquanto, é suficiente saber que há 3 principais opções no Azure: WebRole, AppFabric service bus e WorkerRole.
A desvantagem pode ser que sua aplicação está hospedada por outras pessoas, o que tira o seu controle de ter um servidor on premise. Usando Azure, você ainda terá que fazer a escolhe entre self-host, IIS ou WAS.
Classe ServiceHost
Criar uma instância de ServiceHost é simples. Você chama o construtor passando o tipo do serviço, que deve estar referenciado. Há vários overloads do construtor, mas não são prováveis de estarem no exame. Após isso, você chama o método Open e por fim Close, ambos num try/catch pois várias coisas podem dar errado nesse tempo.
using (ServiceHost HostInstance = new ServiceHost(typeof(TestServiceType)))
{
HostInstance.Open();
//Put in a Wait Condition so Host stays open
HostInstance.Close();
}
Após o canal ser aberto por um client, o comportamento depende das definições do serviço (ConcurrencyMode, InstancingMode, tipos de endpoint, etc.). Um ponto importante para o client é que, caso haja algum erro não tratado, todo o canal é considerado falho e inválido para novas operações. Sempre deve haver a validação se a conexão está válida.
É importante também entender as opções de host. Como serviços WCF podem ser hospedados em qualquer AppDomain, seja uma aplicação Windows Form ou Console, se o AppDomain não estiver ativo, o host também não estará.
Ao usar um mecanismo de hosting como IIS ou WAS, não é necessário criar um ServiceHost. Basta configurar o serviço e gerenciar pela ferramenta.
Há outro ponto que possivelmente esteja no exame. Antes do .NET 4.0, se você quisesse usar o IIS para hospedar seu serviço, você tinha que criar uma aplicação ASP.NET com uma referência ao seu serviço, colocar as configurações no Web.config e criar um arquivo de texto com a extenção .svc (com uma única linha) para mapear o serviço.
Com a versão 4.0, isso não é mais necessário. Você pode usar a classe ServiceHostingEnvironment, que permite que você referencie o arquivo .svc virtualmente, sem a necessidade de criá-lo fisicamente. A configuração via arquivo fica assim:
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="ServiceOrInterfaceName.svc" service="FullyQualifiedServiceName"/>
</serviceActivations>
</serviceHostingEnvironment>
Escolhendo Um Mecanismo De Hosting
Resumindo o que vimos até agora, você tem várias opções para hospedar um serviço WCF:
- Windows Form application
- Console application
- Managed Windows Service
- ASP.NET application
- IIS
- WAS
- Windows Azure
Não existe regra para fazer essa escolha ou uma opção que atenda todos os cenários. Se seu serviço demandar que o transporte não seja feito por HTTP, por exemplo, o IIS não é uma opção. Ou se você precisar usar um binding MSMQ, você vai precisar de um host que dê suporte a isso.
Falando no geral, procure uma solução que te dê menos trabalho. IIS e WAS são produtos confiáveis, com uma base de usuários grande e fáceis de usar em conjunto com WCF. Escrever um novo host fatalmente irá gerar bugs ao longo do caminho.
Criando Serviços Transacionais
No objetivo 1.3, falamos sobre a classe TransactionScope. Ela também funciona de maneira bem simples com serviços WCF.
Você precisa decorar a operação com o atributo TransactionFlow (em conjunto com o atributo OperationContract), que especifica se a operação suporta transações. O construtor aceita 3 valores:
[TransactionFlow(TransactionFlowOption.NotAllowed)]
: a operação não pode participar de uma transaction;
[TransactionFlow(TransactionFlowOption.Allowed)]
: a operação pode participar de uma transaction, se o client iniciar uma;
[TransactionFlow(TransactionFlowOption.Mandatory)]
: obrigatoriamente a chamada deve fazer parte de uma transaction.
Além disso, você deve setar as propriedades TransactionAutoComplete e TransactionScopeRequired do OperationBehavior como true:
[OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
public String GetTestSummary(String examId){}
TransactionAutoComplete diz ao runtime para automaticamente completar a transação se nenhuma exceção for lançada. Caso seja, será feito o rollback. O atributo TransactionScopeRequired diz que o método precisa fazer parte de uma TransactionScope.
Hospedando Serviços Em Um Azure WorkerRole
Hospedar seu serviço no Azure em um WorkerRole significa ter mais controle sobre o servidor e as configurações do seu serviço, permitindo que você não use o IIS como hosting, por exemplo.
Com isso, é de sua responsabilidade configurar endpoints, inicializar e abrir um ServiceHost. Isso pode ser feito no método OnStart.
As configurações de endpoint podem estar no arquivo de configuração da role (.csdef). O código fica assim:
É interessante deixar a variável de host fora do método para que o garbage collector não a remova do escopo quando o método terminar.
O último detalhe desse objetivo, não relacionado a nenhum item, é que você deve saber que existe um DiscoveryEndpoint que faz com que seu serviço seja descoberto por clients.
E acabamos o capítulo 3 sobre serviços WCF 😀 Por ser o maior objetivo da certificação, o assunto ficou bem extenso e chato, às vezes.
Mas agora vem o capítulo 4 com os objetivos sobre Web API, que é o mais comum nas aplicações hoje em dia (e bem mais elegante).
O próximo objetivo será o 4.1, Design a Web API.
Até mais!
Leia Mais