Início > WCF > WCF Routing–Parte2

WCF Routing–Parte2

14 de abril de 2011 Deixe um comentário Go to comments

Veja a primeira parte do artigo.

Implementando o WCF Routing

Agora que fizemos um overview sobre o WCF Routing, vamos ver como desenvolver nosso Router e encaminhar as mensagens para outros serviços. Para fazer este exemplo irei usar como base o cenário acima (Serviço1 e Serviço2) e de acordo com as operações (OperationContract) que meu cliente enviar irei redireciona-lo para um serviço, a ideia é que o cliente não conheça o endereço real dos serviços, pois ele deve saber apenas o endereço do Router.

Para este exemplo eu estruturei a solução com 5 projetos (conforme imagem abaixo), sendo:

03-projetos

 

Nome Projeto

Tipo

Descrição

WCFRoute.Client

Console App.

Será o client a consumir o serviço Router.

WCFRoute.Contract

Class library

Responsável por armazenar nossos contratos WCF (ServiceContract/OperationContract)

WCFRoute.Router

WCF Service Application

Nosso serviço de roteamento, ele que irá receber as mensagens do client e encaminhar para os serviços corretos baseado em um critério de filtro que iremos criar.

WCFRoute.Service1

WCF Service Library

Reponsável por ter a implementação do nosso serviço que expõe a operação GetDataUsingDataContract (no nosso exemplo é o Service1).

WCFRoute.Service2

WCF Service Library

Reponsável por ter a implementação do nosso serviço que expõe a operação GetData (no nosso exemplo é o Service2).

 

Uma vez estruturada a solução de teste, iremos agora preencher cada projeto a começar pela implementação dos nossos serviços, vale lembrar que como é um exemplo não iremos criar lógicas complexas, por isso irei utilizar as próprias classes criadas pelos respectivos tipos de projeto. Para facilitar iremos expor nosso contrato em um assembly separado do Host (padrão recomendado), e iremos referenciar esse assembly direto no client (Proxy), no entanto em alguns cenários talvez necessite expor o WSDL dos serviços para seus clientes.

 

