Neste artigo vamos recordar como usar a injeção de dependência usando a linguagem VB .NET. |
Na definição forma a Wikipedia diz: "Na engenharia de software, a injeção de dependência é uma técnica pela qual um objeto fornece as dependências de outro objeto. Uma dependência é um objeto que pode ser usado (um serviço). Uma injeção é a passagem de uma dependência para um objeto dependente (um cliente) que o usaria. O serviço é feito parte do estado do cliente. Passar o serviço para o cliente, em vez de permitir que um cliente construa ou encontre o serviço, é o requisito fundamental do padrão".
Antes de continuar leia a definição e veja se entendeu. Eu creio que não fica muito claro, não é mesmo ???
Então vamos por partes...
O que é uma dependência ?
Uma dependência é um objeto que a sua classe precisa para funcionar. Para usar esse objeto geralmente você cria uma instância da classe do objeto.
Public Class DAL
Private _sql As AcessoSQL
Public Sub New()
_sql = New AcessoSQL()
End Sub
End Class
|
O
construtor padrão da classe DAL cria um
objeto da classe AcessoSQL.
Isso significa que a classe DAL é responsável pela criação de um objeto da classe AcessoSQL. Portanto, existe um forte acoplamento entre a classe DAL e classe AcessoSQL. A classe DAL possui uma dependência da classe AcessoSQL.
|
A Injeção de Dependência é um tipo de Inversão de Controle e significa que uma classe não mais é responsável por criar ou buscar os objetos dos quais depende.
Isso serve para desacoplar as classes, evitando dependência direta entre elas.
Os resultados são:
Para realizar a injeção de dependência usamos interfaces e/ou um framework que vai injetar as dependências que precisamos usar.
No nosso exemplo para implementar a injeção de dependência usamos uma interface que foi injetada no construtor da classe DAL para obter uma instância do objeto AcessoSQL :
Public Class DAL
Private IAcessoSQL As _sql
Public Sub New(IAcessoSQL as sql)
_sql = sql
End Sub
End Class
|
Para ficar mais claro o conceito vamos a um exemplo prático.
Usando a
injeção de dependência : o problema
Vou usar um exemplo prático bem simples que adaptei de
uma resposta de um tópico no Stackoverflow.
Vou usar um projeto do tipo Console Application usando a linguagem VB .NET.
Este exemplo não utiliza nenhum framework de injeção de dependência para tornar o exemplo mais claro.
Vamos supor que você tem um sistema que processa pagamentos com Boleto, Cartão e Dinheiro e possui uma classe Pagamento que implementa o método efetuarPagamento da seguinte forma:
Public Class Pagamento
Private Sub efetuarPagamento(ByVal tipo As String, ByVal codigo As Integer, ByVal valor As Double)
If "BOLETO".Equals(tipo) Then
Dim integracaoBoletoBanco As New IntegracaoBoletoBanco()
integracaoBoletoBanco.pagarBoleto(codigo, valor)
ElseIf "CARTAO".Equals(tipo) Then
Dim integracaoCartaoBanco As New IntegracaoCartaoBanco()
integracaoCartaoBanco.pagarCartao(codigo, valor)
ElseIf "DINHEIRO".Equals(tipo) Then
Dim integracaoContaBanco As New IntegracaoContaBanco()
integracaoContaBanco.pagarDinheiro(codigo, valor)
End If
End Sub
End Class
|
No código usado no método efetuarPagamento percebemos que temos 3 dependências que são instâncias diretas de outras classes que precisamos para o método funcionar.
Isso faz com que o código da classe Pagamento seja fortemente acoplado com essas dependências e isso traz diversos problemas sendo o principal delas a necessidade de realizar alterações nesta classse sempre que alguma implementação for alterada.
Como podemos resolver esse problema ?
Usando a injeção de dependência para desacoplar a classe pagamento das instâncias que estão sendo criadas diretamente na classe.
Vamos fazer isso injetando essas dependências usando interfaces.
Aplicando a injeção de dependência
Vamos iniciar criando uma interface que vai definir um método para realizar pagamentos.
Inclua uma interface chamda IPagamentoServico no projeto
Public Interface IPagamentoServico
Sub Pagamento()
End Interface
|
A seguir vamos criar as classes PagamentoBoleto, PagamentoCartao e PagamentoDinheiro que implementa a interface e define a sua forma de pagamento:
PagamentoBoleto
Public Class PagamentoBoleto
Implements IPagamentoServico
Public Sub Pagamento() Implements IPagamentoServico.Pagamento
Console.WriteLine("Pagamento com Boleto")
End Sub
End Class
|
PagamentoCartao
Public Class PagamentoCartao
Implements IPagamentoServico
Public Sub Pagamento() Implements IPagamentoServico.Pagamento
Console.WriteLine("Pagamento com Cartão de Crédito/Débito")
End Sub
End Class
|
PagamentoDinheiro
Public Class PagamentoDinheiro
Implements IPagamentoServico
Public Sub Pagamento() Implements IPagamentoServico.Pagamento
Console.WriteLine("Pagamento com Dinheiro")
End Sub
End Class
|
Agora vamos criar uma classe Cobranca onde vamos injetar as dependências dos pagamentos e definir um método Pagamento que usa a instância para realizar o pagamento:
Public Class Cobranca
Private ReadOnly _pagamentoServico As IPagamentoServico
Public Sub New(pagamentoServico As IPagamentoServico)
_pagamentoServico = pagamentoServico
End Sub
Public Sub Pagamento()
_pagamentoServico.Pagamento()
End Sub
End Class
|
Para poder definir as formas de pagamentos vamos criar a classe AgenciaCobradora que retorna instãncias das formas de pagamentos:
Public Class AgenciaCobradora
Public Function GetPagamentoCartaoService() As IPagamentoServico
Return New PagamentoCartao
End Function
Public Function GetPagamentoBoletoService() As IPagamentoServico
Return New PagamentoBoleto
End Function
Public Function GetPagamentoDinheiroService() As IPagamentoServico
Return New PagamentoDinheiro
End Function
End Class
|
Agora é só alegria...
Vamos usar no método Main() do Module1 a nossa implementação com injeção de dependência:
Module Module1
Sub Main()
'Cria uma instância da classe AgenciaCobradora
'Tem acesso aos tipos de pagamentos
Dim injetor As New AgenciaCobradora
'define as formas de pagamento
Dim pagamentoServicoCartao = injetor.GetPagamentoCartaoService
Dim pagamentoServicoBoleto = injetor.GetPagamentoBoletoService
Dim pagamentoServicoDinheiro = injetor.GetPagamentoDinheiroService
'cliente vai pagar com cartão
Dim clientePagamento As New Cobranca(pagamentoServicoCartao)
clientePagamento.Pagamento()
Console.ReadLine()
End Sub
End Module
|
|
|
Agora nosso código ficou desacoplado e não temos mais dependências diretas que propagam suas alterações.
Usando um framework de injeção de dependência como o Ninject, Unity, etc., podemos refatorar e melhorar ainda mais o nosso código.
Pegue o projeto completo aqui: Vbn_DI.zip
(disse
Jesus) "Não crês tu que eu estou no Pai, e que o Pai está em mim? As palavras
que eu vos digo não as digo de mim mesmo, mas o Pai, que está em mim, é quem faz
as obras."
João 14:9
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
ASP .NET Core - Injetando dependências nas Views - Macoratti
ASP .NET Core - Usando a Injeção de dependência nativa - Macoratti
NET - Inversão de controle e Injeção de dependência para ... - Macoratti
.NET - Inversão de Controle (IoC) e Injenção de Dependência (DI)
ASP .NET MVC - Injeção de Dependência e repositório Mock - Macoratti
NET - Design Patterns - Uma abordagem Prática II - Macoratti.net