Inversão de Controle e Injeção de Dependência

O que é a Inversão de Controle

A Inversão de Controle, conhecida pela siga IoC, é um Desing Patner onde a sequência (controle) de chamada dos métodos é invertida em relação à programação tradicional, ou seja, ela não é definida pelo programador. Este controle é feito por uma infraestrutura de software muitas vezes chamada de container ou qualquer outro componente que possa tomar controle sobre a execução.

A inversão de controle em linhas gerais vem para resolver o problema do alto acoplamento.

Código altamente acoplado

Abaixo temos um exemplo de um código que está altamente acoplado onde caberia a utilização da Inversão de Controle.

public class ClientesController : Controller
{
      public ActionResult Index()
      {
            var cliente = new Cliente();
            var todosClientes = cliente.TodosClientes();
            return View(todosClientes);
      }
 }

O código compila sem erros, mais se observarmos ele contém alguns problemas de alto acoplamento. Quando é instanciado a classe cliente dentro de ClientesController criamos uma dependência da classe Cliente, caso essa classe sofra alguma modificação, exemplo seja incluído algo no construtor, teríamos que ajustar também a classe ClientesController.

Outro problema é que estamos chamando todos os clientes na mesma classe, podemos ver que existe um acoplamento com o banco de dados, isso pode nos trazer problemas na hora de fazer os testes de unidade.
Então para resolver o problema entra em ação a Inversão de Controles, onde a ideia é inverter o controle na classe ClientesController, removendo o acoplamento com a classe Clientes. E para fazer isso é utilizada a Injeção de Dependência.

O que é a Injeção de Dependência

A Injeção de Dependência, conhecida pela sigla DI, é um outro design pattener, utilizado quando é necessário manter o baixo nível de acoplamento entre módulos do sistema. Nessa solução as dependências não são definidas programaticamente, mais sim pela configuração de uma infraestrutura de software (container) que é responsável por injetar em cada componente a sua dependência declarada.

Implementação da Injeção de Dependência

Existem algumas maneiras de se implementar a Injeção de Dependência, são elas:
• Constructor: Neste modelo é implementada a injeção na definição dos construtores das classes;
• Getter e Setters: É definida a injeção nos gets e sets das classes;
• Interfaces Implementations: Modo em que é utilizado interfaces para realizar a injeção de dependências;
Assim, fazendo o ajuste no código usando as interfaces e a chamada no controle teríamos o seguinte código:

public class ClientesController : Controller
{
     private ICliente _cliente;
     public ClientesController(ICliente cliente)
     {
          _cliente = cliente;
     }
     public ActionResult Index()
     {
          var todosClientes = _cliente.TodosClientes();
          return View(todosClientes);
     }
}

Podemos ver que agora não estamos acoplados mais a classe de Cliente, qualquer alteração em seu construtor em nada afetaria a classe ClientesController, outra observação é que a gora a classe está testável, pois como está sem o acoplamento de Clientes, podemos fazer o mock do objeto para poder testar quando chamar o método TodosClientes.

Para utilizar a solução de Injeção de Dependência via propriedades ficaria da seguinte forma:

public class ClientesController
{
    private ICliente _cliente;
    public ClientesController()
    {
    }
    public ICliente Cliente
    {
        get  {
           if (_cliente != null)
               return _cliente;
        }
        set  {
           meuPedido = value;
        }
    }
 }

A injeção via propriedade é preferível quando os construtores não possuem nenhum argumento. Mais hoje em dia é mais usual utilizar pelo construtor a fim de se evitar referências circulares.

Frameworks para Injeção de Dependência

Hoje em dia já existem alguns frameworks que ajudam a fazer a injeção de dependências, como o Simple Injector, NInject, LightInject, DryIoc, entre outros, onde eles ficam responsáveis por criar a instancia dos objetos. No site do Palm Media ele faz alguns testes com alguns frameworks e lista os melhores (http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison).

Conclusão

Então podemos ver que com a utilização do IoC e do DI o código fica desacoplado e mais fácil de ser testado, e assim também faz com que nosso código siga os princípios do SOLID. Espero que tenham gostado, até a próxima.

Referências:

https://pt.wikipedia.org/wiki/Invers%C3%A3o_de_controle
http://www.linhadecodigo.com.br/artigo/3418/inversao-de-controle-ioc-e-injecao-de-dependencia-di-diferencas.aspx
https://lucasgermano.wordpress.com/2014/07/29/inversao-de-controle-ioc/
https://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_depend%C3%AAncia

Posted in .NET, Blog, C# and tagged , , , .

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *