Should the Domain layer depend on Infrastructure?

4

I'm reading the Evans book on DDD and I came across the following quote:

  

The Infra layer does not perform any action on the domain layer, because it is below it, because it is below it should not have specific knowledge about the domain it is serving.

     

Application and Domain Layers call services provided by the Infrastructure layer.

Remembering that I am a beginner with DDD, and from what I had previously read the domain layer should not know any other layer, someone could kindly show some implementation closer than Evans wanted to say at this point or correct me if I misinterpreted .

    
asked by anonymous 08.07.2015 / 02:43

2 answers

5
  

Does the Domain layer depend on Infrastructure?

Yes, the Domain layer depends on the Infrastructure layer to perform data persistence in the database.

However, what the DDD advises is that Domain classes are not implemented with direct references to the Infrastructure layer.

That is, in your project responsible for the Domain (related to the business rules) do not put database references, NHibernate, .Net, threads, HTML5, javascript, etc.

Instead use External services that can be reused at various points in the system, for example:

  • In the Domain, create an interface called IClientServiceRepository containing signature methods to Save, Delete, Update and Retrieve data in the database
  • In the Infrastructure project / layer, implement IClientServiceRepository in a ClientServiceRepository class, making the Infrastructure have the implementation of Save, Delete, Update, and Retrieve in the database Client objects using the repositories
  • With the class ClientServiceRepository in your Infrastructure layer implementing the IClientServiceRepository interface defined in the Domain, now let's imagine a scenario where your Domain will depend on Infrastructure Services ...

    Assuming that I need to restrict debtor client exclusion, I can include this rule in the Domain and request methods from the Infrastructure layer, for example:

  • Create a class in the domain called CustomerService for specific customer-related services
  • Use Dependency Injection / Inversion Control to maintain minimal coupling between the Dominino and Infra Framework layers
  • public class ClienteServico
    {
        private readonly IClienteServicoRepositorio _clienteServicoRepositorio;
    
        public ClienteServico(IClienteServicoRepositorio clienteServicoRepositorio)
        {
           _clienteServicoRepositorio = clienteServicoRepositorio;
        }
    
        public ActionResult ExcluirCliente(Cliente cliente)
        {
           if(_clienteServicoRepositorio.ClienteDevedor(Cliente.Id))
           {
               RetornarMensagemExclusaoClienteDevedor();
           }
           //else ...
        }
    }
    

    Next, we have an example where the Domain layer calls services provided by the Infrastructure layer with minimal coupling between the layers.

        
    08.07.2015 / 15:58
    0

    The domain layer should not be 'married' to any other layer, but it needs to call CRUD functions in the persistence layer.

    The idea of the domain layer not knowing the persistence layer (or any other layer) is to avoid 'marrying' it with a specific implementation of the persistence layer. Understand: make calls, yes, but through interfaces.

    The above quote from another concept. The layer below can not make calls at the domain layer. Not by interface, nor by. Who makes the calls, who orchestrates everything is the domain layer.

    So the two ideas that you expose are correct, but deal with different things (although they follow the same philosophy of separation of concepts).

    Examples: Let's say you have class UsersBL for business rules and class UsersRepository for persistence.

    The UsersBL class will need to call the UsersRepository class for creating, searching, changing the data.

    The first concept you mentioned says that the UsersRepository class can not contain calls to the UsersBL class. For example, it might seem useful to use a validation function that is already implemented and tested in the UsersBL class, but that is wrong .

    The second concept says that the UsersBL class should make calls in the UsersRepository class, of course, but should not do this through instances of the UsersRepository class. The class in the domain should use interfaces.

        
    08.07.2015 / 14:42