Home > Software engineering >  Best way validate object in c# with "Manager" class
Best way validate object in c# with "Manager" class

Time:07-01

In my project I have an class named Precatorio

public class Precatorio : Pesquisa.Pesquisa
{ 
    public int FornecedorId { get; set; }
    public Fornecedor Fornecedor { get; set; }
    public int FundoId { get; set; }
    public Fundo Fundo { get; set; }
    public int DestinacaoRecursoId { get; set; }
    public DestinacaoRecurso DestinacaoRecurso { get; set; }
    public DateTime Data { get; set; }
    public int Natureza { get; set; }
    public long Tipo { get; set; }
    public decimal Valor { get; set; }
    public string Descricao { get; set; }
    private Precatorio()
    { 
    }

    internal Precatorio(
        int fornecedorId,
        Fornecedor fornecedor,
        int fundoId,
        Fundo fundo,
        int destinacaoRecursoId,
        DestinacaoRecurso destinacaoRecurso,
        DateTime data,
        int natureza,
        long tipo,
        decimal valor,
        string descricao
    )
    {   
        FornecedorId = fornecedorId;
        Fornecedor = fornecedor;
        FundoId = fundoId;
        Fundo = fundo;
        DestinacaoRecursoId = destinacaoRecursoId;
        DestinacaoRecurso = destinacaoRecurso;
        Data = data;
        Natureza = natureza;
        Tipo = tipo;
        Valor = valor;
        Descricao = descricao;
    }
}

And a PrecatorioManager class which validates the fields in order to return an object

public class PrecatorioManager : DomainService
{

    private readonly IPrecatorioRepository _precatorioRepository;

    public PrecatorioManager(IPrecatorioRepository precatorioRepository)
    {
        _precatorioRepository = precatorioRepository;
    }

    public async Task<Precatorio> CreateAsync(
        int fornecedorId,
        Fornecedor fornecedor,
        int fundoId,
        Fundo fundo,
        int destinacaoRecursoId,
        DestinacaoRecurso destinacaoRecurso,
        DateTime data,
        int natureza,
        long tipo,
        decimal valor,
        string descricao

    )
    {
        return new Precatorio(
            fornecedorId,
            fornecedor,
            fundoId,
            fundo,
            destinacaoRecursoId,
            destinacaoRecurso,
            data,
            natureza,
            tipo,
            valor,
            descricao
        );
    }

}

The problem is that PrecatorioManager.CreateAsync require to many fields, and it will be too much difficult to change some field and refactor in all the code that use this method. Second problem is that sometimes a developer may not use the PrecatorioManager.CreateAsync and pass throw de validation.Validations needs to pass in PrecatorioManager because some validations require repository injection and will be needed in all cases. Developers commonly use just:

var NewPrecatorio = ObjectMapper.Map<CreateUpdatePrecatorioDto,Precatorio>(input);

So, I'm looking for a way that internal Precatorio calls PrecatorioManager.CreateAsync or a best solution.

CodePudding user response:

Change the object's constructor to private and use a public static method to generate objects. Now, short of arcane magic, the consuming developer cannot construct a Precatorio without going through validation. As (another) Victor mentions in his comment, if you need ten parameters, you need ten parameters.

public class Precatorio : Pesquisa.Pesquisa
{ 
    public int FornecedorId { get; set; }
    public Fornecedor Fornecedor { get; set; }
    public int FundoId { get; set; }
    public Fundo Fundo { get; set; }
    public int DestinacaoRecursoId { get; set; }
    public DestinacaoRecurso DestinacaoRecurso { get; set; }
    public DateTime Data { get; set; }
    public int Natureza { get; set; }
    public long Tipo { get; set; }
    public decimal Valor { get; set; }
    public string Descricao { get; set; }

private Precatorio(PrecatorioManager precatorioManager)
{ 
}

private Precatorio(
    int fornecedorId,
    Fornecedor fornecedor,
    int fundoId,
    Fundo fundo,
    int destinacaoRecursoId,
    DestinacaoRecurso destinacaoRecurso,
    DateTime data,
    int natureza,
    long tipo,
    decimal valor,
    string descricao)    
{   
    FornecedorId = fornecedorId;
    Fornecedor = fornecedor;
    FundoId = fundoId;
    Fundo = fundo;
    DestinacaoRecursoId = destinacaoRecursoId;
    DestinacaoRecurso = destinacaoRecurso;
    Data = data;
    Natureza = natureza;
    Tipo = tipo;
    Valor = valor;
    Descricao = descricao;
}

public static async Task<Precatorio> CreateAsync(
    int fornecedorId,
    Fornecedor fornecedor,
    int fundoId,
    Fundo fundo,
    int destinacaoRecursoId,
    DestinacaoRecurso destinacaoRecurso,
    DateTime data,
    int natureza,
    long tipo,
    decimal valor,
    string descricao)
  {
    return new Precatorio(
        fornecedorId,
        fornecedor,
        fundoId,
        fundo,
        destinacaoRecursoId,
        destinacaoRecurso,
        data,
        natureza,
        tipo,
        valor,
        descricao
    );
  }
}

CodePudding user response:

As I understand it, the PrecatorioManager class is responsible for validating new Precatorio objects and you have three design objectives:

  1. The only way to create a Precatorio object is to call PrecatorioManager.CreateAsync() to obtain one.

  2. The developer must not be allowed to bypass the validation of Precatorio.

  3. The pass-through initializer must be robust and expandable for the future when additional properties may be added to the Precatorio class.

Similar to the other answer so far, this Precatorio has a private constructor that prevents direct instantiation. The static Create method has internal visibility to give access to PrecatorioManager, but checks the console output

  • Related