.NET - Consumindo um serviço WCF com acesso a dados via LINQ to SQL


Em meu artigo WCF - Windows Comunication Foundation - Introdução apresentei os conceitos básicos sobre o WCF com um exemplo muito simples de como usar um serviço WCF.

Neste artigo eu vou mostrar como usar um serviço com acesso a dados com LINQ to SQL para consultar  um banco de dados SQL Server. Eu vou usar como exemplo neste artigo o banco de dados Macoratti.mdf e vou trabalhar com a tabela Categories.

O banco de dados Macoratti.mdf é uma réplica simplificada do banco de dados Northwind.mdf e possui a estrutura exibida na figura abaixo. Em detalhes vemos a tabela Categorias com os seus campos e alguns dados informados:

O objetivo é reforçar os conceitos do WCF e mostrar uma forma simples de usar um serviço WCF sendo consumido por uma aplicação Windows Forms com LINQ To SQL.

Para realizar tal tarefa irei criar um solução contendo 3 projetos assim descritos:

Apenas para relembrar,  cada serviço para ser exposto através do WCF precisa atender os seguintes requisitos:

Estes requisitos são conhecidos como ABC: um serviço tem que der um endereço de Endpoint (Address), um Binding e um Contrato.

Uma coisa que eu não mencionei no artigo anterior foram as configurações de Binding fornecidas pela infra-estrutura WCF.

O Binding é responsável por indicar como a comunicação vai ser feita com um endpoint, qual o transporte será usado (HTTP,TCP, etc.), qual a codificação vai ser usada (Texto ou Binário) para serializar as mensagens, transações, segurança, etc.

A seguir temos as principais configurações de Binding que podem ser usadas conforme a utilização e definição de como será hospedada o seu serviço WCF:

Nome Protocolo Definição
BasicHTTPBinding HTTP - Usa o protocolo HTTP para as comunicações como meio de transporte sendo que as mensagens são definidas em XML como os Web Services.
- O modo de transferência pode ser Streaming ou Buffered, sendo a última o default.
- Não da suporte a transações;
- Segurança : None, Transport, Message e Mixed. None é a default.
WSHTTPBinding HTTP -Idêntico ao BasicTTPBinding só que permitindo mais recursos, como transações, segurança na mensagem enviada, etc.
- O modo de transferência Buffered.
- Dá suporte a transações;
- Segurança : None, Transport, Message e Mixed. Message é a default. 
NetTCPBinding TCP -Usa o protocolo TCP para as comunicações; as mensagens são codificadas no formato binário;
NetNamedPipeBinding Windows Named Pipe -Usa o protocolo Windows Named Pipe para as comunicações; as mensagens são definidas no formato binário; É usado para cenários onde o host e o cliente estão hospedados na mesma máquina.
- Não da suporte a transações;
- Transporte IPC;

Obs: Ainda existe a possibilidade de você customizar o seu Binding usando a classe CustomBinding.

Esta definição pode ser feita no arquivo web.config. Veja abaixo um exemplo de um arquivo web.config exibindo a configuração do Binding:

