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.

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 _productAppService.Save();

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.