How to implement business rules or system rules using Domain Driven Design in C #?

7

I'm having second thoughts about how to separate business rules from system rules with DDD.

If I have for example a class Usuario with id , nome , login , senha as properties. A domain rule would require a password for the user, which would be a specification within the domain layer.

Now, a rule that would be: for the user to enter the password, he must enter twice to confirm the password entered:

Would this be a rule within my domain layer? Or would it be in another layer?

    
asked by anonymous 26.08.2015 / 23:49

3 answers

2

The rule itself would be in the Usuario class. But you would not need to validate the password of Usuario twice in the domain class, because when it says:

  

Now, a rule that would be: for the user to register the password, he should   enter twice to confirm the entered password

This is more for a validation on the front-end, without having to do it in the backend (in the Usuario class) as well.

Continuing the answer, in your case, you first need to check where to put your Usuario class inside the system.

In the DDD context, it could stay in a Domain project (domain classes), in the User context (UserCtx) and within a UserAggregation:

>
Projeto.Domain/UsuarioCtx/UsuarioAgg/Usuario.cs

The rule could be in a method within this class. But, however, until you get to your domain class, it is expected to pass through some Controller class. But, you must also properly separate your project to house this controller class. One possibility is that it is in another Interface project. If you are using REST, a suggestion would be:

Projeto.Interface/Services/Rest/UsuarioCtx/UsuarioController.cs

There, finally, you could have a service to register the password. As I said earlier, you can call this service after you validate, on the front end, if the user entered 2 equal passwords. Validate this, call a correct REST service (a PUT , as it is an update), as a cadastrarNovaSenha (name of the method in the class, not the service!) In its UsuarioController .

In% with%, make other pertinent validations that may preferably be in the User's domain class (example: verify that the password is the same as the new password, comparing the hash ). Always taking care of course not to pass Repository classes into your domain class to perform searches ...

If you want to validate the backend of the form's equal passwords, you can use a simple method like this in UsuarioController , calling Usuario.cs :

public bool VerifySenhasIguais(String senhaNova)
{
     //TODO comparação com a senha atual
}

Once the necessary validations are done, update the user with the new password and save again. This step has more details, but I think your question does not encompass this.

Remembering that I'm not getting into the merits of the discussion that you need all this to get what you want, but I'm giving you an example of how it could be.

    
27.08.2015 / 01:43
3

This example is a bit tricky to put in your domain class because you would have to have two password-related properties in your class, which would be strange. In this specific case you could put this rule somewhere else.

A clearer example would be something like checking if the customer has already paid all the previous purchases to complete a new purchase, it would look something like below:

public class Cliente
{
    public ICollection<Compra> Compras { get; set;}
}

public class Compra
{
    public int Id { get; set; }
    public ICollection<Produto> Produtos { get; set;}
    public Cliente Cliente { get; set; }
    public bool Pago { get; get; }

    public void Fechar()
    {
        if (Cliente.Compras.Any(c => c.Id != this.Id && c.Pago == false))
            throw InvalidOperationException("Não é possível concluir a compra pois conta pagamentos em aberto");

        //TODO: código de fechamento de vendas
    }
}
    
27.08.2015 / 01:15
2

This is not a domain rule so it should not reside on the domain layer.

Login and login details are application rules and not business.

Security, in general, are non-functional requirements (unless it is just security software, such as an Active Directory integration tool).

  

In DDD, domain rules are defined by business experts. Can you see a business expert talking about Accounts Payable, for example, and at the same time asking to have to fill two password fields instead of one?

In fact the business expert will not even ask for a login screen. He would not even have to log in if he were allowed to.

  

Login and details of how to log into the system are definitely not business rules, so in DDD this does not belong to the domain layer.

You should write these rules at the application layer.

Possibly authorization * can be a domain rule if separation of duties is essential to the business (sometimes regulatory requirements may even be included).

Authorization * is the definition of how a user can interact with the system in the sense of what it can see and what it can modify.

In these cases, if the project provides core domains and generic subdomains , the authorization belongs to a generic subdomain .

    
06.10.2015 / 21:06