Invocando serviço WCF com Sql Server


A idéia desse post é abordar a integração de dois recursos importantes da suite de desenvolvimento Microsoft. O primeiro é o WCF (Windows Communication Foundation), tecnologia essa que fornece todo o amparato para disponibilização de serviços, fornecendo a abstração técnica de “Como”, “Onde” e “Quem” consumirá um serviço, de maneira que o esforço deve estar concentrado no desenvolvimento da regra de negócio e não na implementação técnica. O segundo recurso é tão popular banco de dados relacional, Sql Server. Importante enfatizar, que nos dias atuais, os bancos de dados não são mais meramente repositórios de dados, mas sim um recurso valioso para implementação de inúmeros serviços.
Atualmente os bancos de dados fornecem recursos de disponibilidade de informações para diversos protocolos, consomem e integram serviços, no qual se foi agregado tantos recursos, que não são mais simplesmente repositórios, mas parte muito mais eficiente e colaborativa na infraestrutura de uma grande aplicação. E porque não integrá-las?
Recentemente, tive uma necessidade de implementar um desenvolvimento de integração de dados cadastrais, entre nossa aplicação e o cliente. Nesse caso, a integração é caracterizada exclusiva desse cliente, que chamaremos de “A”. Tendo essa exclusividade em mente, não poderia de maneira alguma implementar algo referente a essa integração no Core da aplicação, onde essa implementação não faz sentido para os demais clientes. O cliente “A” disponibilizou um web service dentro do padrões WS* para consumir os novos cadastros e implementarmos em nossa aplicação. E para nosso conforto, nossa aplicação tem a regra de cadastramento disponibilizada para consumo externo por diversos tipos de protocolos, usufruindo do WCF. A idéia então foi, consumir o web service do cliente obtendo a coleção de registros e enviá-los para nosso serviço de cadastramento, isolando tudo isso do Core, deixando transparente para os demais clientes e mantendo o código saudável sem aqueles inúmeros e problemáticos parâmetros. Toda essa customização foi centralizada no banco de dados do cliente, não impactando os demais. A implementação foi feita utilizando uma Stored Procedure CLR, que nada mais é que uma classe de código C#, que consome ambos serviços, contendo toda a implementação, utilizando dos valiosos recursos do .net framework, e que finalmente foi agregada dentro do banco de dados, como um recursos CLR.

Ativando funcionalidade CLR no banco de dados
EXEC SP_CONFIGURE 'CLR ENABLED' , '1'
GO
RECONFIGURE;

ALTER DATABASE CUSTDB SET TRUSTWORTHY ON
RECONFIGURE
Implementação exemplo – Serviço WCF

1 – Abra o Visual Studio 2008
2 – Menu Novo, Web Site
3 – Selecione o tipo de projeto WCF Service
4 – Utilizaremos a estrutura padrão criada pelo Visual Studio.


// Contrato
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

[ServiceContract]
public interface IService {

     [OperationContract]
     string GetData(int value);
 
 }

// Implementação Contrato
using System;
using System.Collections.Generic;
using System.Text;

public class Service : IService {

    public string GetData(int value) {
        return string.Format("You entered: {0}", value);
    }

}

1 – Abra o Visual Studio 2008
2 – Menu Novo, Project
3 – Selecione o tipo de projeto SQL Server Project.
4 – Criado o projeto, adicione no projeto um Novo item Stored Procedure.

Implementação exemplo – Stored Procedure CLR
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using System.ServiceModel.Description;
using System.ServiceModel;
using System.Collections;

public partial class ProcedureCLR {

   [SqlProcedure()]
   public static void HelloProcedure(string nome) {

   // Criando endpoint do serviço WCF.
   public static EndpointAddress endpoint =
   new EndpointAddress(new Uri("http://localhost:8443/exemplo/Service.svc"));

   // Criado o binding para o endpoint.
   public static WSHttpBinding httpBinding = new WSHttpBinding();

   // Criando a classe proxy para consumo.
   public static ServiceClient.localhost.ServiceClient proxy =
   new ServiceClient.localhost.ServiceClient(httpBinding, endpoint);

   string result = proxy.GetData(10);
   SqlContext.Pipe.Send(string.Format("O resultado do serviço foi {0}", result);
   // Poderíamos já fazer o insert em uma tabela, e ou qualquer outra instrução crud no banco.
   // Pois isso é uma procedure! 
  }

}
Instalando a Stored Procedure CLR
CREATE ASSEMBLY [SMDiagnostics] from
'C:\Windows\Microsoft.NET\Framework\v3.0\Windows
Communication Foundation\SMDiagnostics.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [System.Web] from
'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [System.Messaging] from
'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [System.IdentityModel] from
'C:\Program Files\Reference Assemblies\Microsoft\
Framework\v3.0\System.IdentityModel.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [System.IdentityModel.Selectors] from
'C:\Program Files\Reference Assemblies\Microsoft\
Framework\v3.0\System.IdentityModel.Selectors.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [Microsoft.Transactions.Bridge] from
'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication
Foundation\Microsoft.Transactions.Bridge.dll'
with permission_set = UNSAFE
GO

CREATE ASSEMBLY [ProcedureCLR] from 'C:\ProcedureCLR.dll'
with permission_set = UNSAFE
GO

// Criar a store procedure para consumir o assembly
CREATE PROCEDURE [dbo].[prc_procedure_clr]
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [prc_procedure_clr]
GO

EXEC sys.sp_addextendedproperty @name=N'AutoDeployed', @value=N'yes' , @level0type=N'SCHEMA',@level0name=N'dbo', 
@level1type=N'PROCEDURE',@level1name=N'prc_procedure_clr'
GO

EXEC sys.sp_addextendedproperty @name=N'SqlAssemblyFile', @value=N'ProcedureCLR.cs' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'prc_procedure_clr'
GO

EXEC sys.sp_addextendedproperty @name=N'SqlAssemblyFileLine', @value=45 , @level0type=N'SCHEMA',@level0name=N'dbo',
@level1type=N'PROCEDURE',@level1name=N'prc_procedure_clr'
GO

Invocando a Stored Procedure CLR
EXECUTE prc_procedure_clr
GO

Leave a comment