Spring.NET: Injeção de Dependências em Aplicações Multicamadas - Revista .NET Magazine 103
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.
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 }
"
[...] continue lendo...
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo