Olá a todos!

Hoje vamos colocar em prática aquilo que aprendemos nos post´s anteriores, ou seja, vamos criar e hospedar nosso primeiro serviço WCF.

Como falei anteriormente, vamos criar nosso serviço sem a utilização de Templates, isso nos dará um bom entendimento sobre tudo que o WCF precisa para funcionar. Mas isso não impede de você criar seus serviços a partir dos Templates o que na verdade é muito mais simples e rápido, porém para estudo vamos ver em detalhes a criação completa do WCF.

Para nossos artigos, vamos criar um projeto que irá disponibilizar métodos para se trabalhar com Post´s, ou seja, iremos criar um Blog. Depois iremos consumí-lo de várias maneiras como WinForm, Console, Asp.Net etc.

Antes de iniciarmos, crie uma solução em branco e dê o nome de WCFPost. Feito isso vamos adicionar a ela dois projetos do tipo C# –> Class Library e dê o nome de WCFPost.Contract, e WCFPost.Data.

Para fins de estudo, não irei utilizar banco de dados pois nosso foco é WCF ok!

Voltando ao nosso projeto, adicione no projeto WCFPost.Data duas classes, Post e Author e decore as classes com o atributo DataContract e suas propriedades com o atributo DataMember, não esqueça de adicionar a referencia a System.Runtime.Serialization pois é neste assembly que estão contidos os atributos DataContract e DataMember. Estes atributos definem que nossas classes poderão ser expostas por um serviço WCF. Suas classes deverão ficar conforme a Listagem 01.

Listagem 01 – classes Post e Author

using System;
using System.Runtime.Serialization;

namespace WCFPost.Data
{
    [DataContract]
    public class Post
    {
        [DataMember]
        public int PostId { get; set; }

        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public DateTime PostDate { get; set; }

        [DataMember]
        public bool IsActive { get; set; }

        [DataMember]
        public Author Author { get; set; }
    }
}

 

using System.Runtime.Serialization;

namespace WCFPost.Data
{
    [DataContract]
    public class Author
    {
        [DataMember]
        public int AuthorId { get; set; }

        [DataMember]
        public string Name { get; set; }
    }
}

Agora que temos a parte Data pronta, vamos começar criando nossa Interface.

Crie uma Interface no projeto WCFPost.Contract e dê o nome de IPost. Ela será o contrato e como todos já sabem, é o contrato quem determinará quais operações estarão expostas, quais informações essas operações necessitam para ser executadas e também qual será o tipo de retorno. O contrato nada mais é que uma Interface que, por sua vez, deverá possuir os métodos que serão expostos para o cliente. Como foi visto anteriormente, devemos decorar nosso contrato com o atributo ServiceContratactAttribute que está presente no assembly System.ServiceModel. Nossa interface deverá ficar como na listagem 02.

Listagem 02 – IPost contract

using System.ServiceModel;
using WCFPost.Data;

namespace WCFPost.Contract
{
    [ServiceContract]
    public interface IPost
    {
        [OperationContract]
        Post GetPostById(int postId);

        [OperationContract]
        void AddPost(Post post);

        [OperationContract]
        void DeletePost(Post post);
    }
}

 

Assim como decoramos a nossa Interface com o atributo ServiceContract, devemos também decorar nossos métodos com o atributo OperationContractAttribute, pois só assim eles estarão expostos para serem consumidos.

Para um melhor entendimento, seu projeto deverá estar como na figura 01.

wcf_p3_01

Figura 01 – Projeto WCFPost

Bem, agora iremos criar a classe que irá representar nosso serviço. Para isso, adicione mais um projeto do tipo C# Class Library e de o nome  de WCFPost.Service. Adicione a este projeto, as referencias às dlls dos projetos WCFPost.Contract e WCFPost.Data.

Precisamos agora implementar a interface do serviço em nossa classe. Seu código deverá ficar como na listagem 03. Fiz a implementação apenas no método GetPostById para tornar o artigo menos extenso ok!

Listagem 03 – implementação da interface IPost.

using System;
using WCFPost.Contract;
using WCFPost.Data;

namespace WCFPost.Service
{
    public class PostService : IPost
    {
        public Post GetPostById(int postId)
        {
            var post = new Post
                           {
                               Author = new Author{AuthorId = 1, Name = "Luciano"},
                               IsActive = true,
                               PostDate = DateTime.Today,
                               PostId = 1,
                               Title = "Trabalhando com WCF"
                           };

            return post;
        }

