Implementando Simple Injector

E aí galera, tudo certo?

Hoje vou falar um pouco sobre o Simple Injector, que é uma biblioteca para usarmos o conceito de Inversão de Controle (IoC) em .NET ou Silverligth. Esse cara é ideal pra quem não está familiarizado com bibliotecas maiores mas quer aplicar os princípios SOLID na aplicação.

Não vou explicar a fundo sobre injeção de dependência, se não o post ficaria muito grande e cansativo, mas tem bons artigos na internet explicando sobre.

O que me motivou à escrever esse post, foi a velocidade e praticidade do Simple Injector em relação ao Ninject, que é outra biblioteca de DI; depois de trabalhar em um projeto razoavelmente grande com o Ninject, pude perceber o quão lento ele é.

Quanto ao uso, uma boa prática é minimizar a dependência entre sua aplicação e o IoC. Isso aumenta a capacidade de manutenção e de testes da aplicação, além de resultar em um código mais limpo.

“E como fazer isso?”

Existem várias coisas que podemos fazer, uma delas é adotar o padrão de injeção de dependência pelo construtor, ou seja, você define todas as dependências de uma classe como parâmetros do construtor público dela.

A implementação do Simple Injector é bastante simples, pra exemplificar, criei um projeto com algumas camadas, simulando uma aplicação, mas nada de muito complexo e nada arquiteturado.

Basicamente, trata-se de um projeto ASP .NET MVC 5, uma Class Library simulando a camada de regras de negócio, outra Class Library simulando a camada de acesso ao banco de dados e outra Class Library simulando um Cross Cutting com a implementação da Injeção de Dependência, que é o que nos interessa hoje.

Enfim, como utilizaremos o padrão de injeção de dependência pelo construtor, irei mostrar como implementar as classes de maneira à se comportarem como queremos, primeiramente, a minha camada Web vai fazer uma requisição à camada de negócios, já deixo subentendido que a minha View recebe um IEnumerable de Client :

Web

Reparem no construtor do ClientController, ele espera um tipo IClientService que é instanciado através do Simple Injector, o mesmo acontece com a implementação da interface IClientService, veja:

Business

A única diferença é que o construtor da classe ClientService espera um tipo IClientRepository, que é a camada de persistência de dados, e novamente o Simple Injector que faz a instância.

E por fim, temos que implementar a classe que faz a resolução das dependências, pra isso precisamos instalar o Simple Injector no projeto inicial, ou seja, no Web, e no projeto que vai comportar as resoluções; podemos fazer isso através do NuGet:

PM> Install-Package SimpleInjector

Ela fica mais ou menos assim:

DI

E pra tudo funcionar perfeitamente, basta adicionar uma linha de código no Global.asax do seu projeto Web:

Global

E com isso já conseguimos deixar a aplicação usando Injeção de Dependência perfeitamente! 😀

Também gostaria de deixar registrado o quanto gostei da documentação do Simple Injector, bastante rica, com muita informação e dicas legais. Uma dessas dicas é de como registrar as dependências automaticamente, sem precisar mexer na classe do Container toda vez que adicionar uma nova classe que precise ser resolvida, o que facilita e agiliza muito o desenvolvimento, o exemplo disso está disponível no projeto no GitHub: https://github.com/vmussak/SimpleInjectorExample

Por hoje é só isso, qualquer dúvida ou sugestão, estou à disposição!

Referências:

https://simpleinjector.org/index.html
https://simpleinjector.codeplex.com/

