Compressão em Serviços WCF 4.5

Serviços WCF que são hospedados no IIS sempre puderam usufruir da compactação de mensagens, já que bastar habilitar, pois o próprio servidor fornece este recurso. Serviços que são hospedados em seu próprio servidor (self-hosted), como é o caso de aplicações Windows (Windows Forms, WPF, Console ou Windows Service), precisam de um trabalho extra, que consiste em criar um message encoder customizado para isso. Inclusive uma implementação padrão é fornecida no pacote de demonstrações oferecidos pela própria Microsoft.

A partir do WCF 4.5, nós teremos esse recurso nativamente, ou seja, o codificador binário (BinaryMessageEncoding) passa a fornecer uma propriedade chamada CompressionFormat, que determina o formato da compressão, podendo escolher entre GZip, Deflate ou None. Como essa é uma propriedade fornecida pelo encoder, temos que customizar a criação da binding, para que assim tenhamos acesso à propriedade que define o padrão da compressão. O código abaixo ilustra a criação deste binding, e logo na sequência, temos a mesma configuração, só que através do modelo declarativo (via arquivo de configuração):

var binding = 
    new CustomBinding
    (
        new BinaryMessageEncodingBindingElement()
        {
            CompressionFormat = CompressionFormat.GZip
        },
        new HttpTransportBindingElement()
    );

<customBinding>
  <binding name=”BinaryCompressionBinding”>
    <binaryMessageEncoding compressionFormat =”GZip”/>
    <httpTransport />
  </binding>
</customBinding>

Se interceptarmos a requisição para um serviço sem qualquer configuração de compactação, enviando uma string com 5000 caracteres, temos a requisição abaixo (removendo alguns elementos por questões de espaço):

POST http://127.0.0.1:9291/srv HTTP/1.1
Content-Type: application/soap+msbin1
Host: 127.0.0.1:9291
Content-Length: 5157
Accept-Encoding: gzip, deflate

Agora, se optarmos pelo modelo de compactação GZip, ao analisarmos a requisição para o mesmo serviço, podemos reparar que a quantidade de bytes trafegados é bem menor quando comparado à primeira requisição:

POST http://127.0.0.1:9291/srv HTTP/1.1
Content-Type: application/soap+msbin1+gzip
Host: 127.0.0.1:9291
Content-Length: 185
Accept-Encoding: gzip, deflate

Apesar de um ganho significativo, é importante avaliar corretamente o ambiente em qual o serviço será disponibilizado. Enquanto a compactação é interessante quando o gargalo é a rede, a mesma exige muito mais da CPU para realizar o processo de compactação e descompactação. Sendo assim, o melhor é analisar e realizar alguns testes, e mensurar o que realmente importa durante a execução no ambiente de produção.

Claims em todo lugar

Há algum tempo eu falei aqui sobre o WIF (Windows Identity Foundation), que consiste em um framework para tornar o gerenciamento de identidades em aplicações .NET mais simples. Ele traz uma série de funcionalidades, que quando utilizado nas aplicações, nos permite lidar com a autenticação e autorização de uma forma mais poderosa, conseguindo inclusive, terceirizar/centralizar isso para uma outra aplicação.

O modelo de objetos do WIF, definia duas novas interfaces: IClaimsIdentity e IClaimsPrincipal, que herdavam de duas interfaces já existentes no .NET Framework desde a sua primeira versão (IIdentity e IPrincipal, respectivamente). Apesar de indiretamente compatíveis com os principals do .NET (WindowsPrincipal e GenericPrincipal), havia um trabalho extra a se fazer quando a conversão fosse necessária, ou melhor, quando a aplicação queria trabalhar com claims ao invés do modelo tradicional.

Com o .NET Framework 4.5, a Microsoft decidiu incorporar o modelo de claims diretamente no .NET Framework ao invés disso ser fornecido exclusivamente pelo WIF. A partir da versão 4.5, o .NET Framework passa a fornecer nativamente os tipos necessários para trabalhar com claims, e ainda, fez com que as classes WindowsPrincipal e GenericPrincipal herdem de ClaimsPrincipal e, consequentemente, toda e qualquer aplicação ao ser migrada para a versão 4.5 do .NET, automaticamente poderá fazer uso de claims. O diagrama abaixo mostra a hierarquia da herança entre essas classes:

System.Security.Claims é um novo namespace que foi adicionado ao .NET Framework, com a finalidade de agrupar os tipos disponíveis para realizar o trabalho via claims. Abaixo temos um exemplo de como podemos fazer o uso de claims em aplicações que utilizam, por exemplo, um modelo de autenticação customizado:

using System;
using System.Security.Claims;
using System.Security.Principal;

namespace App
{
class Program
{
static void Main(string[] args)
{
var principal =
new GenericPrincipal(new GenericIdentity(“Israel Aece”), new [] { “Admin”, “IT” });

foreach (var item in principal.Claims)
Console.WriteLine(“{0}: {1}”, item.Type, item.Value);
}
}
}

ASP.NET Web API: Implementação Assíncrona

A Microsoft trabalha para que na próxima versão do C# e do VB.NET, eles já saiam com suporte para programação assíncrona. Como eu já havia mencionado em um post anterior, a ideia é facilitar a programação assíncrona, que não é nada trivial. A ideia é tornar a escrita de um código assíncrono, muito próximo a escrita de um código síncrono, e nos bastidores, o compilador faz grande parte do trabalho. Grande parte das funcionalidades do .NET Framework que já possuem suporte nativo ao consumo em formato assíncrono, foram readaptados para que assim, os desenvolvedores possam fazer uso dos recursos oferecidos pela linguagem para consumi-los.

Desta mesma forma, algumas tecnologias que dão suporte à construção de funcionalidades assíncronas, também sofreram adequações para este novo modelo. Para citar um caso, o WCF permite agora a construção de um serviço assíncrono de forma muito mais tranquila que antes, onde tínhamos que implementar um contrato assíncrono.

Já o ASP.NET merece algumas considerações: o ASP.NET Web Forms traz o conceito de páginas assíncronas, que também farão uso dos recursos das linguagens para implementa-las. O ASP.NET MVC possui uma classe chamada AsyncController, de qual herdamos e com pequenos ajustes, conseguimos ter ações sendo disparadas de forma assíncrona. Na próxima versão, o ASP.NET MVC também flexibilizará a criação das ações assíncronas, deixando, novamente, o trabalho árduo para o compilador.

Agora, ao utilizar o ASP.NET Web API, também podemos fazer com que as ações expostas pela API sejam processadas assincronamente. Como é a primeira versão desta tecnologia, a forma de escrevermos as ações assincronamente, é somente através dos recursos das linguagens. Só que antes de exibir como procedemos para criar o código assíncrono, vamos primeiramente criar a versão síncrona desta ação:

