ASPNET CORE 2 — Usando Autofac para não expôr o domínio em um projeto web

Existe diversas maneiras de desenvolver um projeto utilizando DDD (Domain Driven Design) e há bastante tempo eu tenho o cuidado em não expôr o Domínio no projeto e pode utilizar a injeção de dependências, porém nem sempre é uma tarefa fácil diante das diversas formas de organizar a arquitetura de um projeto.

É importante salientar que existe inúmeras formas de implementar o DDD e cada arquiteto defende a sua forma conforme a necessidade, ou seja, não estou impondo nem dizendo que esta forma é a correta. É apenas mais uma forma.

Autofac

O Autofac é um serviço que facilita a injeção de dependências (DI).

Configuração

  • Crie um ASP.NET Core Web Application utilizando ASPNET CORE 2;
  • Adicione ao projeto web usando o NuGet as bibliotecas:

Autofac e Microsoft.Extensions.DependencyInjection

Program.cs

Adicione o Autofac ao Build.

public static IWebHost BuildWebHost(string[] args) =>  
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(s =>
s.AddAutofac())
.Build();

Startup.cs

Configura o Container do Autofac.

public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new Lib.Infra.Dependences.Injection.InjectionContainer());
}

Injetando as dependências

  • Criar a class library Lib.Infra.Dependences.Injection
  • Criar a classe InjectionContainer

Nesta classe você vai precisar adicionar a biblioteca Autofac via NuGet.

using Autofac;  
using Lib.Application.Core.Interfaces;
using Lib.Application.Core.Services;
using Lib.Domain.Core.Interfaces;
using Lib.Domain.Core.Services;

public class InjectionContainer : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ProductAppService>().As<IProductAppService>().InstancePerLifetimeScope();
builder.RegisterType<ProductService>().As<IProductService>().InstancePerLifetimeScope();
}
}

Perceba que neste exemplo já temos outras class libraries. Elas estão no projeto do GitHub http:// https://github.com/alextochetto/2017.01

A biblioteca `Lib.Infra.Dependences.Injection` que foi criada, será adicionada ao projeto web como referência.

Controller

A hora da verdade.

public class HomeController : Controller  
{
private readonly IProductAppService _productAppService;
public HomeController(IProductAppService pProductAppService)
{
_productAppService = pProductAppService;
}

public IActionResult Index()
{
_productAppService.Save();
return View();
}
}

Para testar, vocês podem utilizar a imaginação e criar um projeto de testes e seguir os conceitos do TDD (Test Driven Development) ou então fazer a chamada

Conclusão

Com isso, fica bem claro que não há necessidade de expôr o domínio no projeto web para realizar a injeção de dependências através do middleware do próprio CORE 2 (o que é possível). Assim, se você desejar terceirizar o desenvolvimento de uma interface, basta apenas passar a biblioteca application para que ele faça a implementação das interfaces sem conhecer as regras de negócio.