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