public class NoticiasRegionaisController : ApiController
{
    private const string ServicoDeNoticias =
        “http://localhost:1256/api/noticias/recuperar&#8221;;

    [HttpGet]
    public IEnumerable<NoticiaDaRegiao> Recuperar()
    {
        return
            JsonArray.Parse
            (
                new WebClient().DownloadString(ServicoDeNoticias)
            ).ReadAsType<IEnumerable<NoticiaDaRegiao>>();
    }
}

Note que há um serviço chamado NoticiasRegionais, qual recorre à um outro serviço que é mais abrangente, para extrair as notícias de uma determinada região ou cidade. No interior do método Recuperar, propositalmente fazemos a chamada para o serviço e esperamos pelo resultado, que ao voltar, efetuamos o parser e, finalmente, convertemos para o formato esperado e retornamos ao cliente.

Ao rodar esse código, a requisição será bloqueada pelo runtime até que o resultado seja devolvido pelo serviço. Isso prejedica, e muito, a escalabilidade do serviço. O fato da thread ficar bloqueada enquanto espera pelo resultado do serviço, ela poderia estar atendendo à outras requisições, que talvez não exijam recursos de terceiros (I/O bound). O fato de disponibilizar a thread para que ela possa atender à outras requisições, farão com que elas não esperem por um – longo – tempo indeterminado, pois como dependemos do resultado de um terceiro, poderíamos arranjar muito trabalho para esta thread, até que ela precise retomar o trabalho da requisição anterior.

O gráfico abaixo apresenta algumas medições que foram feitas no serviço acima, que foi implementado de forma síncrona. Entre os contadores podemos visualizar a média do tempo gasto para que a requisição retorne, e além disso, a quantidade de requisições que o serviço de notícias regionais é capaz de atender por segundo.

Como mencionado acima, podemos implementar o controller da API de forma assíncrona, o que exigirá algumas mudanças, mas nada que faça com que seja necessário escrever e/ou gerenciar uma porção de código para garantir o assincronismo. Com isso, o primeiro detalhe a notar na escrita da ação assíncrona, é a exigência da keyword async, que faz parte do C#. Além disso, uma das grandes diferenças aqui, é com relação ao tipo de retorno da ação. No exemplo anterior, retornávamos um IEnumerable<T>, onde o tipo T é representado pela classe NoticiaDaRegiao. Aqui, ao invés disso, vamos retornar um Task<TResult>, onde TResult será definido com o mesmo tipo de retorno da ação síncrona, ou seja, IEnumerable<NoticiaDaRegiao>.

Internamente a implementação também mudará. Passamos a recorrer a classe HttpClient, que fará parte do .NET Framework, utilizado para consumir serviços REST, fornecendo vários facilitadores. Além disso, o fato de colocarmos a keyword async na assinatura do método, o compilador já nos obriga a definir o local que vamos aguardar pelo resultado, e para isso, utilizamos uma segunda keyword, chamada de await. No exemplo abaixo aguardamos a resposta voltar, e além disso, também invocamos a leitura do corpo da mensagem de forma assíncrona. Com isso, a ação que tínhamos foi rescrita e ficou da seguinte forma:

public class NoticiasRegionaisController : ApiController
{
    private const string ServicoDeNoticias =
        “http://localhost:1256/api/noticias/recuperar&#8221;;

    [HttpGet]
    public async Task<IEnumerable<NoticiaDaRegiao>> Recuperar()
    {
        using (var client = new HttpClient())
            return await
                (await client.GetAsync(ServicoDeNoticias))
                .Content
                .ReadAsAsync<IEnumerable<NoticiaDaRegiao>>();
    }
}

Com isso, ao executarmos novamente os testes, agora contra o serviço implementado de forma assíncrona, veremos um ganho considerável, onde o tempo de resposta diminui e a quantidade de requisições atendidas por segundo aumenta. O gráfico abaixo já reflete essa mudança:

A implementação assíncrona trouxe um resultado interessante, aumentando a capacidade da aplicação de lidar com muitas requisições, e isso tende a aumentar dependendo das características do ambiente, como máquina, recursos, funcionalidades do serviço, etc.

SingleWSDL no WCF

Como o WCF é fortemente baseado em SOAP, ele fornece várias funcionalidades para lidar com os documentos WSDL, que são documentos que descrevem as funcionalidades e os tipos de dados utilizados por um determinado serviço. Com este arquivo, podemos referenciá-lo nas aplicações clientes, para que elas possam construir toda a infraestrutura necessária (proxy) para realizar a comunicação.

Só que o documento WSDL gerado pelo WCF contém em seu interior, os detalhes referente as funcionalidades que são expostas pelo serviço. Já as operações podem receber e/ou retornar vários tipos de dados, que devem também estar contemplados no documento. Só que ao invés disso, toda a estrutura dos tipos utilizada pelas operações do serviço, é colocada em arquivos externos (XSD), e o WSDL apenas os referencia.

Ao consumir estes tipos de documentos dentro do próprio .NET, não há problemas, pois ele consegue facilmente importar o documento WSDL e resolver essas dependências. O problema começa a aparecer quando consumimos este WSDL em outras tecnologias, que exigem que todas as definições do serviço estejam dentro de um mesmo arquivo, não lidando com essa modularização. Por estas questões de interoperabilidade, temos que recorrer à algumas implementações customizadas para gerar o WSDL neste formato. Uma das opções mais conhecidas é o FlatWSDL, criada pelo Christian Weyer, já há algum tempo.

Já na versão 4.5 do WCF, a Microsoft já trará isso nativamente, ou seja, a criação do serviço continua a mesma, só que podemos acessar o endereço que expõe o WSDL, anexando na querystring o sufixo ?singleWsdl, o que fará com que o documento WSDL gerado, incluia toda a informação necessária, sem referências para arquivos externos. Abaixo temos uma imagem quando acessamos este serviço no navegador. Note que há um link na página que já aponta para este novo recurso.

Características do ASP.NET Web API

Como o ASP.NET Web API é implementando sobre o ASP.NET MVC, muitas das funcionalidades que o MVC possui, foram reutilizadas pelo Web API, para que os mesmos recursos e a mesma forma de configuração sejam equivalentes, não importando se estamos desenvolvendo um site ou uma API para ser exposta e consumida pelos clientes.

