Autofac – inversão de controle e injeção de dependência no .net

Facebooktwittergoogle_plusredditpinterestlinkedinmail

O Autofac é um dos mais conhecidos e populares containers de inversão de controle para .net, e é dele quem vamos falar hoje. Dentre os containers de IoC disponíveis no NuGet, o Autofac é o segundo com maior número de downloads. Não é o objetivo deste post explicar sobre o pattern de injeção de dependência e inversão de controle, e sim mostrar como utilizar o Autofac, além de suas características.

Para começar, vamos criar um projeto para uma aplicação Windows Forms. Após o projeto criado, abra o NuGet Package Manager, e pesquise por “Autofac”, e faça a instalação, de acordo com a figura abaixo:

instalação Autofac

instalação Autofac

Agora que já temos nosso projeto configurado para utilizar o Autofac, vamos criar uma interface IDesenvolvedor conforme o código abaixo:

namespace AutofacDemoWin
{
    public interface IDesenvolvedor
    {
        string GetLinguagemProgramacao();
    }
}

Agora vamos criar a classe DesenvolvedorNinja, que irá implementar a interface acima:

namespace AutofacDemoWin
{
    public class DesenvolvedorNinja : IDesenvolvedor
    {
        public string GetLinguagemProgramacao()
        {
            return "C#";
        }
    }
}

Agora, vamos deixar nosso Form de acordo com a imagem abaixo, para isso coloque um botão com o texto “Obter Linguagem da forma tradicional” e um botão com o texto “Obter Linguagem usando Autofac”:

form demo Aautofac

Agora vamos ao código do botão “Obter Linguagem da forma tradicional”:

private void buttonObterLinguagemDefault_Click(object sender, EventArgs e)
{
 IDesenvolvedor desenvolvedor = new DesenvolvedorNinja();
 MessageBox.Show(desenvolvedor.GetLinguagemProgramacao());
}

Essa é a forma que vemos na maioria dos projetos por aí, certo? Nós somos os responsáveis por criar a instância de um DesenvolvedorNinja e atribuí-lo à interface IDesenvolvedor. Então quando nós queremos utilizar a interface IDesenvolvedor, nós somos obrigados a conhecer qual implementação dela queremos criar.

Antes de ver como faríamos para utilizar a interface IDesenvolvedor usando o Autofac, vamos precisar criar o container do Autofac, e registrar nossas interfaces/classes para que ele possa fazer todo o gerenciamento para nós. Para isso, vamos declarar uma variável do tipo IContainer dentro da classe do nosso form:

private IContainer _container;

E no evento Load de nosso form, colocar o código abaixo:

private void FormAutofacDemoWin_Load(object sender, EventArgs e)
{
	var builder = new ContainerBuilder();
	builder.RegisterType<DesenvolvedorNinja>().As<IDesenvolvedor>().InstancePerDependency();
	_container = builder.Build();
}

O que estamos fazendo nesse trecho de código, é em primeiro lugar criando o container builder do Autofac, é ele quem é usado para registrarmos nossas classes/interfaces e para criar o container. Na próxima linha estamos registrando nossa classe DesenvolvedorNinja, para ser criada toda vez que alguém pedir pela interface IDesenvolvedor, e definindo que cada vez que pedirem pela interface, uma nova instância será criada. E por fim, estamos criando o container do Autofac, a partir do container builder que utilizamos para registrar nossas classes/interfaces.

Agora sim, vamos ao código de nosso segundo botão, ele ficará dessa forma:

private void buttonObterLinguagemAutofac_Click(object sender, EventArgs e)
{
	IDesenvolvedor desenvolvedor = _container.Resolve<IDesenvolvedor>();
	MessageBox.Show(desenvolvedor.GetLinguagemProgramacao());
}

Ao executarmos nossa aplicação, quando clicamos nos dois botões, o resultado obtido é o mesmo, um MessageBox é exibido com o texto “C#”. A grande diferença do código de um botão para o outro, e que mostra um dos grandes benefícios da inversão de controle, é que no código de nosso segundo botão, nós não fazemos nenhuma referência à classe DesenvolvedorNinja, o que faz com que o acoplamento seja reduzido. A instrução “Resolve” devolve a instância registrada no container do Autofac para o tipo solicitado, no nosso caso, para a interface IDesenvolvedor.

Com o Autofac, em vez de criarmos nossas classes usando “new”, nós pedimos a instância ao container usando o método “Resolvo”.

Esse exemplo é bem básico e introdutório ao Autofac, nós veremos aqui mais artigos sobre o assunto, entrando em detalhes mais avançados, como automatizar o registro das dependências, como injetar as dependências necessárias no construtor da classe, escolher qual implementação se deseja a partir de parâmetros, etc. Eu venho usando o Autofac em alguns projetos, e o resultado é bastante satisfatório.

Segue abaixo o código completo do form de nosso exemplo:

using Autofac;
using System;
using System.Windows.Forms;

namespace AutofacDemoWin
{
    public partial class FormAutofacDemoWin : Form
    {
        private IContainer _container;

        public FormAutofacDemoWin()
        {
            InitializeComponent();
        }

        private void buttonObterLinguagemDefault_Click(object sender, EventArgs e)
        {
            IDesenvolvedor desenvolvedor = new DesenvolvedorNinja();
            MessageBox.Show(desenvolvedor.GetLinguagemProgramacao());
        }

        private void FormAutofacDemoWin_Load(object sender, EventArgs e)
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<DesenvolvedorNinja>().As<IDesenvolvedor>().InstancePerDependency();
            _container = builder.Build();
        }

        private void buttonObterLinguagemAutofac_Click(object sender, EventArgs e)
        {
            IDesenvolvedor desenvolvedor = _container.Resolve<IDesenvolvedor>();
            MessageBox.Show(desenvolvedor.GetLinguagemProgramacao());
        }
    }
}

O código-fonte completo do exemplo está disponível no GitHub: https://github.com/rdakar/autofac-primeiros-passos

Página oficial do Autofac: http://autofac.org/

Facebooktwittergoogle_plusredditpinterestlinkedinmail

5 thoughts on “Autofac – inversão de controle e injeção de dependência no .net

Deixe uma resposta

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