        public void AddPost(Post post)
        {
            throw new NotImplementedException();
        }

        public void DeletePost(Post post)
        {
            throw new NotImplementedException();
        }
    }
}

 

Uma das maravilhas do WCF é a possibilidade de utilizar qualquer tipo de aplicação como host, ou seja, ele não tem uma dependência de algum software, como o IIS, como acontecia com os Web Services, pois o WCF pode expor serviços para serem consumidos através de diversos tipos de protocolos, como por exemplo: HTTP, TCP, IPC e MSMQ. 

Para nosso artigo, iremos utilizar um Console Application para hospedar nosso host. Então, inclua mais um projeto, mas agora do tipo C# –> Console Application. Adicione a referencia a System.ServiceModel e aos projetos WCFPost.Contract e WCFPost.Service.

Para que nosso serviço comece a funcionar, precisamos antes definir nosso ServiceHost, este precisa conhecer o ABC. Lembram do ABC do artigo anterior? A – Address, B – Binding, C – Contract, pois então iremos utilizá-lo agora.

Defina seu Address como http://localhost:1010, o Binding será do tipo basicHttpBinding e o Contract será o nosso serviço PostService.

Atente que estamos realizando tudo a base de código, isso faz com que nosso aplicativo fique engessado tornando-o praticamente “incustomizável”, palavrinha estranha!!.

Mas não se preocupem, existe outra forma de se realizar tais configurações, porem veremos esta em um outro post galera.

Seu código deve estar como na listagem 04.

Listagem 04 – criando o serviço

using System;
using System.ServiceModel;

namespace WCFPost.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            var address = new Uri("http://localhost:1010");
            var type = typeof (Service.PostService);

            ServiceHost serviceHost = new ServiceHost(type, address);

            serviceHost.Open();
            Console.WriteLine("Service started...");
            Console.ReadLine();
        }
    }
}

Bem, nosso serviço ainda não está totalmente pronto pois, para que os clientes possam extrair as informações (metadados), precisamos expor a descrição do mesmo para que os desenvolvedores possam referenciá-lo nas aplicações clientes que irão consumí-lo.

Você pode expor essas informações através do protocolo HTTP – via método Get – ou utilizar um Endpoint exclusivo para o metadado.

Desta forma iremos utilizar o MEX (Metadata Exchange Endpoint), ele é extremamente necessário, já que o cliente necessita importar os metadados para ter localmente a representação do serviço.

Para configurarmos um serviço a ser exposto, iremos adicionar um EndPoint para o MEX, desta forma altere o código do seu host para o código conforme a listagem 05. Novamente venho frisar que iremos aprender a fazer todas essas configurações em um App.config e no Web.config para termos uma aplicação customizável.

Listagem 05 – criação do MEX

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using WCFPost.Contract;

namespace WCFPost.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            var address = new Uri("http://localhost:1010");
            var type = typeof (Service.PostService);

            ServiceHost serviceHost = new ServiceHost(type, address);

            serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior {HttpGetEnabled = true});
            serviceHost.AddServiceEndpoint(typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
            serviceHost.AddServiceEndpoint(typeof (IPost), new BasicHttpBinding(), "ServicePost");

            serviceHost.Open();
            Console.WriteLine("Service started...");
            Console.ReadLine();
        }
    }
}

 

Vamos observar algumas mudanças em nosso host.

Criamos um ServiceMetadataBehavior com a propriedades HttpGetEnabled setada como true, isso faz com que os metadados sejam acessíveis através de HTTP-GET.

Criamos o EndPoint para o Mex, definindo a interface IMetadataExchange como sendo nosso Contract, deixamos que o método CreateMexHttpBinding() fique responsável por criado o Binding apropriado para nós e por fim definimos um Address para nosso mex.

Rode a aplicação, ela deve estar conforme as figuras 02 e 03.

wcf_p3_02

Figura 02 – serviço iniciado

wcf_p3_03

Figura 03 – acesso ao endereço da aplicação

 

Ufa, finalmente terminamos nosso serviço!! Mas espera ai, é só isso? Claro que não, ainda tem muito mais, mas vamos deixar para os próximos posts né galera!!

Espero que estejam gostando.

Enjoy!!