Entre as funcionalidades mais comuns, temos o envio de tipos complexos, ou seja, a capacidade das aplicações criarem objetos, definir seus atributos, e submetê-los ao serviço. Isso nos permite criar objetos que descrevem o nosso negócio, tornando bem mais intuitivo que criar um método com vários parâmetros. Além disso, nem sempre o serviço rodará sem qualquer problema; durante a execução vários tipos de exceção podem acontecer, e o tratamento por parte do serviço e a formatação da resposta precisam ser cuidadosamente pensadas, afinal, precisamos no basear nos códigos do HTTP para reportar o problema. Finalmente, muitas vezes as APIs recorrem a recursos externos, tais como: leitura/escrita de arquivos, leitura/escrita de dados no banco de dados, etc., e ao invés do serviço depender diretamente da implementação, podemos fazer com ele dependa de uma abstração, que durante a execução, o objeto concreto é injetado. Para isso, podemos recorrer aos serviços de injeção de dependência, que já estão espalhados pelo ASP.NET Web API, e que nos permitirá customizar várias situações, em pontos distintos.

A ideia deste artigo é introduzir cada um destes tópicos, com detalhes de implementação, ao qual poderemos recorrer durante a construção das nossas APIs.

Model Binding

As aplicações geralmente trabalham com objetos que descrevem suas características, onde estes objetos são manipulados o tempo todo, já que na grande maioria dos casos, ela acaba também sendo persistido no banco de dados, apresentado na tela, etc. Como esses objetos são parte do core da aplicação, é muito comum criarmos formulários que apresente a instância no mesmo na tela (HTML), para que o usuário seja capaz de editá-lo.

Ao submeter o formulário para o servidor, todas as informações (querystrings, body, URI, etc.) chegam através de um dicionário, onde cada valor está associado à uma chave. Ao invés de manualmente construirmos a instância da classe baseada no corpo da requisição, o ASP.NET MVC já fez esse árduo trabalho para nós, e o responsável por isso são os model binders. Baseando-se na action para qual estamos postando a requisição, ele captura o tipo do objeto que precisa ser criado, mapeando o dicionário para cada uma de suas propriedades.

Quando utilizamos o ASP.NET Web API, não é diferente, ou seja, quando o nosso serviço espera um objeto complexo, o ASP.NET faz o trabalho para entregá-lo já materializado para nós. Neste caso, há como recebermos a postagem de um formulário HTML, mas também temos que nos atentar, que na maioria das vezes, vamos lidar com o conteúdo em formato XML ou JSON.

Os formatters, já discutido anteriormente, executam um papel importante aqui. Apesar da tecnologia ter sido readequada para o ASP.NET, os principais formatters foram mantidos: FormUrlEncodedMediaTypeFormatter, JsonMediaTypeFormatter e o XmlMediaTypeFormatter. Baseando-se no header Content-Type da própria requisição, ele escolhe qual destes formatters irá utilizar para extrair as informações do corpo da mensagem, e na sequência, encaminha as informações para que o model binder faça a criação do objeto e, consequentemente, atribua os respectivos valores.

Levando em consideração que temos uma ação que receba como parâmetro a instância da classe Cliente, que por sua vez, possui duas propriedades (Nome e Email), podemos postar o conteúdo em qualquer formato, e desde que haja um formatter para o tipo de conteúdo submetido (Content-Type), o ASP.NET Web API também será capaz de transformá-lo em algo concreto. Abaixo temos a assinatura da ação, e na sequência, os posts efetuados com os diferentes formatos.

[HttpPost]
public void Adicionar(Cliente cliente) { }

[ Via Formulário ]

POST http://localhost:1062/api/clientes/Adicionar HTTP/1.1
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: localhost:1062
Content-Length: 35

Nome=Israel&Email=ia@israelaece.com

[ Via JSON ]

POST http://localhost:1062/api/clientes/Adicionar HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:1062
Content-Length: 48

{“Nome”: “Israel”, “Email”: “ia@israelaece.com”}

[ Via XML ]

POST http://localhost:1062/api/clientes/Adicionar HTTP/1.1
User-Agent: Fiddler
Content-Type: application/xml
Host: localhost:1062
Content-Length: 70

<Cliente><Nome>Israel</Nome><Email>ia@israelaece.com</Email></Cliente>

Validações

Uma vez que o model binder foi capaz de construir o objeto baseando-se na requisição, um passo, que pode ser opcional, é a validação desse objeto, que consiste em saber se todas as propriedades do mesmo foram extraídas da requisição, e estão com seus valores definidos conforme esperado.

Novamente, assim como no ASP.NET MVC, o Web API também pode confiar nos Data Annotations do .NET Framework para validar se o objeto encontra-se em um estado válido. Para isso, basta decorarmos as propriedades com os mais variados atributos que existem debaixo do namespace System.ComponentModel.DataAnnotations. Só que apenas isso não é suficiente, pois na versão atual (Beta), o ASP.NET Web API não executa automaticamente as validações, e sendo assim, precisamos interceptar a requisição, e antes da ação ser executada, validarmos se o estado do objeto está ou não válido.

Para isso, temos que criar um filtro herdando de ActionFilterAttribute, sobrescrevendo o método OnActionExecuting. Como parâmetro recebemos a instância da classe HttpActionContext, que como o próprio nome diz, traz informações pertinentes ao contexto da requisição atual. Entre as várias propriedades, ela expõe uma chamada de ModelState, que define um dicionário contendo o estado do modelo e determina se o mesmo passou ou não nas eventuais regras de validação que foram definidas.

Com isso, podemos facilmente recuperar os detalhes das validações realizadas, e repassá-las para que o cliente possa ter informações precisas sobre os problemas que aconteceram. Para interrompermos a execução, basta criar uma mensagem de resposta (HttpResponseMessage), definindo que a requisição não está de acordo com o esperado, e atribuí-la a propriedade Response do contexto. Abaixo temos a implementação deste atributo:

public class ModelValidationAtribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext ctx)
    {
        if (!ctx.ModelState.IsValid)
        {
            ctx.Response =
                new HttpResponseMessage<IEnumerable<ErrorDetails>>
                (
                    from e in ctx.ModelState.Values
                    where e.Errors.Count > 0
                    select new ErrorDetails()
                    {
                        Message = e.Errors.First().ErrorMessage
                    },
                    HttpStatusCode.BadRequest
                );
        }
    }
}

Para injetá-lo na execução, podemos decorar diretamente na classe (controller) ou no método (action), ou como é algo comum para qualquer ação do serviço, podemos definí-lo como um filtro global, que automaticamente será executado por toda e qualquer ação que é executada naquela aplicação. O trecho do código abaixo foi adicionado ao arquivo Global.asax, para que o filtro seja adicionado à aplicação durante o início da mesma.

GlobalConfiguration
    .Configuration
    .Filters
    .Add(new ModelValidationAtribute());

Um detalhe interessante é com relação a negociação do conteúdo. Se houver algum problema, é importante que o runtime devolva a resposta ao cliente de acordo com o tipo que ele aceita. Ele olhará para o header Accept para determinar em que formato ele devolverá o conteúdo ao cliente, e com isso, o nosso filtro fica completamente isento em relação à detalhes de formatação da resposta. Abaixo temos a requisição sendo rejeitada pelo serviço:

