Existem diversas maneiras de desenvolver um projeto utilizando DDD (Domain Driven Design), e há bastante tempo eu tenho o cuidado em não expor o domínio no projeto e poder 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 existem 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 expor 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.