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:
NET - Unit of Work - Padrão Unidade de ...
NET - O padrão de projeto Decorator
NET - Padrão de Projeto Builder
C# - O Padrão Strategy (revisitado)
NET - O padrão de projeto Command
NET - Apresentando o padrão Repository