[ Via JSON ]

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Tue, 06 Mar 2012 11:30:41 GMT
Content-Length: 43

[{“Message”:”The Nome field is required.”}]

[ Via XML ]

HTTP/1.1 400 Bad Request
Content-Type: application/xml; charset=utf-8
Date: Tue, 06 Mar 2012 11:28:46 GMT
Content-Length: 255

<?xml version=”1.0″ encoding=”utf-8″?>
<ArrayOfErrorDetails xmlns:xsi=”…” xmlns:xsd=”…”>
    <ErrorDetails>
        <Message>The Nome field is required.</Message>
    </ErrorDetails>
</ArrayOfErrorDetails>

Tratamento de Erros

Durante a execução, uma porção de exceções podem acontecer, sejam elas referentes à infraestrutura ou até mesmo à alguma regra de negócio, e o não tratamento correto delas, fará com as mesmas não sejam propagadas corretamente ao cliente que consome a API. A maior preocupação aqui é mapear o problema ocorrido para algum código HTTP correspondente.

Tratar as exceções in-place pode não é uma saída elegante, devido a redundância de código. Para facilitar, podemos centralizar o tratamento em nível de aplicação, o que permitirá com que qualquer exceção não tratada no interior da ação, será capturada por este tratador, que por sua vez, analisará o erro ocorrido, podendo efetuar algum tipo de logging e, finalmente, encaminhar o problema ao cliente. É neste momento que podemos efetuar alguma espécie de tradução, para tornar a resposta coerente ao que determina os códigos do HTTP, como por exemplo: se algum erro relacionado à autorização, devemos definir como resposta 403 (Forbidden); já se algum informação está faltante (assim como vimos no exemplo acima), devemos retornar (400) BadRequest; já se o registro procurado não foi encontrado, ele deverá receber o código 404 (NotFound), e assim por diante.

Da mesma forma que vimos acima, aqui também vamos recorrer a criação de um filtro customizado para centralizar a tradução de algum problema que acontecer. Só que neste caso, temos uma classe abstrata chamada de ExceptionFilterAttribute, que já fornece parte da infraestrutura necessária para o tratamento de erros que ocorrem, e é equivalente ao atributo HandleErrorAttribute que temos no ASP.NET MVC. Tudo o que precisamos fazer aqui é sobrescrever o método OnException e definir toda a regra de tradução necessária. Abaixo um exemplo simples de como proceder para realizar esta customização:

public class ExceptionTranslatorAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext ctx)
    {
        var errorDetails = new ErrorDetails();
        var statusCode = HttpStatusCode.InternalServerError;

        if (ctx.Exception is HttpException)
        {
            var httpEx = (HttpException)ctx.Exception;

            errorDetails.Message = httpEx.Message;
            statusCode = (HttpStatusCode)httpEx.GetHttpCode();
        }
        else
        {
            errorDetails.Message = “** Internal Server Error **”;
        }

        ctx.Result =
            new HttpResponseMessage<ErrorDetails>(errorDetails, statusCode);
    }
}

Assim como no caso do validação que vimos acima, podemos aplicar este atributo em nível de classe (controller) ou de método (action), mas como o tratamento é, geralmente, comum para todos os serviços que rodam dentro da aplicação, então podemos, novamente, aplicar em nível global, assim como é mostrado no código a seguir:

GlobalConfiguration
    .Configuration
    .Filters
    .Add(new ExceptionTranslatorAttribute());

Injeção de Dependências

Quando criamos a classe que representará a API, definimos os métodos que serão expostos para os clientes. No interior destes métodos, vamos escrever o código necessário para atender a necessidade dos mesmos, seja calculando, persistindo ou devolvendo alguma informação que é exigida por ele.

Com isso, é extremamente comum que a classe que representa a API necessite recorrer a recursos externos para executar qualquer uma dessas ações, como por exemplo: se ele necessitar salvar alguma informação no banco de dados, precisamos da classe responsável por realizar isso (repositório). O mesmo acontecerá quando ele necessite de alguma informação, pois muito provavelmente, recorreremos a este mesmo repositório.

Todas as funcionalidades e/ou informações que a API precise, e que não seja de responsabilidade dela gerenciar, ela dependerá disso para cumprir o seu objetivo. Com isso, de alguma forma precisaremos injetar essas dependências na API, e com isso, torná-la independente de qualquer implementação concreta, para que se tenha flexibilidade e que facilite os testes.

Como a criação do controller que representa a API é feita pelo próprio ASP.NET, a Microsoft deixou alguns pontos em que podemos customizar a criação do mesmo, e com isso, temos a possibilidade de criarmos a dependência exigida pela API, ou se ainda desejar, recorrer a algum container de injeção de dependência de sua preferência, para que ele contemple e gerencia todas as dependências daquela aplicação.

Incrementando a API que utilizamos acima, ela precisa de um repositório para ler/persistir os clientes no banco de dados. Sendo assim, vamos mudar a API e colocar um construtor exigindo o tal repositório, já que é o mínimo que ela precisa para poder desempenhar a sua atividade.

public class Clientes : ApiController
{
    public Cliente(IRepositorioDeClientes repositorio)
    {
        //…
    }

    [HttpPost]
    public void Adicionar(Cliente cliente)
    {
        //…
        repositorio.Adicionar(cliente);
    }
}

ASP.NET Web API recorre a um resolver, e que podemos fornecer a nossa própria implementação, nos permitindo determinar a forma como construímos as dependnências (incluindo dependências relacionadas à infraestrutura), ou ainda, como disse acima, recorrer à utilização de algum container de DI, e você verá que isso é muito próximo ao padrão que já temos implementado com o ASP.NET MVC. Para customizarmos, basta criarmos uma classe que implemente a interface IDependencyResolver, qual fornece dois métodos autoexplicativos: GetService e GetServices. Abaixo uma implmentação simples deste resolvedor:

public class HardcodeResolver : IDependencyResolver
{
    public object GetService(Type serviceType)
    {
        if (serviceType == typeof(ClientesController))
            return new ClientesController(new RepositorioDeClientes());

        return null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return new List<object>();
    }
}

Da mesma forma, como grande parte dos recursos que vimos acima, a criação desta classe não é suficiente para poder funcionar, pois precisamos incorpora-la à execução. O ASP.NET Web API fornece uma classe que gerencia a configuração das APIs que rodam na aplicação, e ela é chamada de HttpConfiguration. Esta classe possui vários membros, e entre eles expõe uma propriedade chamada de ServiceResolver, que como o próprio nome sugere, é utilizada para resolver os serviços requeridos pelo serviço.

Nesta classe existe um método chamado SetResolver, que como parâmetro recebe uma classe que implemente a interface IDependencyResolver. É por este ponto de estensibilidade que plugamos a classe que criamos para resolver as dependências. O código abaixo exibe como procedemos para colocá-la em execução:

GlobalConfiguration
    .Configuration
    .ServiceResolver
    .SetResolver(new HardcodeResolver());

Há também um overload deste mesmo método que nos permite passar, via lambdas, o método que deverá criar a instância das dependências, não precisando assim criar uma classe específica para isso. Abaixo temos a mesmo exemplo só que utilizando esta outra opção:

GlobalConfiguration
    .Configuration
    .ServiceResolver
    .SetResolver
    (
        serviceType =>
        {
            if (serviceType == typeof(ClientesController))
                return new ClientesController(new RepositorioDeClientes());

            return null;
        },
        serviceType => return new List<object>()
    );

Um detalhe importante aqui é que quando a dependência não for resolvida, o ASP.NET Web API espera que retornemos um valor nulo ao invés de disparar uma exceção. Retornando nulo, fará com que o runtime escolha alguma implementação padrão, caso ela exista.

A classe DependencyResolver ainda lida com diversos outros recursos que são utilizados pela própria infraestrutura do ASP.NET Web API. Isso quer dizer que o Web API também recorre a este mesmo objeto, para buscar recursos que ele precisa para funcionar, e com isso, podemos utilizá-lo para inserir as customizações que desenvolvemos quando queremos alterar alguma configuração/comportamento diferente do padrão.

ASP.NET Web API – Overview

Como mencionei anteriormente, a partir da versão 4, o ASP.NET MVC passará a ter uma infraestrutura completa para a construção e hospedagem de serviços REST. Apesar de essencialmente ser baseado em uma template Web, há algumas mudanças em como implementar o serviço em relação a como fazíamos no WCF Web API.

Ao instalar essa versão, que ainda encontra-se em Beta, passamos a ter uma template de projeto chamada ASP.NET MVC 4, e ao selecioná-la, uma segunda tela é exibida para escolhermos uma entre as seis opções disponíveis, sendo que uma delas é a Web API. Basicamente, cada uma delas traz um projeto pré-configurado com os recursos necessários para que ele funcione corretamente.

Se começarmos a explorar esta template, já começamos a nos deparar com alguns destes recursos configurados. Em primeiro lugar, podemos notar a existência de novos assemblies, que são utilizamos para a construção de APIs Web. Entre eles, o principal é o System.Web.Http.dll, que possui grande parte dos tipos que são utilizados por estes serviços, incluindo tipos que serão utilizados diretamente pelo serviço, bem como tipos que são utilizados pela infraestrutura e pipeline.

Como estamos utilizando a infraestrutura do ASP.NET MVC, as classes que servirão como serviços, deverão herdar da classe abstrata ApiController, que possui características diferentes do Controller tradicional, próprio do MVC; e este novo controller fornece detalhes específicos para a construção de serviços. Os métodos que estarão acessíveis pelos clientes, serão métodos (ações) que estarão dentro desta classe, e que através do sistema de roteamento, deverá procurar e encontrar pela classe/método de acordo com a URI informada.

Dentro desta classe podemos receber e/ou retornar tipos simples, bem como tipos complexos, que são aquelas classes que criamos para representar nossas entidades. Se precisarmos de um acesso mais refinado, da requisição ou da resposta, podemos recorrer ao uso das classes HttpRequestMessage<T> e HttpResponseMessage<T>, mas que infelizmente na versão atual (ainda em Beta), não há nenhum model binder que faz conversão da requisição em um objeto do tipo HttpRequestMessage<T>, mas segundo o time, isso será resolvido em futuras versões. Se precisarmos acessar informações pertinentes à requisição, então devemos recorrer à propriedade Request diretamente, exporta pela classe ApiController. Abaixo temos um exemplo simples de como fica a classe que conterá os métodos de exemplo:

public class NoticiasController : ApiController
{
private static IList<Noticia> noticias = new List<Noticia>();

public IQueryable<Noticia> Get()
{
return noticias.AsQueryable();
}

public Noticia Post(Noticia noticia)
{
noticias.Add(noticia);
return noticia;
}
}

Com essa implementação, já é tudo o que precisamos para poder consumi-lo em uma aplicação cliente. Há um detalhe que passa despercebido no código acima, que é a nomenclatura dos métodos. Note que propositalmente nomeamos o primeiro como Get e o segundo como Post, que refletem dois dos mais comuns verbos do protocolo HTTP.

Na verdade, como parte da template do projeto, já há uma configuração no arquivo Global.asax, que determina uma rota padrão para os serviços. Copiei abaixo a configuração, e podemos notar que há espaço para o controller, mas nada é mencionado em relação ao método/ação na rota. Existem algumas deduções que ele faz, como por exemplo, verificar se dentro do controller há um método, sem parâmetros, onde o nome inicie com “Get…”. O mesmo coisa acontece com o método Post e também para os outros métodos GET e PUT do HTTP.

routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{id}”,
defaults: new { id = RouteParameter.Optional }
);

Se desejar definir um nome diferente destas regras, você pode recorrer aos atributos HttpGetAttribute, HttpPostAttribute, HttpPutAttribute e HttpDeleteAttribute, para dizer ao framework o que e como pode ser acessado um determinado método dentro desta classe.

Algumas funcionalidades inerentes ao HTTP já estão devidamente configuradas, como por exemplo, basta apontar o header Content-Type ou Accept, do tipo do conteúdo ou tipo da resposta, respectivamente, e o ASP.NET Web API já sabe como deve ler/gerar o conteúdo. Além disso, já existe suporte nativo a alguns operadores do protocolo OData, como paginação, ordenação, etc., e para tudo isso funcionar, a única preocupação é que nosso método retorne a instância de uma classe que implemente a interface IQueryable<T>, e a partir daí, é só incorporar na querystring os parâmetros necessários.

Finalmente, podemos perceber neste pequeno trecho de código, que a construção de um serviço REST acaba ficando mais simples se comparado ao WCF Web API, e muito mais simples ainda, se compararmos com o WCF HTTP.

WCF Web API agora é ASP.NET Web API

Por algum tempo eu venho falando sobre um novo projeto da Microsoft chamado de WCF Web API, que trata-se de um espécie de estensão do WCF que facilita a construção e o consumo de serviços que são puramente Web (REST), ou seja, estão fortemente amarrados ao protocolo HTTP e o assumem como uma camada de aplicação. Abaixo temos alguns dos artigos que escrevi e que abordam essa tecnologia:

Apesar de possuir uma forma de hospedar esse tipo de serviço através de uma aplicação do tipo Windows (Windows Service, Console, etc.), a sua forma mais natural é utilizar o IIS, ou melhor, utilizar qualquer template de aplicação ASP.NET e lá criar a classe que representará o serviço, e apenas com uma linha de código, é o suficiente para mapear uma URI base para o serviço e tudo magicamente funciona, sem a necessidade de uma configuração extra no arquivo Web.config.

