Inversão de controle (IoC) é um padrão que descreve técnicas genéricas para suportar uma arquitetura plug-in, onde os objetos podem “procurar” os outros objetos que eles necessitam para executar determinada ação.
IoC está sendo muito utilizado em projetos orientados a objeto. Conceitos como interface, herança e polimorfismo são bem presentes. O uso de IoC tem como objetivo reduzir o acoplamento, facilitar o reuso e os testes no projeto de software.
Em uma hierarquia, os módulos de nível mais alto não devem depender diretamente dos módulos de nível mais baixo. Ambos devem depender de abstrações. As abstrações não devem depender de detalhes da implementação, mas estes detalhes devem depender das abstrações. Desta forma, invertendo o controle.
A Injeção de Dependências é um caso especial do padrão IoC onde a técnica de programação é baseada em alterar o comportamento sem modificar classes internas. Além de classes independentes umas das outras por meio de abstrações, a injeção de dependências gera menor impacto para introdução de mudanças e um código mais facil de testar.
Um container de injeção de dependências é capaz de criar objetos com todas suas dependências injetadas e totalmente prontos para uso. Em geral estes containers podem ser configurados manualmente (programaticamente) ou dinamicamente (através de arquivos de configuração por exemplo).
Vamos falar neste post do uso de IoC na tecnologia Microsoft .NET.
O Unity da Microsoft foi escolhido como exemplo de container para entender melhor o uso de IoC.
O Unity suporta diversos tipos de injeção, como por exemplo: injeção por construtor, injeção por métodos gets e sets, injeção por arquivos de configuração, entre outras.
Como primeiro passo, precisamos criar uma Interface para ele.

Como segundo passo, vamos fazer o setup dele dentro do Global.asax da Aplicação Web.
OBS: Não é obrigatório fazer desta forma, é apenas uma abordagem que considero interessante e indicada por “gurus” da Microsoft.

Observem que no BuildContainer() tem um TODO para que seja adicionado o registro dos objetos.
Existem diversas formas de se registrar os objetos e cada uma está ligada a uma necessidade especifica, neste post, não irei tratar todas elas para termos oportunidade de discutir cada uma delas com mais tempo em um momento futuro.
Diante disto, vamos considerar a Injeção por Construtor utilizando a seguinte forma de registro:
unityContainer.RegisterType<INTERFACE/CLASSE ABSTRATA, CLASSE CONCRETA>();
Agora vamos olhar o código abaixo para entender o que este registro significa…

Observem que no exemplo, temos uma interface para o Logger chamada de ILogger. Temos também três implementações de Logger: uma para arquivo (FileLogger), uma para memória (MemoryLogger) e uma para banco de dados (DatabaseLogger). Além disto, existe uma Classe X que em seu construtor recebe a interface por parâmetro e fica apta a usar um dos 3 logs. Quem define qual deles será utilizado, é o registro que foi feito anteriormente no container do Unity.
Ou seja, voltando para o setup no Global.asax, em meu exemplo iremos colocar o seguinte registro:
unityContainer.RegisterType<ILogger, DatabaseLogger>();
e posteriormente faremos…
X x = container.Resolve<X>();
Neste momento o Unity irá resolver o objeto X e injetar a dependência do ILogger para a classe concreta do DatabaseLogger.
Espero que esta introdução ao IoC e Unity tenha ajudado de alguma forma… Em posts posteriores, podemos entrar em mais detalhes…
Referências:
http://unity.codeplex.com/
http://msdn.microsoft.com/en-us/library/cc440954.aspx/
http://msdn.microsoft.com/en-us/library/dd203101.aspx/

home










blog de design do c.e.s.a.r.