C# -  Fluent Interface


 Neste artigo vamos discutir o padrão Fluent Interface na linguagem C#.

O principal objetivo do padrão Fluent Interface é que podemos aplicar várias propriedades (ou métodos) a um objeto, conectando-os com pontos (.) sem ter que especificar novamente o nome do objeto a cada vez.

Um exemplo de uso deste recurso pode ser visto quando usamos o EF Core Fluent API para configurar propriedades das entidades:

modelBuilder.Entity()
                     .Property(e => e.EmployeeID)
                     .HasColumnName("EmployeeID")
                     .HasDefaultValue(0)
                     .IsRequired();



Como implementar a Fluent Interface ?

Vamos supor que temos a seguinte classe Email :

public class Email
{
    public string Destino { get; set; }
    public string Origem { get; set; }
    public string Assunto { get; set; }
    public string Body { get; set; }

    public override string ToString()
    {
         return ($"{Destino} - {Origem}\n {Assunto}\n {Body}\n");
     }
}

Se quisermos consumir a classe Email acima, geralmente criamos uma instância de Email e definimos as respectivas propriedades conforme mostrado abaixo:

static void Main(string[] args)
{
    var email = new Email();
    email.Origem = "macoratti@yahoo.com";
    email.Destino = "microsoft@hotmail.com";
    email.Assunto = "Testando a classe Email";
    email.Body = "Teste de utilização da classe Email";
   Console.ReadLine();
}

Mas e se quisermos usar a Fluent Interface para esta classe e assim poder definir o código abaixo ?

static void Main(string[] args)
{
     var email = new Email();
                      .Origem = "macoratti@yahoo.com";
                      .Destino = "microsoft@hotmail.com";
                      .Assunto = "Testando a classe Email";
                      .Body = "Teste de utilização da classe Email";
    Console.ReadLine();
}

Olhando o código notamos que ele fica mais legível e podemos implementar este recursos usando o encadeamento de métodos.

O que é o encadeamento de métodos

O encadeamento de métodos é uma técnica comum em que cada método retorna um objeto e todos esses métodos podem ser encadeados para formar uma única instrução.

Para conseguir isso, primeiro precisamos criar uma classe wrapper ou invólucro em torno da classe Email, conforme mostrado abaixo:

 public class EmailFluent
 {
        private readonly Email email;
        public EmailFluent()
        {
            email = new Email();
        }
        public EmailFluent OrigemEmail(string origem)
        {
            email.Origem = origem;
            return this;
        }
        public EmailFluent DestinoEmail(string destino)
        {
            email.Destino = destino;
            return this;
        }
        public EmailFluent AssuntoEmail(string assunto)
        {
            email.Assunto = assunto;
            return this;
        }
        public EmailFluent BodyEmail(string body)
        {
            email.Body = body;
            return this;
        }
        public Email Build()
        {
            return email;
        }
    }

Nesta classe criamos métodos para cada propriedade. Além disso, observe que o retorno do método é definido para o EmailFluent.  E em cada método estamos usando return this; que significa a estamos retornando a mesma instância.

Agora, a interface fluente acima será consumida pelo cliente. Portanto, com a classe EmailFluent acima, agora o código do cliente deve se parecer com o mostrado abaixo.

static void Main(string[] args)
{
     var email = new EmailFluent();
     email.OrigemEmail("macoratti@yahoo.com")
             .DestinoEmail("microsoft@hotmail.com")
             .AssuntoEmail("Testando a classe Email")
             .BodyEmail("Teste de utilização da classe Email")
             .Build();
     Console.ReadLine();
}

E assim temos a utilização da Fluent Interface.

Geralmente usamos este recurso quando você deseja fornecer uma API fluida e de fácil leitura. Essas interfaces tendem a imitar linguagens específicas de domínio, de modo que quase podem ser lidas como linguagens humanas.

Pegue o código do projeto aqui : FluentInterface1.zip

"Os meus olhos anteciparam as vigílias da noite, para meditar na tua palavra."
Salmos 119:148

Referências:


José Carlos Macoratti