Foi a partir deste momento que nos perguntarmos porque não utilizar o próprio ASP.NET MVC? Com o ASP.NET você tem acesso a todo conjunto de recursos do HTTP, já que projetos Web tem afinidade com este protocolo. Além disso, a necessidade que os scripts tem em invocar um método C#, fez com que a Microsoft criasse um tipo de resultado chamado de JsonResult, qual retorna um valor “facilmente legível” para o Javascript.

Haviam certos overlaps entre o WCF Web API e o ASP.NET MVC, onde cada um deles determina uma forma específica de utilizar o mesmo protocolo, que é o HTTP. Então, para remover essa confusão, a Microsoft decidiu juntar essas duas tecnologias, e daí surgiu o ASP.NET Web API.

Com essa mesclagem alguns dos elementos que compunham o WCF Web API não existirão mais, justamente porque o ASP.NET MVC trata de outra forma. No ASP.NET Web API, agora vamos lidar com controllers e actions ao invés de uma classe decorada com o atributo ServiceContractAttribute e de métodos decorados com WebGetAttribute/WebInvokeAttribute. O roteamento do ASP.NET será utilizado para direcionar as requisições aos serviços. O model binding será o responsável por materializar o corpo da requisição em objetos complexos que, eventualmente, receberemos em nossos métodos. As actions filters serão utilizados ao invés de operation handlers, e ainda em tempo, se quisermos manipular complementamente a mensagem de requisição/resposta, continuamos tendo acesso às classes HttpRequestMessage e HttpResponseMessage.

Particularmente, eu gosto mais da ideia de ter um único framework que aborda os mais diferentes tipos de comunicação ao invés de atrelar isso especificamente a um tipo de projeto, mas também sou capaz de compreender a necessidade que a Microsoft tem de apartar isso, afinal, o WCF foi construído quando todos pensavam que o protocolo SOAP seria a solução para todo e qualquer tipo de comunicação existente, e o protocolo HTTP só seria mais um meio de transporte. Mas como percebemos ao longo do tempo, em certas ocasiões, ele é extremamente overkill. Mas é importante dizer que há funcionalidades que o SOAP possui que são bem interessantes, e se utilizadas da forma correta, podem trazer vários benefícios, mesmo em ambientes homogêneos. De qualquer forma, em posts futuros mostrarei como procedemos para construir serviços através desta nova tecnologia, que é o ASP.NET Web API.

Introdução ao CORS

Nos dias de hoje vivemos em um mundo cada vez mais conectado (virtualmente falando), o que nos faz criar sites e aplicações que consumam ou forneçam informações uns aos outros, tendo um conteúdo mais consistente, reutilizável e, principalmente, sincronizado. Sendo assim, existem diversas fontes de informação ao redor do mundo, que provê os mais variados conteúdos que podemos consumir em nossas aplicações.

Só que trazendo isso para o lado técnico, nos deparamos com uma grande limitação (por questões de segurança), que é o consumo de informações por parte de uma aplicação Web, onde ela somente está autorizada a consumir dados que são disponibilizados a partir do mesmo domínio de onde ela se originou (Same Origin Policy).

Uma das alternativas que temos atualmente para burlar isso, é a utilização do JSONP. Com este recurso, podemos efetuar requisições GET para um determinado recurso, mesmo que esteja além do domínio de origem, e conseguiremos recuperar as informações desejadas. O problema do JSONP é que ele somente trabalha com o verbo GET, ou seja, outros verbos não são suportados, nem mesmo o POST, já que a requisição JSONP faz uso da tag <script />, levando os parâmetros somente via querystring.

Mais cedo ou mais tarde vamos nos deparar com a necessidade de submeter algo além de simples GETs para um servidor. Para resolvermos isso, existe uma solução que está lentamente se tornando uma saída viável, é o CORS (Cross-Origin Resource Sharing). Basicamente, o CORS é uma especificação que está sendo criada e regida pelo W3C, qual define uma forma de acesso à recursos que estão em diferentes domínios.

O CORS é implementado no objeto XmlHttpRequest, e a ideia por trás dele é o uso de headers customizados que são injetados na requisição e resposta do HTTP, e que faz com que o cliente (navegador) e o servidor se conheçam, afim de determinar se a requisição deve ou não ser executada com sucesso, sendo algo mais ou menos como acontece com o Client Access Policy do Silverlight.

Observação: Apesar do XmlHttpRequest ser comum para todos os navegadores, infelizmente no caso do Internet Explorer, esse recurso é implementado em um objeto separado, chamado de XDomainRequest. Com isso, ele nos obriga a criar um código diferenciado caso estejamos rodando o código no navegador da Microsoft. A novidade é que o time do IE, recentemente publicou em seu blog, que o CORS está sendo implementado diretamente no objeto XmlHttpRequest, ficando compatível com a grande maioria dos navegadores do mercado.

Ao invés de utilizar diretamente estes objetos, podemos recorrer ao jQuery, que graças à um recurso chamado de detecção de funcionalidades, ele é capaz de detectar a presença dos objetos mencionados acima, e se existirem, podem fazer uso dele. No caso do CORS não é diferente, e vamos utilizá-lo aqui para mostrar como podemos proceder para consumir um recurso que está em outro domínio. Para o exemplo, considere o diagrama abaixo:

Como mencionei acima, é através da verificação dos headers na requisição/resposta, que o navegador decide se pode ou não concluir o processo. Se interceptarmos a requisição que é realizada, podemos notar as informações que são trocadas, incluindo os “novos” headers. Abaixo temos a requisição e a resposta, mas omitindo algumas informação irrelevantes para a explicação:

[ Requisição ]
GET http://localhost:5342/Servicos/ViaGet?valorDeEnvio=abc HTTP/1.1
Host: localhost:5342
Origin: http://localhost:5560
Referer: http://localhost:5560/Index.htm

[ Resposta ]
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:5560
Content-Type: application/json; charset=utf-8

{“ValorInformado”:”abc”}

Note que a requisição é realizada através da aplicação que está localizada no endereço http://localhost:5560, encaminhando-a para um serviço que encontra-se em um outro local, além desta, localizada no endereço http://localhost:5342. O grande detalhe a se notar na requisição é o header Origin, que é controlado pelo navegador, que o injeta na requisição. Já na resposta, o servidor analisa se aquele site solicitante (de qual partiu a requisição) possui ou não permissão para executar a requisição. Para indicar ao navegador que é permitido o acesso, basta retornar o endereço da aplicação que solicitou (ou * para qualquer uma) como valor do header Access-Control-Allow-Origin. Caso não informe nenhuma destas duas informações, a requisição não será concluída.