Neste exemplo o endereço do endpoint esta vazio ( <endpoint address=""permitindo que IIS use o endereço padrão.

.........
<services>
      <service name="ServicoWCF.Service1" behaviorConfiguration="ServicoWCF.Service1Behavior">
         <!-- Service Endpoints -->
        <endpoint address="" binding="wsHttpBinding" contract="ServicoWCF.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>
               <dns value="localhost"/>
           </identity>
       </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
</services>
......

Eu vou usar o Visual Studio 2008 SP1 para criar a solução deste artigo.

Criando a solução e os projetos

Abra o Visual Studio 2008 SP1 (se você não tiver o VS 2008 pegue a versão trial por 90 dias aqui)  e no menu File selecione New Project ou clique diretamente em Create Project;

Na janela New Project selecione : Other Project Types e a seguir Visual Studio Solutions e em Templates selecione Blank Solution e informe o nome Usando_LINQ_WCF e escolha a localização do projeto;

Vamos agora incluir o projeto do tipo Class Library chamado DAL_Linq que será a nossa camada de acesso a dados onde iremos usar o LINQ to SQL.

No menu File selecione selecione Add e a seguir New Project;

Na janela Add New Project selecione Visual Basic, e, em Templates selecione Class Library e informe o nome DAL_Linq e clique em OK;

Agora vamos incluir outro projeto, o projeto WCF onde iremos definir o serviço que iremos consumir. Iremos usar o template WCF Service Application que já fornece a infra-estrutura básica para usar o serviço.

No menu File selecione selecione Add e a seguir New Project;

Na janela Add New Project selecione Web, e, em Templates selecione WCF Service Application informe o nome ServicoWCF e clique em OK;

Por último vamos incluir um projeto Windows Forms que irá consumir o serviço criado no WCF.

No menu File selecione selecione Add e a seguir New Project;

Na janela Add New Project selecione Windows, e,  em Templates selecione Windows Forms Application informe o nome WindowsConsumeWCF e clique em OK;

Ao final desta etapa a sua solução deverá exibir na janela Soluction explorer os seguintes projetos:

Definindo a camada de acesso a dados - DAL_Linq

Vamos definir a camada de acesso a dados usando o LINQ to SQL. Para isso vamos excluir a classe class1.vb criada por padrão. Feito isso vamos verificar se existe uma conexão com o banco de dados que desejamos usar. Neste exemplo eu vou usar o banco de dados Macoratti.mdf.

Abra o Server Explorer e se a conexão com o banco de dados não aparecer na janela clique em Add Connection e informe o nome do servidor e selecione o Banco de dados Macoratti.mdf ou outro que você quiser usar e clique em OK;

Agora  vamos clicar com o botão direito do mouse sobre o nome do projeto e selecionar a opção Add New Item;

Selecione o template LINQ to SQL Classes e informe o nome Categorias.dbml e clique em Add;

Abra a janela Server Explorer , expanda os objetos do banco de dados Macoratti.mdf e arraste e solte a tabela Categorias no descritor LINQ para criar a entidade Categoria. Neste momento será criado o mapeamento OR/M.  Observe que foi criado o DataContext CategoriasDataContext.

Selecione a propriedade Serialization Mode do DataContext  e defina o seu valor como Unidirectional com isso teremos a serialização requerida pelo serviço WCF. Feito isso salve o projeto.

Definindo o serviço WCF em : ServicoWCF

Para definir o serviço WCF primeiro temos que incluir uma referência ao nosso projeto DAL_Linq. Clique com o botão direito do mouse sobre o projeto ServicoWCF e selecione Add Reference;

Na janela Add Reference selecione a guia Projects, selecione DAL_Linq e clique em OK;

Abra o arquivo de interface IService1.vb e remova todo o código existente. A seguir inclua o código que define o método GetDataCategorias() que retorna uma Lista de Categorias do tipo DAL_Linq.Categoria;

Observe que os atributos <ServiceContratct()> e  <OperationContract()> são obrigatórios para definir o contrato do serviço. O atributo ServiceContract serve para indicar que a interface é um serviço WCF e o atributo OperationContract indique o método será exportado e estará visível para os clientes do serviço.

Agora temos que implementar o método definido na interface no arquivo Service1.svc. Selecione o arquivo e remova todo o código existente definindo o código conforme mostrado na figura abaixo:

Obs: Você terá que incluir uma referência a System.Data.Linq neste projeto.

O método GetDataCategorias retorna uma coleção de Categorias usando uma consulta LINQ. Após isso salve o projeto.

Consumindo o serviço em uma aplicação Windows Forms: WindowsConsomeWCF

Vamos agora criar uma interface simples incluindo um controle DataGridView no formulário form1.vb do projeto WindowsConsomeWCF;

Inclua um controle DataGridView- gdvCategorias e um controle Button - btnExibir conforme a figura abaixo:

Feito isso clique com o botão direito do mouse sobre o projeto Windows e selecione a opção Add  Service Reference;

Clique no botão Discover e selecione Services in Solution;

Ocorrendo tudo como previsto o serviço que criamos será encontrado e exibido na janela Services;

Clique no serviço Service1.svc e o método GetDataCategorias() será exibido na janela Operations;

Podemos alterar o nome do namespace sugerido mas eu vou usar o nome indicado: ServiceReference1;

Antes de encerrar precisamos efetuar um pequeno ajuste. Clique no botão Advanced... e altere o tipo de dados para System.Collections.Generic.List pois este é o tipo de dados que será retornado pelo nosso serviço.

Após isso clique em OK;

Você deverá ver no seu projeto WIndows Forms a referência ao serviço criada conforme a figura abaixo:

Agora vamos usar o serviço incluindo no evento Click do botão Exibir Categorias o seguinte código:

O código é simples, estou criando uma instância do meu serviço definido em ServiceReference1;

A seguir estou acessando o método getDataCategorias()  definido no serviço que retorna uma coleção de categorias e exibindo no controle DataGridView.

O resultado pode ser visto na figura abaixo:

Com isso concluímos a nossa primeira aplicação que consome um serviço WCF com acesso a dados usando o LINQ to SQL.

Pegue a solução completa aqui: Usando_LINQ_WCF.zip e o banco de dados  aqui Macoratti.mdf

Eu sei é apenas WCF e LINQ, mas eu gosto...

referências:


José Carlos Macoratti