Desenvolvimento - WCF/WPF

A importância dos Namespaces em serviços

Para gerar um serviço WCF da forma politicamente correta, é necessário criarmos uma classe que representará o serviço, e implementar nela a Interface que é considerada como contrato do serviço.

por Israel Aéce



Para gerar um serviço WCF da forma politicamente correta, é necessário criarmos uma classe que representará o serviço, e implementar nela a Interface que é considerada como contrato do serviço. Você não está restrito em uma relação um para um, ou seja, você pode implementar quantas Interfaces quiser na classe que representa o serviço. Os membros expostos por essas Interfaces, somente serão propagados para o cliente se você mencioná-los durante a criação de um endpoint.

A partir do momento que você pode receber Interfaces criadas por outros membros do time, ou até mesmo por outras empresas, há a possibilidade de haver nomes de Interfaces e de membros iguais. Quando isso acontece, podemos utilizar um recurso fornecido pela própria linguagem, que é a implementação explícita da Interface, e os conflitos de nomenclatura não ocorrem.

Como essa classe trata-se de um serviço WCF, se utilizarmos esse recurso tudo compilará sem problemas, mas ao rodar o serviço, teremos uma exceção do tipo InvalidOperationException sendo disparada. Mas porque isso ocorre? Quando você invoca um serviço WCF a partir de um cliente qualquer, dentro do envelope SOAP temos a SoapAction. Essa informação determina o “alvo” da requisição, ou melhor, qual a operação que será disparada no serviço. Essa informação é uma junção entre as propriedades Namespace do atributo ServiceContractAttribute com a propriedade Name, exposta pelo atributo OperationContractAttribute. Quando essas configurações não são informadas, por padrão, ele define a propriedade Namespace para “http://tempuri.org/”, e com isso, a SoapAction final será: “http://tempuri.org/TeuContrato/TuaOperacao”.

Sendo assim, como temos Interfaces com o mesmo nome, e talvez até a mesma estrutura, elas terão em tempo de execução a mesma SoapAction. Com isso, o WCF não conseguirá entender para qual delas encaminhar a requisição, e neste caso antes de efetivamente abrir o host, irá disparar a exceção que falamos acima. Assim como os namespaces que utilizamos no VB.NET/C#, os namespaces do XML também servem para evitar conflitos de nomenclatura, como é o caso aqui. Configurando os contratos com os seus respectivos namespaces, evitaremos o problema. O código abaixo ilustra isso:

namespace Core
{
[ServiceContract(Namespace = "http://www.israelaece.com/Core")]
public interface IContrato
{
[OperationContract]
string Ping(string value);
}
}

namespace Tools
{
[ServiceContract(Namespace = "http://www.israelaece.com/Tools")]
public interface IContrato
{
[OperationContract]
string Ping(string value);
}
}

É importante não confundir o endereço do serviço com a SoapAction. O endereço do serviço é aquele que definimos durante a criação do endpoint, enquanto a SoapAction é o “alvo” da requisição. Convencionou-se utilizar uma URL na SoapAction, mas isso não é uma obrigação, ou seja, você poderia utilizar algo como “AppCore” e “AppTools” ao invés. Geralmente utiliza-se a URL quando o serviço está público, e o nome da aplicação se ele está acessível apenas internamente.
Israel Aéce

Israel Aéce - Especialista em tecnologias de desenvolvimento Microsoft, atua como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. Como instrutor Microsoft, leciona sobre o desenvolvimento de aplicações .NET. É palestrante em diversos eventos Microsoft no Brasil e autor de diversos artigos que podem ser lidos a partir de seu site http://www.israelaece.com/. Possui as seguintes credenciais: MVP (Connected System Developer), MCP, MCAD, MCTS (Web, Windows, Distributed, ASP.NET 3.5, ADO.NET 3.5, Windows Forms 3.5 e WCF), MCPD (Web, Windows, Enterprise, ASP.NET 3.5 e Windows 3.5) e MCT.