Requisições via GET com JSONP podem ser encaminhadas para outros servidores sem problemas; podemos também postar (POST) um formulário para um outro domínio. Em ambos os casos, não haveria necessidade de utilizar CORS. Qualquer outra requisição que diferencie destes critérios, deve utilizar o CORS para atingir o objetivo que queremos, e também exigirá uma cooperação por parte do servidor para conseguir executa-la.

Por exemplo, métodos como PUT ou DELETE, ou ainda, o envio de alguns headers ou de headers customizados, também podem ser controlados pelo servidor, pois será ele que definirá quais headers e/ou verbos que poderão ser acessíveis aos clientes. Para exemplificar, vamos supor que desejamos enviar um header customizado para o serviço, e ele deverá nos dizer se ele pode ou não ser encaminhado. Vamos analisar a imagem abaixo para ilustrar o comportamento deste outro cenário:

Note que agora temos duas requisições sendo realizadas ao servidor. A primeira é conhecida como preflight request, qual utiliza o método OPTIONS do HTTP, que tem a finalidade de extrair alguma informação a respeito da comunicação, e como já suspeitamos, vai trazer as informações necessárias para o navegador determinar se pode ou não ser executada. Vamos analisar a as requisições:

A primeira requisição encaminha ao servidor (1), além do Origin, mais dois headers: Access-Control-Request-Method e Access-Control-Request-Headers. O primeiro deles questiona o servidor se o cliente pode ou não executar um GET, enquanto o segundo questiona se o cliente pode ou não encaminhar os headers ali definidos. Na resposta para a requisição de OPTIONS, mais dois – novos – headers são devolvidos (2): Access-Control-Allow-Methods e Access-Control-Allow-Headers. O primeiro informa uma lista de métodos que são permitidos aquele cliente encaminhar; já o segundo, lista quais são os headers que podem ser encaminhados ao servidor. Depois de validado pelo navegador, a requisição efetiva é encaminhada para o servidor (3), qual retornará o conteúdo propriamento dito (4).

Como vimos, em duas etapas conseguimos realizar a comunicação entre domínios diferentes, com a possibilidade de refinar como ela deve ser executada. Como mencionei anteriormente, isso parece ser uma opção viável as técnicas que temos hoje para a comunicação entre domínios, e pelo que parece, há um grande empenho por parte dos fabricantes a adotá-lo. E, para finalizar, ainda é necessário que o servidor (serviço), saiba lidar com este tipo de requisição, que será tema para um outro post.

Habilitando JSONP no ASP.NET MVC

Recentemente mostrei aqui como devemos proceder para fazer uso do JSONP no WCF Web API, que permite o consumo de serviços através de domínios diferentes. Algumas vezes, quando já existe um projeto Web do tipo ASP.NET MVC, podemos expor uma ação no controller para que ele seja consumido diretamente pelo lado cliente da mesma (Javascript/jQuery), sem qualquer problema referente à chamada cross-domain.

Mas se quisermos expor isso para clientes que estão além do mesmo domínio, vamos nos deparar com os problemas que já conhecemos e/ou vimos anteriormente. A classe JsonResult, que já é parte do MVC, expõe um conteúdo baseado em JSON, mas não é capaz de envolver a resposta em uma função de callback (JSONP), algo que é necessário para que o jQuery/JSONP possa ser capaz de processar o resultado.

Temos várias alternativas para que isso funcione corretamente, e uma delas, seria criar um resultado customizado para capturar o nome da função de callback, que no caso do jQuery, é encaminhada através da querystring chamada callback, e por fim, envolvemos o resultado definido no interior da ação do controller nesta função, retornando o resultado conforme é esperado pelo jQuery. Abaixo temos o código que define um resultado de uma requisição via JSONP:

public class JsonpResult : JsonResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException(“context”);

        var callback = context.HttpContext.Request[“callback”];

        if (string.IsNullOrWhiteSpace(callback))
            throw new ArgumentNullException(“É necessário informar a função de callback”);

        if (this.Data != null)
            context.HttpContext.Response.Write(
                string.Format(“{0}({1});”,
                    callback, 
                    new JavaScriptSerializer().Serialize(this.Data)));
    }
}

Com este novo tipo criado, podemos simplesmente retornar uma instância desta classe, definido a propriedade Data (herdada da classe JsonResult) com o valor do objeto que queremos serializar, e o JsonpResult se encarregará de fazer o restante do trabalho, deixando o controller isento de qualquer código que interessa – somente – à infraestrutura.

public class ServicosController : Controller
{
    public ActionResult ViaGet(string valor)
    {
        return new JsonpResult() { Data = new { ValorInformado = “bla bla bla” } };
    }
}

Assincronismo no WPF

Uma grande necessidade que existe ao escrevermos aplicações, é a necessidade de executar tarefas custosas e/ou periódicas (polling). Muitas vezes, se elas forem escritas em sua forma tradicional, vamos nos deparar com uma experiência ruim durante o uso do software, justamente porque essas tarefas serão executadas de forma síncrona, ou seja, até que elas não sejam concluídas, o usuário não poderá acessar qualquer outra área do sistema.

