Overloading de métodos no WCF

Um outro detalhe que funciona perfeitamente bem no C# ou qualquer linguagem orientado a objetos, é o overloading de métodos, onde você tem várias métodos com o mesmo nome, variando o tipo ou a quantidade de parâmetros. Podemos aplicar essa técnica também em Interfaces, e quando ela for implementada nas classes, teremos tais métodos a nossa disposição.

A questão é que, assim como a implementação explícita, quando aplicado em uma Interface que servirá como contrato de um serviço WCF, isso não funcionará. Mas isso não é uma limitação da plataforma, mas sim do documento WSDL, que não suporta algumas características de programação orientada à objetos, e a sobrecarga de métodos é uma delas. Com essa “limitação”, ao rodar um serviço (hosting) com algum método que possua algum overload, você receberá uma exceção do tipo InvalidOperationException, indicando que isso não é suportado.

Para resolver, basta recorrermos a propriedade Name do atributo OperationContractAttribute. Quando essa propriedade é omitida, o WCF assume o nome do método para publicar no documento WSDL. Eventualmente, você poderá customizar, escolhendo o nome que será exposto, já que você não está obrigado a manter o mesmo nome, que muitas vezes reflete algo intuitivo para a sua aplicação, mas incoerente com a operação que será publicada pelo serviço. O exemplo abaixo, ilustra como proceder para utilizar este atributo:

[ServiceContract]
public interface IContrato
{
   [OperationContract(Name = “RecuperarClientesPorEstado”)]
   string[] RecuperarClientes(string estado);

   [OperationContract(Name = “RecuperarClientesPorCidade”)]
   string[] RecuperarClientes(string estado, string cidade);
}

Ao referenciar esse serviço em um aplicação cliente, o mesmo enxergará dois métodos, com os respectivos nomes: “RecuperarClientesPorEstado” e “RecuperarClientesPorCidade”, baseando-se no alias que demos ao criar o contrato. Apesar da ferramenta criar dois métodos, você poderá customizar o proxy gerado, recriando os overloads e tornando a programação do lado do cliente mais intuitiva. Ao gerar o proxy – automaticamente – do lado do cliente, o contrato é criado da seguinte maneira:

[System.CodeDom.Compiler.GeneratedCodeAttribute(“System.ServiceModel”, “3.0.0.0”)]
[ServiceContractAttribute(ConfigurationName=”Servico.IClientes”)]
public interface IClientes {
    [
        OperationContract(
            Action=”http://tempuri.org/IClientes/RecuperarClientesPorEstado”, 
            ReplyAction=”http://tempuri.org/IClientes/RecuperarClientesPorEstadoResponse”)
    ]
    string[] RecuperarClientesPorEstado(string estado);

    [
        OperationContract(
            Action=”http://tempuri.org/IClientes/RecuperarClientesPorCidade”, 
            ReplyAction=”http://tempuri.org/IClientes/RecuperarClientesPorCidadeResponse”)
    ]
    string[] RecuperarClientesPorCidade(string estado, string cidade);
}

Para que você consiga refazer o overloading do lado do cliente, você precisa seguir a mesma técnica aplicada do lado do serviço, ou seja, adicionar a propriedade Name no atributo OperationContractAttribute, renomear as operações para “RecuperarClientes” e, finalmente, reimplementar o contrato na classe que representa o proxy. Desta forma, o cliente e o serviço trabalharão da forma tradicional (OO), enquanto em runtime, tudo será tratado com os “aliases”.