Recursos especiais neste artigo:
Contém nota Quickupdate, Conteúdo sobre boas práticas.
A Injeção de Dependências veio para trazer mais desacoplamento à programação, apesar da técnica não ser nova, com o advento das grandes aplicações e da necessidade de maior reuso e testabilidade, este assunto voltou com força total e tem sido conversa frequente entre arquitetos e engenheiros. Veremos todos os conceitos à cerca de DI e IoC juntos com o Spring.NET e depois vamos criar uma aplicação desde a UML até a implementação final da camada de apresentação, aplicando assim o Spring e sua injeção de dependências em um cenário bem próximo do real.
Em que situação o tema é útil
Este artigo é útil a qualquer
aplicação .NET onde se deseje ter um maior nível de desacoplamento e
testabilidade, aumentando ainda o reuso e consequentemente a produtividade das
equipes que empregarem as práticas citadas aqui.
O termo Injeção de Dependências foi usado pela primeira vez por Martin Fowler em seu famoso artigo chamado Inversion of Control Containers and the Dependency Injection pattern que em português significa Containers de Inversão de Controles e o Padrão de Injeção de Dependências.
Quando ouvimos falar de “fraco acoplamento” devemos compreender que os objetos precisam ter apenas dependências necessárias para desempenharem bem o seu papel e estas dependências precisam ser muito poucas. Estas dependências de objetos devem ser uma interface e não uma classe concreta. Esta é a vantagem de se usar o fraco acoplamento, porque oferece usabilidade, manutenibilidade e principalmente testabilidade para as aplicações.
De acordo com Fowler, os termos Injeção de Dependências (DI) e Inversão de Controle (IoC) são muito parecidos: tendo a DI alguns tipos a menos que IoC, de forma que se use apenas o que há de melhor na IoC. O motivo da troca de nome fora apenas de semântica para que possa facilitar a compreensão do leitor e daqueles que estão aprendendo este padrão de desenvolvimento.
O objetivo da Injeção de Dependência é separar objetos que populam outros – tais objetos são chamados de montadores, ou assemblers – dos que fazem uso de implementação de interfaces, onde esta implementação é chamada de serviço.
A Injeção de Dependências consiste em dois tipos ou estilos principais:
1) Injeção via Construtor
2) Injeção via Setter
Injeção via Construtor
Consiste em passar um objeto de Serviço que será injetado diretamente na classe via construtor. Na Listagem 1 podemos ver um exemplo de uma interface com os métodos de operação no banco de dados, enquanto que na Listagem 2 temos a simulação de uma classe concreta implementando esta interface. Observe que na linha 5 temos a variável de instância que será injetada na classe e na linha 13 temos a injeção propriamente dita através do construtor da Classe.
Listagem 1. Interface
01 public interface IContatoDAL
02 {
03 void Salvar(Contato entidade);
04 List<Contato> listarTudo();
05 Contato listarPorId (int id);
06 void Atualizar(Contato entidade);
07 void Apagar(Contato entidade);
08 }
Listagem 2. Classe acessando o Serviço IContatoDAL
01 public class ContatoDAL:IContatoDAL
02 {
03 #region Atributos
04 public Conexao Conexao{ get; set; }
05 #endregion
06 #region Construtor
07 public ContatoDAL(Conexao conexao)
08 {
09 this.Conexao = conexao;
10 }
11 #endregion
12 }
Injeção via setter
Faz a DI em um método set dentro da Classe que irá acessar o serviço, bastando referenciá-lo no framework para injetá-lo na Classe que irá consumir o serviço, como mostra a Listagem 3.
Listagem 3. Injeção de Dependências via Setter
01 public class ManterContato : IManterContato
02 {
03 //pode ser feito desta forma
04 private IContatoDAL dao;
05
06 public IContatoDAL Dao
07 {
08 set { dao = value; }
09 }
10
11 //ou pode ser feito desta forma
12
13 public IContatoDAL Dao {get; set;}
14
15 //Implementação da Classe
16 }
Veja na Listagem 3 que a dependência que a classe ManterContato têm da interface IContatoDAL é passada através de um método Set, dessa forma não precisamos inicializar a variável (linha 4), visto que o container de IoC/DI fará isso automaticamente assim que a classe ManterContato for utilizada na aplicação. Além disso, podemos observar nesta mesma listagem que podemos fazer isso através de uma propery manual (linha 6) ou através de uma property automática (linha 13).
Spring.NET
O Spring.NET é uma versão .NET do framework Spring criado para java e que é largamente usado pela comunidade do mesmo, sendo que o Spring.NET não se limita à injeção de dependências, que é o seu propósito básico, mas estende suas funcionalidade à integrações em aplicações corporativas.
O Spring.NET contém módulos de integração para frameworks como NHibernate para persistência, AOP – Programação Orientada a Aspectos, ASP.NET MVC 2, ASP.NET MVC 3, NUnit para testes, Integração SOA e MQs para troca de mensagens entre aplicações utilizando barramentos, conforme podemos ver na Figura 1.
O Spring.NET é uma solução de Container de IoC/DI para .NET, fazendo frente aos já estabelecidos frameworks Ninject , Structure Map, Castle Windsor e Unity, contendo uma semântica idêntica a do java, porém com implementações totalmente distintas, até por serem linguagens diferentes.
Figura 1. Módulos do Spring.NET
Devido à extensão do assunto, neste artigo utilizaremos apenas o módulo Core do framework pelo fato de que o mesmo é a base para compreensão geral do Spring.NET.
Para instruções detalhadas sobre o que faz cada módulo, consulte a seção links. Porém, entendendo a Spring.Core podemos compreender melhor os outros módulos.
Por que usar o Spring.NET?
Para responder a esta pergunta, vamos observar uma implementação sem o Spring e outra com o Spring.
Para fins de exemplo, vamos criar uma classe chamada Conexão que fará uma simulação de acesso ao Banco de Dados, para isso criaremos ainda uma interface chamada IClasseDAL para o serviço da ClasseDAL. Na Listagem 4 podemos ver estas classes, onde temos a classe de conexão (linha 1 à 9), a interface IClassDAL (linha 10 à 15), ClasseDAL (linha 17 à 47) e Principal (linha 49 à 60), que seria para simulação da execução da aplicação.
Neste caso, na ClasseDAL temos dois construtores implementados. No primeiro, sem parâmetros, teríamos que instanciar uma nova conexão para ser utilizada pelos métodos da classe. Já no segundo receberíamos a conexão via parâmetro. Além disso, nos métodos da classe temos que Abrir (linha 31) e Fechar (linha 43) a conexão para controlar a memória e evitar problemas de performance.
Listagem 4. Implementação sem Spring.NET
01 public class Conexao {
02 public Boolean IsConectado {get; set;}
03 public String Conexao {get; set;}
04 public Conexao(){
05 this.conexao = "Data Source=ALLSPARK;Initial
Catalog=ANS;User ID=usuario";
06
07 //instruções de conexão
08 }
09 }
10 public interface IClasseDAL{
11
12 List<Object> listarTudo();
13 void Salvar(Object o);
14 void Excluir(Object o);
15 }
16
17 public class ClasseDAL : IClasseDAL {
18 private Conexao conexao = null;
19 public ClasseDAL(){
20 this.conexao = new Conexao();
21 }
22
23 public ClasseDAL(Conexao conexao){
24 this.conexao = conexao;
25 }
26
27 private List<Object> listarTudo(){
28
29 try{
30
31 conexao.abre
32 //Operação
33 //...
34 ...
35 ...
36 ...
37 } catch {
38
39 throw;
40
41 } finally {
42
43 conexao.fecha
44
45 }
46 }
47 }
48
49 public class Principal {
50
51 public static void main(){
52
53 Object classe = new Object();
54
55 ClasseDAL dal = new ClasseDAL();
56
57 dal.Salvar(classe);
58 }
59
60 }
Na linha 55 instanciamos ClasseDAL para permitir que o objeto DAL acesse todas as operações necessárias. Observe que neste caso utilizamos o construtor padrão da mesma, desta forma a conexão foi criada dentro da própria classe.
Na Listagem 5 temos as mesmas classes existentes na Listagem 4, porém, com o uso do Spring.
Listagem 5. Mesma implementação utilizando o Spring
01 public class ClasseDAL : IClasseDAL {
02 private Conexao conexao;
03 public Conexao PConexao {
04 set {
05 conexao = value;
06 }
07 }
08 private List<Object> listarTudo(){
09 try{
10 conexao.Commit;
11 //Operação
12 //...
...
...
...
13 } catch {
14 conexao.Rollback;
15 }
16 }
17 }
18 public class Principal {
19 public static void Main(){
20 IApplicationContext di = ContextRegistry.GetContext();
21 IClasseDAL dal = (ClasseDAL) di.GetObject("ClasseDAL");
22 dal.listarTudo();
23 }
24 }
Veja que neste caso estamos utilizando a injeção via setter, através da propriedade da linha 5. Além disso, na linha 36 temos a criação da ClasseDAL através do método GeoObject do Spring.
Após sua implementação, precisamos registrar os objetos para que o Spring.NET possa reconhecê-los, existindo duas formas para isso:
1) Registrar o mesmo dentro do arquivo App.Config ou Web.Config propriamente marcado com as tags do Spring. Esta é a forma que será utilizada neste artigo, devido á simplicidade do mesmo.
2) Usar um arquivo .xml separado fazendo uma menção a eles nos App.Config\Web.Config fazendo com que o Spring aponte para este arquivo. Esta é a melhor opção caso o seu sistema seja grande e com muitas regras de negócios e implementações que necessitem de Injeção de Dependências, esta é uma forma de deixar mais organizado e facilitar a manutenção do seu código.
...Confira outros conteúdos:
Teste unitário com NUnit
Como migrar projetos do ASP.NET MVC...
Crie relatórios com o Stimulsoft...
Promoção de Natal
Oferta exclusiva de Natal!
Pagamento anual
12x no cartão
De: R$ 69,00
Por: R$ 59,90
Total: R$ 718,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- 12 meses de acesso
Pagamento recorrente
Cobrado mensalmente no cartão
De: R$ 79,00
Por: R$ 59,90 /mês
Total: R$ 718,80
Garanta o desconto
- Formação FullStack Completa
- Carreira Front-end I e II, Algoritmo e Javascript, Back-end e Mobile
- +10.000 exercícios gamificados
- +50 projetos reais
- Comunidade com + 200 mil alunos
- Estude pelo Aplicativo (Android e iOS)
- Suporte online
- Fidelidade de 12 meses
- Não compromete o limite do seu cartão
<Perguntas frequentes>
Nossos casos de sucesso
Eu sabia pouquíssimas coisas de programação antes de começar a estudar com vocês, fui me especializando em várias áreas e ferramentas que tinham na plataforma, e com essa bagagem consegui um estágio logo no início do meu primeiro período na faculdade.
Estudo aqui na Dev desde o meio do ano passado!
Nesse período a Dev me ajudou a crescer muito aqui no trampo.
Fui o primeiro desenvolvedor contratado pela minha
empresa. Hoje eu lidero um time de desenvolvimento!
Minha meta é continuar estudando e praticando para ser um
Full-Stack Dev!
Economizei 3 meses para assinar a plataforma e sendo sincero valeu muito a pena, pois a plataforma é bem intuitiva e muuuuito didática a metodologia de ensino. Sinto que estou EVOLUINDO a cada dia. Muito obrigado!
Nossa! Plataforma maravilhosa. To amando o curso de desenvolvimento front-end, tinha coisas que eu ainda não tinha visto. A didática é do jeito que qualquer pessoa consegue aprender. Sério, to apaixonado, adorando demais.
Adquiri o curso de vocês e logo percebi que são os melhores do Brasil. É um passo a passo incrível. Só não aprende quem não quer. Foi o melhor investimento da minha vida!
Foi um dos melhores investimentos que já fiz na vida e tenho aprendido bastante com a plataforma. Vocês estão fazendo parte da minha jornada nesse mundo da programação, irei assinar meu contrato como programador graças a plataforma.
Wanderson Oliveira
Comprei a assinatura tem uma semana, aprendi mais do que 4 meses estudando outros cursos. Exercícios práticos que não tem como não aprender, estão de parabéns!
Obrigado DevMedia, nunca presenciei uma plataforma de ensino tão presente na vida acadêmica de seus alunos, parabéns!
Eduardo Dorneles
Aprendi React na plataforma da DevMedia há cerca de 1 ano e meio... Hoje estou há 1 ano empregado trabalhando 100% com React!
Adauto Junior
Já fiz alguns cursos na área e nenhum é tão bom quanto o de vocês. Estou aprendendo muito, muito obrigado por existirem. Estão de parabéns... Espero um dia conseguir um emprego na área.
Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.