Ainda que você não viva no mundo dos micro-serviços, uma hora você vai precisar chamar um serviço REST em outra ponta via HTTP/S, e no caso do AspNetCore, o jeito mais natural de fazê-lo é via a classe HttpClient.
Até aqui, tudo tranquilo, os métodos Get, Post, Put, Patch e Delete (talvez até outros) estão lá para serem usados. O problema é, caso sua implementação precise passar por testes unitários, a classe HttpClient pode lhe trazer problemas, já que não há interface disponível para mock e os métodos acima citados não são virtual.
Note que citei que ela “pode” lhe trazer problemas. Como fazer então para que a classe HttpClient não seja um para seus testes unitários?
Tudo se resume ao SendAsync
Se há algo que é mágico no AspNetCore é que ele é código aberto. Isso mesmo, você ir lá no github e ter acesso ao código fonte de praticamente 100% das classes que você usa no seu projeto. E, felizmente, esse é a caso do HttpClient. Vou deixar o link do fonte no fim do artigo.
Dando uma lida na classe, que é bem escrita por sinal, percebe-se que todos os métodos REST com exceção do Get, chamam um método chamado SendAsync, que recebe como parâmetro um objeto HttpRequestMessage e opcionalmente um CancellationToken.
O HttpRequestMessage precisa basicamente do corpo que você enviaria via Post, Put, Patch e Delete. O ponto de atenção é que somente a versão com o CancellationToken é virtual/override. Se você sabe o que o CancellationToken é, você deveria estar usando-o. Caso não, use CancellationToken.None por agora.
O código de exemplo abaixo faz um Post usando HttpClient:
public class MeuController : ControllerBase
{
private readonly HttpClient client;
public MeuController(HttpClient client)
{
this.client = client;
}
public async Task AlgumPost(Criterios criterios)
{
// estou ignorando quaisquer configurações de header
// também estou assumindo que a classe HttpClient é injetada via construto
var stringContent = new StringContent(JsonConvert.SerializeObject(criterios), Encoding.UTF8, "application/json");
var result = await this.client.PostAsync($"url", stringContent, CancellationToken.None);
return Ok(result);
}
}
O código é até simples. Agora, o teste unitário que permite você fazer o “mockar” a chamada PostAsync seria o seguinte:
public async Task DeveriaExecutarOSendAsyncAoMenosUmaVez()
{
// assumindo o uso do Moq e xUnit
var httpClient = new Mock();
httpClient
.Setup(x => x.SendAsync(It.IsAny(), CancellationToken.None))
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{}"),
}).Verifiable();
var controller = new MeuController(
httpClient.Object
);
var criterios = new Criterios() { };
var result = await controller.AlgumPost(criterios);
httpClient.Verify(x => x.SendAsync(It.IsAny(), CancellationToken.None), Times.Exactly(1));
}
O teste acima passa com sucesso! Note que não estamos fazendo Mock do PostAsync, mas do SendAsync já que o primeiro não pode ser “mockado”, mas ele chama o segundo. Caso queira checar que a chamada tenha sido correta, basta usar o CallBack oferecido pelo Moq.
Mas e o Get/GetString/GetStringAsync?
O que fazer então com os Gets? Simples! Não os use! Digo isso com certeza pois há uma alternativa muito mais limpa para ele. O próprio Send/SendAsync!
O problema dos Gets é que não há um meio apropriado de tratar erros. Se o request falhar, uma Exception pode ser disparada ou não.
O substituto ideal seria o seguinte:
// ao invés disso
public async Task ObterConteudo()
{
var resultado = await this.client.GetStringAsync("https://alguma.api.por.ai");
return Ok(resultado);
}
// faça isso
public async Task ObterConteudo()
{
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "https://alguma.api.por.ai");
var response = await this.client.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
var resultado = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
return Ok(resultado);
}
else
{
return StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync().Result);
}
}
Desta forma, o retorno dado ao cliente é muito mais “honesto” e de quebra, você ganha a oportunidade de testá-lo apropriadamente.
Bom proveito!
Fazia tempo que não tinha um bom motivo para “escrever um artigo”. Ultimamente gravar e publicar vídeo tutorias tem sido cada vez mais fácil (valeu Youtube) e o pessoal parece gostar do formato.
Com a toada em que a internet se encontra, decidi deixar o título simples. Nada de click bait. Nada de “O VBA vai acabar” ou “VBA, a hora da verdade”. Isso me irrita tanto que não tenho coragem de fazê-lo com vocês, pelo menos até hoje.
Indo ao assunto, estamos falando de VBA, ou melhor, desenvolvimento para a plataforma Office, depois de trabalhar quase 17 anos com essa notável ferramenta, a qual me levou a ser o profissional que sou hoje. Não sou o cara mais bem sucedido do mundo, mas estando bem empregado no mesmo ramo e gostando muito do que faço diariamente, considero isso um ponto muito positivo.
Vamos ao que interessa, mas antes, as opiniões colocadas aqui são 100% minhas e têm como fontes além da vivência, longas conversas com colegas que manjam do assunto, incluindo MVPs em Office. E sim, isso foi uma carteirada. 🙂
Público Alvo
O público que pretendo atingir é o de programadores/usuários VBA e também a comunidade engajada no seu (bom) uso. Se por um acaso você é um programador não VBA mas se interessa pelo assunto, bem, meus parabéns e seja bem vindo!
Desenvolvimento para Office: Como estamos atualmente?
Tendo em mente que estou escrevendo este artigo no primeiro semestre de 2017, o que vou escrever aqui pode mudar muito nos próximos meses, quem dirá nos próxmos anos. O momento atual pode ser definido da seguinte forma:
O VBA ainda existe, vem como padrão na instalação do Office 2016, mas não é atualizado seriamente desde 1999. Houveram algumas funções adicionadas no Office 2003, mas nada sério.
A investida atual da Microsoft para desenvolvimento Office é o Office Add Ins, permitindo criar “Apps” que são embutidos no Office via barra de tarefas (aquela que aparece à direita), mas criadas em Javascript e distribuídas via Office Store.
O VBA está de fato cada vez mais bugado e isso só piora a cada versão.
Adicionalmente, alguns fatos precisam ser colocados para servir de base para a argumentação que farei neste texto.
O desenvolvimento para VBA está longe de acabar. Comunidades sobre o assunto só crescem e o interesse permanece estável. Abaixo podemos ver o gráfico do Google Trends que mostra o interesse na linguagem comparada ao que são suas alternativas:
A comparação chega a ser ridícula. Ainda que seja possível argumentar que o desenvolvimento vem caindo, é muito pouco para uma linguagem que não têm investimento algum a quase duas décadas, enquanto outras lutam para ser manter no páreo. O que não entendo é como isso pode ser ruim.
O stackoverflow.com, que é no momento “O FÓRUM” para qualquer linguagem de programação, tecnologia ou framework em uso trás os seguintes números aproximados:
VBA: ~80 mil menções
VSTO: ~12 mil menções
Office JS: ~1,5 mil menções
Procurar por Office Add In não conta pois ele engloba toda e qualquer tecnologia na qual se pode construir um, desde o VBA até mesmo C++.
Convenhamos, a Microsoft é muito conhecida tanto por seus grandes acertos (Office, .NET, SQL Server, Azure) como por seus inesquecíveis fracassos (Windows Milenium, Vista, Infopath, Zune, Windows Phone).
Por fim, temos o VBA firme e forte, o VSTO sabe lá onde está, o Office Add In em Javascript está engatinhando, mas não estou muito otimista sobre. Já comento mais.
Qual é o real estado do VBA?
O estado do VBA em si, desde o mercado até a ferramenta é caótico. O grande problema é que ser caótico não é necessariamente ruim.
O caos se dá pela falta de direção que um programador VBA deve tomar. No meu caso, eu comecei criando macros simples sem entender muito o que estava acontecendo, para depois sim entrar num curso de lógica de programação, que foi quando as coisas começaram a fazer mais sentido. Depois de trabalhar 3 anos descobrindo o VBA, ingressei na faculdade de Ciências da Computação e aí tudo ficou mais polido, já que tive uma visão mais abrangente de como linguagens de programação e ferramentas como ele funcionam.
Entretanto, para a maioria o caminho não é bem esse. Muitos vem de outras áreas que nada tem em relação com programação em si. Eles encontram seu próprio caminho usando o VBA porque ele permite isso. No fim, temos soluções das mais variadas criadas pelo mais variados tipos de profissionais e que entendem do negócio (quem mais faria um código para o mercado financeiro do que uma analista de finanças?) resolvendo uma série de pequenos problemas e até mesmo movendo negócios.
Onde está o problema nisso? Manutenção.
É relativamente simples criar um código, mas mantê-lo, nem tanto. O criador da proeza faz tudo que pode para fazer funcionar sem o compromisso de manter um nível decente de manutenibilidade. E se você é um deles, eu não te culpo. Você não teve a contextualização suficiente para entender a importância disso pois você não é um programador e naturalmente não deveria se preocupar em ser. Você assumiu o papel de um. Você gosta de ser um quando está criando um código, mas não quer ser quando precisa resolver um bug nele.
O resultado? Milhares (quiçá milhões) de aplicativos VBA criados precisando desesperadamente de manutenção e não há quem queira fazê-lo. Quem criou não tem disposição ou noção para tal e programadores em outras linguagens (sim, porque este programador olha para o VBA como um patinho feio, algo de segunda linha) não querem chegar perto desse tipo de código.
A facilidade de criação permitida pelo VBA é o que o faz tão forte e utilizado, mas a mesma facilidade permite que o código vire uma bagunça logo e desenhe o cenário que temos hoje. É preciso encontrar um meio termo. Uma mudança drástica como as que vem sendo propostas não tem sido a melhor escolha e matar o ecossistema pode além de causar revolta nos usuários, sacrificar um número expressivo de negócios e fazer o mercado criar alternativas.
Alô Microsoft?!?
O que aconteceu com o VSTO?
O VSTO (Visual Studio for Office) foi a primeira tentativa oficial da Microsoft de dar ao Office um desenvolvimento “sério”, antes feito através do VBA ou das bibliotecas padrão do Office manipuladas via VB6, Delphi ou C++.
Antes mesmo do VSTO, tivemos um movimento chamado Smart Documents. Era, na minha opinião, algo incrível! Você mapeava áreas de documentos Word, planilhas Excel e/ou slides no PowerPoint e adicionava inteligência a isso, como uma tradução simultânea, acesso a contratos que estivesse no contexto. Notável! Podia ser feito tanto no VB6, o que era bom para programadores VBA, como em C# ou VB.NET. Envolvia muito XML (lembra daqueles mapas de documento?) e era chato de fazer, mas o resultado era bom.
O VSTO veio incrementar isso, sendo completamente integrado ao Visual Studio, permitindo abrir o Excel e o Word dentro da ferramenta para ver o resultado quase pronto, podendo arrastar controles, datasets, conexões com o banco de dados e o que mais a ferramenta entregava. Um marco! Era bom, mas assim como a alternativa acima citada, errava num ponto crucial:
A distribuição.
Publicar um aplicativo VSTO era (e ainda é) uma epopéia, envolvendo arquivos de manifesto (mais xml), privilégios de execução, etc, etc, etc. Fazer o usuário executar uma planilha feita nessa tecnologia era tão desencorajador que o desenvolvedor parava no meio do caminho e voltava para o VBA, mesmo sabendo que isso lhe custaria abrir mão de todos os recursos do Visual Studio e das linguagens que se pode utilizar nele. E sim, o problema continua até hoje.
O VSTO evolui bem em quanto ferramenta, bibliotecas e até implementou tipos dinâmicos para fazer ser mais fácil codificar em C#, mas nada mudou na forma de entregar o produto compilado ou para facilitar a vida de quem veio do VBA.
Office mais… Javascript?
Confesso que quando li isso pela primeira vez, quase pulei da cadeira. Trazer a linguagem mais utilizada na internet para o Office seria o pulo do gato para o desenvolvimento VBA!
Mas… sim, tem o “mas”. O que a Microsoft fez foi nada mais do que manter o VSTO só que ao invés de codificar C#/VB.NET, você faz isso em Javascript. O problema da distribuição permanece.
Aliás, é pior! Você só pode construir Add-Ins e publicá-los via Office Store, ou Office App Store, ou sei lá eu o que isso seja. Nunca tinha ouvido falar disso antes de ler sobre o assunto. Se eu como criador de aplicativos Office não sabia, que dirá o usuário.
A ideia ainda me empolga, mas se o modelo de distribuição não for modificado, eu vejo para o Office JS o mesmo fim do VSTO.
O que está errado?
Há um misto de enganos. Novamente, esta é minha opinião.
A Microsoft parece estar simplesmente ignorando as forças do VBA, que penso serem principalmente as seguintes:
Facilitade de desenvolvimento (Visual Basic é fácil de aprender)
Facilidade de distribuição (Salvar arquivo, Ativar macros, pronto)
Ubiquidade (o VBA já está lá, queira você ou não)
Nada disso está presente nas novas soluções propostas. O VBA não é para programadores. Ele forma programadores (presente!). Comentei isso com colegas de trabalho recentemente. Ninguém que não usa Office gosta de trabalhar com ele. O Office é bom para quem o usa diariamente, os usuários. Para todo o resto, especialmente programadores, ele não agradável de se lidar.
E é o VBA que torna a manipulação de objetos do Office algo torelável. E sim, o Office não seria o que é se não fosse o VBA e já teria sido facilmente substituído por alternativas como o Google Sheets ou as finadas que vieram uma década atrás.
A decisão óbvia que não foi tomada
Pelo menos era a decisão óbvia para mim. Como programador VBA e .NET, tinha a visão clara de que uma hora seria lançado o Visua Basic .NET for Applications.
Seria perfeito! Toda aquela estrutura do VB6 seria substituída por um subset do Visual Studio e teríamos acesso a todas as vantagens da então nova plataforma .NET. Mas não foi assim.
A Microsoft focou nos desenvolvedores, tentando atraí-los para programar para o Office. Deu certo com o .NET, por isso não os culpo por adotar tal estratégia.
Mas depois de algum tempo, ficou claro a falta de adoção por quem deveria tê-lo feito, os programadores VBA. A pergunta que fica é, porque ainda insistem tanto neste caminho?
O que está por vir
Sinceramente, não faço ideia. O que dá para prever é que se a direção não mudar, nós veremos o VBA cair na velhice e deixando de ser usado por pura inviabilidade técnica, o que já está acontecendo atualmente.
E, se você é um desenvolvedor VBA, qual é a probabilidade de adotar o VSTO ou Office JS como sua alternativa quando não houver mais escolha? O que fazer? Abandonar de vez?
Alternativas
O mercado não ficou parado. Os programadores VBA não deixaram de sê-lo e aqueles que precisam manipular documentos do Office continuam fazendo-o, mas nada de VSTO.
O acesso é feito direto via Office Primary Interop Assemblies. Isso deu um ar fresco para programadores que precisam criar soluções baseadas no Office via código, apesar de todos os problemas de compatibilidade, que vem sendo resolvidos com o tempo.
Entretanto, programadores VBA mal chegam perto desse tipo de solução.
Outra alternativa que apareceu recentemente foi o Excel DNA. Ele é uma biblioteca que permite criar AddIns para Excel usando C#/VB.NET. Você codifica no Visual Studio com todo seu potencial e no final gera o assembly .net junto com o arquivo xll (addin). É uma maneira muito elegante de resolver o problema da distribuição e prova para a Microsoft que há outros caminhos. Não tenho visto ele ser atualizado recentemente, o que é uma pena. 🙁
O que mais? O Google Sheets está vindo aí e já é possível codificar “macros” nele, e em Javascript! Até escrevi sobre isso aqui.
Não vi muito do que o Open Office está fazendo. Quem quiser comentar sobre, fique à vontade.
O que está sendo feito sobre isso?
Da Microsoft, a única certeza que tenho é que eles querem se livrar deste contexto, seja criando alternativas, seja matando o VBA, o que parece ser o caso.
Da comunidade, há um esforço enorme em espalhar o bom uso da ferramenta através de artigos e tutoriais dos mais variados tipos e autores. O material é rico e extenso. Há representantes de peso e engajados na causa do bom uso do VBA. Isso eu posso garantir que está sendo feito, e bem feito!
E o que eu vou fazer a respeito?
Até o momento, pretendo continuar compartilhando conhecimento em VBA. Ele está aí, presente, forte, ao alcance de um atalho para que qualquer profissional possa começar sem burocracia a criar seus primeiros códigos e trilhar uma carreira no mercado de programação, que foi exatamente o meu caso.
Eu tenho um sonho grande de poder criar algum tipo de alternativa ao VBA, mas no momento é um projeto muito grande para encaixar na vida. Quem quiser uma pista, esse projeto envolveria Roslyn e muito C#. É muito louco, mas quem sabe?
Outra ideia seria criar transpiladores, ou seja, ferramentas mais modernas em linguagens mais novas que produziriam código VBA. Não deixa de ser uma solução (acontece hoje com o Javascript), mas o VBA ainda estaria por lá e em pouco tempo, evoluções no mesmo seriam necessárias (como também acontece com o Javascript), o que já é um fato hoje.
Acredito ser o melhor a fazer já que não podemos mudar o produto por conta própria.
Agradecimentos
Meu agradecimento especial os integrantes do grupo Especialistas Excel e PBI, do qual tenho a honra de fazer parte e que tanto me esclarece em doses diárias de conhecimento e bom humor. 😀
Nunca precisei muito fazer questão de instanciar uma coleção usando LINQ e Entity Framework. Normalmente até criava as instâncias sem especificar o tipo, usando var mesmo.
Bem, isso se resolvia quando você não precisa fazer muita coisa com a variável de retorno, ou quando fazia a atribuição direta, vindo da query LINQ. Mas, e quando não dá para fazer a atribuição? Você pergunta, pra quê instanciar? Eu respondo: tem horas que é necessário, por exemplo, quando hoje precisei criar uma coleção em memória sem conectá-la diretamente ao contexto, que seria serializada mais tarde (em JSON). E como a resposta seria para uma aplicacação front-end, null não é a melhor opção.