15 thoughts on “Implementando Simple Injector

  1. Claudio Maia 10/04/2015 / 17:06

    Parabéns pelo Post, muito bem detalhado! E realmente, a documentação do Simple Injector foi muito bem feita. Abraço!

    Gostar

  2. Sergio Prates 13/04/2015 / 12:51

    Muito interessante este artigo, era o que eu estava procurando, como implementar o simple injector de maneira simples e prática

    Gostar

  3. Sergio Prates 01/07/2015 / 20:30

    Vinicius, estou implementando um projeto Web API com Simple Injector, entretanto tá meio complicado aqui,ele coloca as depedencias para as minhas classes mas da problema com as controllers do webapi, já procurei bastante na internet e não consegui achar nada que ajudasse. Será que vc poderia me ajudar? O erro é o seguinte: An error occurred when trying to create a controller of type ‘UserController’. Make sure that the controller has a parameterless public constructor

    Gostar

    • Sergio Prates 01/07/2015 / 20:33

      deixa quieto… achei uma resposta XD.

      Gostar

      • Lincoln 09/08/2016 / 15:32

        Sergio Prates, estou fazendo uma WebApi e meu problema é parecido, porém, no meu caso, o Dispose é chamado no meio de um contexto, como você resolveu isso ? tem um exemplo do codigo.

        Obrigado

        Gostar

      • Roberto Lopes Ramos 05/11/2016 / 09:33

        Qual foi Sergio? estou com o mesmo problema… 😦

        Tenho classes base e acho q meu problema ta nisso, tipo ServiceBase ou RepositoryBase.

        Gostar

  4. RAPHAEL POEIRAS 09/03/2017 / 15:56

    Ótimo post. Parabéns! Fui muito útil para o meu problema

    Gostar

  5. thiago capaverde 16/05/2017 / 11:00

    Ola, parabéns pelo conteúdo. Muito bem explicado.
    Estava realizando uns testes para implementar o simple injector na empresa mas me deparei com um problema.
    Tenho uma solução com vários projetos. Vou chamar aqui para exemplificar de projeto PDV e retaguarda.
    Se eu colocar uma interface em um construtor da classe “Login” por exemplo e esquecer de por nas configurações do simple injector ou esta classe tiver 2 construtores quando eu for executar este projeto ele vai reclamar. Até ai tudo certo.
    Mas se eu tiver 2 contêineres diferentes um para cada projeto ele vai reclamar para um mas não vai reclamar falando que esta faltando também no outro. Vai dar erro só quando eu executar o segundo projeto. Pensando que minha solução pode ter muitos projetos é um grande problema.
    Como resolver isto e evitar que um estrague o código do outro projeto que usa também a mesma classe?

    Gostar

    • viniciusmussak 16/05/2017 / 20:19

      Fala Thiago! Tudo certo?

      Obrigado pelo feedback 😀

      Se eu entendi corretamente, você compartilha classes de projetos em outros, certo? E cada projeto possui o seu próprio container para resolver as dependências. Se for isso, para resolver o seu problema você deve resolver a dependência de todas as classes utilizadas no projeto, mesmo que forem de outro projeto.

      Por exemplo:

      Você tem o projeto 1, que possui a classe A;
      e o projeto 2, que utiliza a classe A;

      No projeto 1, você deve declarar a dependência (você já deve estar fazendo isso, é o projeto que “não reclama”)
      E No projeto 2, você também tem que resolver; feito isso, é só alegria!

      Caso eu não tenha entendido ou algo não tenha ficado claro, pode me mandar um email (vinicius.mussak@outlook.com) que a gente resolve 🙂

      Abraços!

      Gostar

  6. Lucia 27/12/2017 / 18:18

    Estou com dificuldade para usar o simpleInjector, quase desistindo, parece que há um problema com enumerable!!!! Já tentei de tudo

    public static class SimpleInjectorContainer
    {
    public static Container RegisterServices()
    {
    var container = new Container();

    container.Register();
    container.Register();
    container.Verify();

    return container;
    }

    public interface IProductServices
    {
    IEnumerable ReturnProductsSellof();
    }

    Erro: No registration for type IEnumerable could be found.
    Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.

    Detalhes da Exceção: SimpleInjector.ActivationException: No registration for type IEnumerable could be found.

    Erro de Origem:

    Exceção sem tratamento foi gerada durante a execução da atual solicitação da Web. As informações relacionadas à origem e ao local da exceção podem ser identificadas usando-se o rastreamento de pilha de exceção abaixo.

    Rastreamento de Pilha:

    [ActivationException: No registration for type IEnumerable could be found.]

    Gostar

Deixe uma resposta para RAPHAEL POEIRAS Cancelar resposta