.NET - Injeção de dependência com Ninject


Hoje vou escrever novamente sobre injeção de dependência e desta vez eu vou mostrar como usar o Ninject para fazer a injeção de dependência.

O Ninject é um Contâiner para injeção de dependência e nos ajuda a injetar de uma forma simples e elegante.

A primeira coisa a fazer e obter o Ninject e você pode fazer isso baixando diretamente do link: http://www.ninject.org/download.html e depois fazendo a referência em sua aplicação ou via Nuget em seu projeto.

Vamos definir um cenário bem simples a partir do qual vou mostrar como usar o Ninject.

Neste exemplo eu estou usando o Visual Studio Express 2012 for desktop e a linguagem VB .NET.

Temos a classe Produtos que define de forma bem simples o id, o nome e o preço de um produto:

Public Class Produtos

    Public Property Id As Integer
    Public Property Nome As String
    Public Property Preco As Decimal

End Class

Temos a interface ICalcularPedido que define como calcular o valor total dos produtos em um pedido:

Public Interface ICalcularPedido

    Function CalcularValorTotal(ParamArray produtos As Produtos()) As Decimal

End Interface

Temos a classe concreta CalcularTotalPedido que implementa a interface ICalcularPedido:

Public Class CalcularTotalPedido
    Implements ICalcularPedido

    Public Function CalcularValorTotal(ParamArray produtos() As Produtos) As Decimal Implements ICalcularPedido.CalcularValorTotal
        Return produtos.Sum(Function(p) p.Preco)
    End Function

End Class

Como você faria para calcular o valor total dos produtos em um pedido ?

No formato atual primeiro temos que criar uma instância da classe CalcularTotalPedido:

Dim _calcularTotalPedido As New CalcularTotalPedido

E nosso objetivo é justamente evitar a criação da instância da classe CalcularTotalPedido para poder usar o método CalcularValorTotal().

Vamos definir uma classe chamada Pedidos com o código a seguir numa tentativa de resolver este problema:

Public Class Pedidos

    Private calculaPedido As ICalcularPedido

     Public Sub New(_calculaPedido As ICalcularPedido)
        calculaPedido = _calculaPedido
    End Sub

     Dim _produtos As Produtos() = {New Produtos() With { _
             .Nome = "Caderno", .Preco = 4.5 _
        }, New Produtos() With { _
             .Nome = "Caneta", .Preco = 1.3 _
        }, New Produtos() With { _
             .Nome = "Lápis", .Preco = 1.2 _
        }}

    Public Function CalcularValorPedido() As Decimal
        Dim total As Decimal = calculaPedido.CalcularValorTotal(_produtos)
        Return total
    End Function

End Class

A classe Pedidos possui um construtor (Sub New) que recebe uma implementação da interface ICalcularPedido e possui também o método CalcularValorPedido que usa a implementação da interface para calcular o valor total do pedido recebendo um array de produtos.

Mas de onde virá a implementação da interface ???

Aqui entra em ação o Ninject...

Vamos então mostrar como ele atua e como usá-lo em um projeto do tipo Console Application usando as classes acima descritas.

Abra o Visual Studio 2012 Express for desktop e no menu File clique em New Project e selecione o template Console Application:

Para definir as classes use o menu Project e clique em Add Class informando o nome da classe.

Após criar a interface e as classes vamos incluir a referência ao Ninject em nosso projeto.

Clique no menu Project -> Add Reference e a seguir no item Browse e localize a biblioteca Ninject selecionando Ninject.dll e clicando em OK:

Agora declare no projeto a referência ao namespace Ninject:

Imports Ninject

Vamos abrir o arquivo Modelu1.vb e implementar a injeção de dependência usando o Ninject:

1- Primeiro vamos instanciar o Kernel do Ninject que irá criar um objeto a partir do qual podemos nos comunicar com o Ninject

Dim ninjectKernel As IKernel = New StandardKernel()

Como muitos Containers para Injeção de dependência o Ninject usa um objeto central (que ele chama de kernel) para fornecer implementações concretas de dependências em tempo de execução.

O kernel é a implementação padrão de tal objeto.

2- A seguir vamos redirecionar o pedido da implementação da interface ICalcularPedido para a classe onde a interface esta implementada que é a classe CalcularTotalPedido:

ninjectKernel.Bind(Of ICalcularPedido)().[To](Of CalcularTotalPedido)()

3- Após a definição do Kernel e do redirecionamento da interface temos que implementá-la e passá-la ao construtor da classe “Pedidos”, através do método Get do Ninject.

Dim _calculaPedido As ICalcularPedido = ninjectKernel.[Get](Of ICalcularPedido)()
Dim _pedido As New Pedidos(_calculaPedido)

4- A implementação é então passada pelo construtor da classe "Pedidos" e a seguir chamamos o método "CalcularValorPedido" da interface que calcula o valor total do pedido:

Dim _total As Decimal = _pedido.CalcularValorPedido()

O código completo do módulo Module1.vb é dado abaixo:

Imports Ninject

Module Module1

    Sub Main()

        Dim ninjectKernel As IKernel = New StandardKernel()
        ninjectKernel.Bind(Of ICalcularPedido)().[To](Of CalcularTotalPedido)()

        Console.WriteLine("Implementando Ninject")
        Console.WriteLine("---------------------------")
        Console.WriteLine("")
        Dim _calculaPedido As ICalcularPedido = ninjectKernel.[Get](Of ICalcularPedido)()
        'passa a implementação para construtor da classe Pedidos
        Dim _pedido As New Pedidos(_calculaPedido)
        Dim _total As Decimal = _pedido.CalcularValorPedido()
        Console.WriteLine("Valor Total do Pedido: {0}", _total)
        Console.ReadKey()
    End Sub

End Module

Ao lado vemos o resultado da execução do projeto.

Como você observou usar o Ninject é muito simples...

Sayonara...

Pegue o projeto completo aqui: UsandoNinject.zip

Mar 1:8 Eu vos batizei em água; ele, porém, vos batizará no Espírito Santo.

Mar 1:9 E aconteceu naqueles dias que veio Jesus de Nazaré da Galiléia, e foi batizado por João no Jordão.

Mar 1:10 E logo, quando saía da água, viu os céus se abrirem, e o Espírito, qual pomba, a descer sobre ele;

Mar 1:11 e ouviu-se dos céus esta voz: Tu és meu Filho amado; em ti me comprazo.

Mar 1:12 Imediatamente o Espírito o impeliu para o deserto.

Referências:


José Carlos Macoratti