No nosso exemplo, iremos criar dois contratos para os serviços, sendo Service1 e Service2, onde suas implementações estarão no WCFRoute.Service1 para o contrato IService1 e WCFRoute.Service2 para o contrato IService2, veja abaixo a implementação do contrato dentro do projeto WCFRoute.Contract:

 

    // NOTE: You can use the “Rename” command on the “Refactor” menu to change the interface name “IService1” in both code and config file together.

    [ServiceContract(Namespace = http://exemplo/Router”)]

    publicinterfaceIService1

    {

 

        [OperationContract(Action = http://exemplo/Router/GetDataUsingDataContract”)]

        CompositeType GetDataUsingDataContract(CompositeType composite);

 

        // TODO: Add your service operations here

    }

 

    [ServiceContract(Namespace = http://exemplo/Router”)]

    publicinterfaceIService2

    {

 

        [OperationContract(Action = http://exemplo/Router/GetData”)]

        string GetData();

 

        // TODO: Add your service operations here

    }

 

    // Use a data contract as illustrated in the sample below to add composite types to service operations

    [DataContract]

    publicclassCompositeType

    {

        bool boolValue = true;

        string stringValue = “Hello “;

 

        [DataMember]

        publicbool BoolValue

        {

            get { return boolValue; }

            set { boolValue = value; }

        }

 

        [DataMember]

        publicstring StringValue

        {

            get { return stringValue; }

            set { stringValue = value; }

        }

    }

 

 

Importante notar que cada contrato do serviço possui uma operação, sendo IService1 com a operação GetDataUsingDataContract e IService2 com a operação GetData. Nosso critério de filtro no Router será a ação, ou seja, se o cliente chamar a ação GetData iremos enviar esta requisição para o Serviço2 e etc, por isso eu utilizei um Namespace tanto na declaração do serviço (atributo ServiceContract propriedade Namespace) quanto na declaração da operação (OperationContract, propriedade Action).

 

Agora que nosso contrato (operações e serviços que serão expostos) esta pronto, iremos criar a implementação de nossos serviços (Service1 e Service2).

 

            Dentro do projeto WCFRoute.Service1, referencie o assembly do contrato IService1 (WCFRoute.Contract) e crie uma classe para implementar o serviço1.

 

using WCFRoute.Contract;

namespace WCFRoute.Service1

{

    // NOTE: You can use the “Rename” command on the “Refactor” menu to change the class name “Service1” in both code and config file together.

    publicclassService1 : IService1

    {

        publicCompositeType GetDataUsingDataContract(CompositeType composite)

        {

            if (composite == null)

            {

                thrownewArgumentNullException(“composite”);

            }

            if (composite.BoolValue)

            {

                composite.StringValue += “Suffix”;

            }

            return composite;

        }

    }

}

Obs: Por padrão deixei o nome da classe Service1, mas caso deseje pode deixar o nome do service como quiser, lembrando que como boas praticas nomes de classes e de namespaces não podem coincidir.

 

 

Dentro do projeto WCFRoute.Service2, também faça a referencia ao assembly do contrato IService1 (WCFRoute.Contract) e crie uma classe para implementar o serviço2, veja abaixo minha implementação: 

using WCFRoute.Contract;

 

namespace WCFRoute.Service2

{

    // NOTE: You can use the “Rename” command on the “Refactor” menu to change the class name “Service1” in both code and config file together.

    publicclassService1 : IService2

    {

 

        publicstring GetData()

        {

            return“Retorno do serviço 2”;

        }

    }

}

 

Agora que implementamos nossos serviços, iremos configurar o ABC para que possamos criar nosso Router, para isso deixe o arquivo de configuração (app.config) da seguinte forma:

 

Serviço1:

<?xmlversion=1.0encoding=utf-8 ?>

<configuration>

 

  <system.web>

    <compilationdebug=true />

  </system.web>

  <!– When deploying the service library project, the content of the config file must be added to the host’s

  app.config file. System.Configuration does not support config files for libraries. –>

  <system.serviceModel>

    <services>

      <servicename=WCFRoute.Service1.Service1behaviorConfiguration=testsvc>

        <host>

          <baseAddresses>

            <addbaseAddress = http://localhost:8732/WCFRoute.Service1/Service1/ />

          </baseAddresses>

        </host>

        <!– Service Endpoints –>

        <!– Unless fully qualified, address is relative to base address supplied above –>

        <endpointaddress =“”binding=wsHttpBindingcontract=WCFRoute.Contract.IService1>

          <!–

              Upon deployment, the following identity element should be removed or replaced to reflect the

              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity

              automatically.

          –>

          <identity>

            <dnsvalue=localhost/>

          </identity>

        </endpoint>

        <!– Metadata Endpoints –>

        <!– The Metadata Exchange endpoint is used by the service to describe itself to clients. –>

        <!– This endpoint does not use a secure binding and should be secured or removed before deployment –>

        <endpointaddress=mexbinding=mexHttpBindingcontract=IMetadataExchange/>

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behaviorname=testsvc>

          <!– To avoid disclosing metadata information,

          set the value below to false and remove the metadata endpoint above before deployment –>

          <serviceMetadatahttpGetEnabled=TruehttpGetUrl=http://localhost:8732/WCFRoute.Service1/Service1//>

          <!– To receive exception details in faults for debugging purposes,

          set the value below to true.  Set to false before deployment

          to avoid disclosing exception information –>

          <serviceDebugincludeExceptionDetailInFaults=True />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

 

</configuration>

 

 

 

Serviço2:

<?xmlversion=1.0encoding=utf-8 ?>

<configuration>

 

  <system.web>

    <compilationdebug=true />

  </system.web>

  <!– When deploying the service library project, the content of the config file must be added to the host’s

  app.config file. System.Configuration does not support config files for libraries. –>

  <system.serviceModel>

    <services>

      <servicename=WCFRoute.Service2.Service2>

        <endpointaddress=“”binding=wsHttpBindingcontract=WCFRoute.Contract.IService2>

          <identity>

            <dnsvalue=localhost />

          </identity>

        </endpoint>

        <endpointaddress=mexbinding=mexHttpBindingcontract=IMetadataExchange />

        <host>

          <baseAddresses>

            <addbaseAddress=http://localhost:8731/WCFRoute.Service2/Service2/ />

          </baseAddresses>

        </host>

      </service>

    </services>

    <behaviors>

      <serviceBehaviors>

        <behavior>

          <!– To avoid disclosing metadata information,

          set the value below to false and remove the metadata endpoint above before deployment –>

          <serviceMetadatahttpGetEnabled=TruehttpGetUrl=http://localhost:8731/WCFRoute.Service2/Service2//>

          <!– To receive exception details in faults for debugging purposes,

          set the value below to true.  Set to false before deployment

          to avoid disclosing exception information –>

          <serviceDebugincludeExceptionDetailInFaults=False />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

 

Obs.: Note que em ambos serviços estamos expondo os mesmos com o Binding WsHttpBinding (por isso o BaseAddress como http).

 

Agora que nossos serviços estão prontos iremos criar nosso Roteador que irá receber as requisições dos clientes e encaminhar para os serviços acima de acordo com o filtro da ação.

 

 

 

Continua.

 

Categorias:WCF
  1. Francisco Bento
    25 de agosto de 2011 às 16:34

    Grande Nelson !!!
    Sensacional cara ..Continue assim
    Abraço

  1. No trackbacks yet.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: