Neste post, compartilho mais algumas ideias que tenho adotado, com êxito, em meus projetos envolvendo Microsserviços e que podem ajudar você a ser mais efetivo em suas implementações.
Se você ainda não leu, recomendo que acesse um post anterior sobre esse tema, com mais recomendações, antes de avançar.
1. Comece pelos comandos e pelas consultas que vai suportar
Antes de definir qualquer aspecto mais técnico, ter clareza sobre quais comandos e consultas seu microsserviço deverá suportar irá ajudar você a ser mais efetivo e mais alinhado com as necessidades do negócio.

No exemplo, apenas ilustrativo, o microsserviço irá manter um “contador”.
Tenho optado (não faz muito tempo) por usar o Mediatr para intermediar a chamada dos handlers, orquestrar validação das mensagegens, etc.
using System.Threading;
using System.Threading.Tasks;
using CountingMicroservice.Application.Services;
using MediatR;
namespace CountingMicroservice.Application.CommandSide.Commands
{
public class IncrementCommandHandler
: IRequestHandler<IncrementCommand, bool>
{
private readonly ICounterRepository _repository;
public IncrementCommandHandler(ICounterRepository repository)
{
_repository = repository;
}
public Task Handle(
IncrementCommand request,
CancellationToken cancellationToken
)
{
if (request == null)
{
return Task.FromResult(false);
}
_repository.Increment();
return Task.FromResult(true);
}
}
}
2. Mantenha sua WebApi simples (se essa for sua interface)
Manter um projeto específico para a aplicação permite que o projeto da Web API seja extremamente simplificado. Caberá a WebAPI, apenas, fazer as devidas inicializações e prover features que “chamam” os comandos e consultas no momento apropriado.

Aliás, para aliviar acoplamento, tenho adotado por hábito fazer inicializações específicas da aplicação no código da aplicação (fora da web api)
using CountingMicroservice.Application.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ServiceStack.Redis;
namespace CountingMicroservice.Application
{
public static class StartupExtensions
{
public static IServiceCollection AddCounterApplication(
this IServiceCollection services,
IConfiguration configuration
)
{
var redisConnectionString = configuration["REDIS_CONNECTIONSTRING"] ?? "-counter.data";
services
.AddSingleton(sp =>
new RedisManagerPool(redisConnectionString)
)
.AddSingleton<ICounterRepository, RedisCounterRepository>();
return services;
}
public static IApplicationBuilder UseCounterApplication(
this IApplicationBuilder app
)
{
return app;
}
}
}
Fica dentro da WebAPI apenas inicializações que são específicas dela (Swagger, por exemplo)
using System;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using CountingMicroservice.Application;
using CountingMicroservice.Application.CommandSide.Commands;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
namespace CountingMicroservice.WebApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.RespectBrowserAcceptHeader = true;
});
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new Info()
{
Title = "Counting Microservice",
Version = "v1",
Description = "Basic Microservice Example"
});
});
services.AddCounterApplication(Configuration);
var container = new ContainerBuilder();
container.RegisterModule(
MediatrModule.Create(typeof(StartupExtensions).Assembly)
);
container.Populate(services);
return new AutofacServiceProvider(container.Build());
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvcWithDefaultRoute();
app
.UseSwagger()
.UseSwaggerUI(options =>
{
options.SwaggerEndpoint(
"/swagger/v1/swagger.json",
"Counting Microservice v1"
);
});
app.UseCounterApplication();
}
}
}
3. Use e abuse do Docker
Provavelmente seu microsserviço irá rodar em um container;. Aproveite-se do suporte do Visual Studio para Docker e já comece seu projeto rodando e depurando em containers.

O efeito positivo dessa escolha é que ficará muito mais fácil gerenciar dependências de softwares tecerceiros. Veja o docker-compose.yml da aplicação exemplo
version: '3'
services:
countingmicroservice.webapi:
image: countingmicroservice.webapi
build:
context: .
dockerfile: CountingMicroservice.WebApi/Dockerfile
depends_on:
- redis
redis:
image: redis
No exemplo, não preciso mais me preocupar em ter um servidor redis rodando em meu Windows. Ao começar a rodar minha aplicação, uma imagem do Redis irá ser baixada e um container iniciado.
4. Use variáveis de ambiente para configuração
É muito mais fácil configurar sua aplicação usando variáveis de ambiente do que utilizando arquivos de configuração. No Asp.net Core, é simples fazer isso.
namespace CountingMicroservice.WebApi
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddEnvironmentVariables();
})
.Build();
}
}
Além disso, variáveis de ambiente são perfeitas combinadas ao Docker. No exemplo, configuro endereço do Redis no arquivo de composição. Isso simplificará muito o deploy mais tarde.
version: '3'
services:
countingmicroservice.webapi:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- REDIS_CONNECTIONSTRING=redis
ports:
- "5000:80"
redis:
ports:
- "6379:6379"
Concluindo
Novamente, “são as cicatrizes que contam a história do guerreiro”.
- Sempre achei tedioso fazer o link entre meus Controllers e o código do domínio. Mediatr é uma “mão na roda” e a separação do microsserviço em projetos “adaptadores” e um “core” me ajuda a manter focado no negócio.
- A ideia de implementar comandos e consultas me faz manter o foco nas histórias de negócio ao invés de dados colecionados.
- Sempre achei péssimo instalar bancos de dados e outros artefatos em meu computador apenas para desenvolver – Docker é vida!
- Sempre odiei o web.config! Felizmente, não preciso mais dele. Adoro a ideia de poder usar simples variáveis de ambiente para configurar minha aplicação.
Novamente, há bem mais que poderia ser compartilhado. Entretanto, mais uma vez, é hora de pedir a sua opinião.