O .NET Framework fornece desde as primeiras versões suporte para escrita de código assíncrono. O problema é que a escrita deste código não é lá muito trivial, tendo que lidar com muitos detalhes de baixa nível, tais como asyncs results, callbacks, sincronização, etc. Para facilitar isso, a Microsoft trabalha na criação de novos recursos que serão incorporados na própria linguagem (C# e VB.NET), tornando a programação assíncrona muito mais simples de ser realizada, tornando-a tão intuitiva quanto a programação síncrona.

Além dessa mudança nas linguagens, ainda temos o Reactive Extensions, que uma das suas funcionalidades, é prover uma forma diferente de lidar com a programação assíncrona, que ao invés de “puxarmos” o resultado de algum lugar, podemos fazer com que esse resultado seja “empurrado” para a aplicação, o que lhe permitirá trabalhar de forma reativa. A finalidade deste artigo é apresentar como podemos proceder para trabalhar de forma assíncrona em uma aplicação Windows, e para o exemplo, vamos recorrer a um projeto baseado em WPF em conjunto com o Reactive Extensions.

Como disse anteriormente, podemos executar uma tarefa de forma assíncrona ou executar uma ação periodicamente. No primeiro caso, em que precisamos executar uma tarefa de forma assíncrona, podemos recorrer ao método de extensão ToAsync da classe Observable. Esse método possui centenas de overloads, qual contempla grande parte (senão todas) das versões dos delegates Action e Func. Sendo assim, podemos vincular diretamente um método que leva um tempo longo para executar, e com isso, reagir quando o resultado for retornado. A implementação deste código pode variar dependendo se você está ou não utilizando o padrão MVVM. Abaixo temos o exemplo de como podemos proceder para executar um cálculo custoso de forma assíncrona, utilizando Reactive Extensions, sem MVVM:

private void Operacao_Click(object sender, RoutedEventArgs e)
{
    int v1 = int.Parse(this.Valor1.Text);
    int v2 = int.Parse(this.Valor2.Text);

    Observable
        .ToAsync<int, int, int>(Somar)(v1, v2)
        .ObserveOnDispatcher()
        .Subscribe<int>(r => this.Resultado.Text = r.ToString());
}

private int Somar(int v1, int v2)
{
    Thread.Sleep(4000);

    return v1 + v2;
}

O único comentário relevante ao método Somar é que ele simula um processamento custoso através do método Sleep. Já no evento Click do botão, invocamos o método ToAsync, informando qual o método que deve ser disparado de forma assíncrona, incluindo logo na sequência, os parâmetros exigido pelo método Somar. Quando chamamos o método Subscribe, ele passa a monitorar qualquer resultado (de sucesso) gerado pelo método Somar, e neste caso, estamos apresentando-o em um terceiro TextBox.

Um detalhe extremamente importante é sobre o método ObserveOnDispatcher. O WPF possui uma classe chamada Dispatcher, que serve como um gerenciador de tarefas para serem executadas, e está sempre associada com uma determinada thread de UI. Isso quer dizer que qualquer notificação enviada pelo método Somar será enviada e executada pela própria thread que criou os controles de UI, já que aplicações Windows (WPF e Windows Forms) possuem essa afinidade. Se não nos atentarmos a este método, uma exceção do tipo InvalidOperationException será disparada, contendo a seguinte mensagem: The calling thread cannot access this object because a different thread owns it.

Já quando utilizamos MVVM, a implentação é um pouco diferente por conta da estrutura imposta pelo padrão. Os botões da View (Xaml) são executados através de um comando que deve implementar a interface ICommand. Neste caso, é muito comum recorrer à criação de um comando chamado de RelayCommand, que permite você injetar a lógica do comando a ser executado através de delegates. Só que é importante dizer que a execução deste comando é realizado de forma síncrona. Precisamos realizar uma pequena implementação para conseguir executar este mesmo comando de forma assíncrona. O método que representa a lógica a ser executada, pode ser executado de forma síncrona ou assíncrona, sem a necessidade de qualquer alteração no mesmo.

Abaixo temos o código que representa o comando que define que a execução de alguma tarefa seja realizada de forma assíncrona. Note que continuamos utilizando o Reactive Extensions, e no método ToAsync definimos o método que é informado no construtor desta mesma classe.

public class AsyncRelayCommand : RelayCommand
{
    public AsyncRelayCommand(Action execute)
        : base(execute) { }

    public AsyncRelayCommand(Action execute, Func<bool> canExecute)
        : base(execute, canExecute) { }

    public override void Execute(object parameter)
    {
        Observable
            .ToAsync(base.execute)()
            .Subscribe();
    }
}

Depois de criado esta classe, podemos fazer o uso da mesma diretamente em nossa ViewModel. Aqui optei por variar o método Somar, pois ao invés de receber os parâmetros e devolver o resultado, estou optando por acessar diretamente as propriedades no interior do método. E aqui cabe comentar um detalhe interessante: note que não usamos o método ObserveOnDispatcher na classe AsyncRelayCommand. Isso se deve ao fato de que o padrão MVVM faz com que a ViewModel seja completamente independente da View, e com isso, não conseguimos acessar seus respectivos controles e, consequentemente, não corremos risco nos depararmos novamente com aquela exceção que vimos acima.

public class CalculoViewModel : INotifyPropertyChanged
{
    public CalculoViewModel()
    {
        this.Calculo = new AsyncRelayCommand(Somar);
    }

    public ICommand Calculo { get; private set; }

    public string Valor1 { get; set;}

    public string Valor2 { get; set; }

    public string Resultado { get; set; }

    private void Somar()
    {
        Thread.Sleep(4000);

        this.Resultado =
            Convert.ToString(int.Parse(this.Valor1) + int.Parse(this.Valor2));
    }
}

Observação: Por questões de espaço eu preferi omitir a implementação necessária para notificar a alteração das propriedades (INotifyPropertyChanged). Isso continua sendo necessário, pois é assim que a View monitora toda e qualquer alteração que é realizada no interior da ViewModel para assim atualizar a UI.

Além das opções que vimos acima, ainda podemos necessitar que tenhamos um consumo periódico de alguma informação. Por exemplo, necessitamos monitorar serviço de cotação de valores, notícias de algum site (RSS), empregos, etc. Com isso, haverá uma tarefa sendo executando a cada X segundos, buscando as informações e, consequentemente, apresentando-as na tela para que o usuário possa visualizá-la.

Abaixo temos a ViewModel criada para atender este cenário. Temos uma propriedade chamada Noticias que retorna uma coleção do tipo ObservableCollection<Noticia>, qual será definida como fonte de dados de um controle ListBox da View (Xaml).

public class NoticiasViewModel
{
    public NoticiasViewModel()
    {
        this.Noticias = new ObservableCollection<Noticia>();
        this.MonitorarNoticias();
    }

    private void MonitorarNoticias()
    {
        Observable
            .Timer(TimeSpan.Zero, TimeSpan.FromSeconds(3))
            .Select(_ => BuscarNoticiasViaWeb())
            .ObserveOnDispatcher()
            .Subscribe(noticias => noticias.ForEach(n => this.Noticias.Add(n)));
    }

    private static List<Noticia> BuscarNoticiasViaWeb()
    {
        // Buscar notícias via Http
    }

    public ObservableCollection<Noticia> Noticias { get; set; }
}

Alguns novos operadores entram em cena aqui. O método Timer retorna uma sequência produzida (pelo método Select) a cada X segundos/minutos/horas. Note que voltamos a necessitar do método ObserveOnDispatcher, mesmo aqui, onde estamos utilizando MVVM. A questão é que quando definimos uma coleção como fonte de dados de algum controle, como é o caso do ListBox, ele envolve essa coleção em uma classe do tipo CollectionView, e esta herda diretamente da classe DispatcherObject, o que determina que ela tenha afinidade com a thread (Dispatcher) em que a mesma foi criada. Sendo assim, a não utilização do método ObserveOnDispatcher, vamos nos deparar com uma exceção do tipo NotSuppertedException, com a seguinte mensagem: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

Eis aqui algumas opções que temos para trabalharmos de forma assíncrona no WPF. Como disse antes, temos algumas mudanças que estão acontecendo nas linguagens que tendem a facilitar ainda mais a criação de código assíncrono, sem depender de qualquer recurso extra. De qualquer forma, essas opções já tornam o código bem mais expressivo e de fácil manutenção.