Autofac: Injeção Seletiva de Propriedades e Métodos

  1. Injeção de Propriedades Básica

Para implementar a injeção de propriedades com Autofac, crie uma aplicação console e adicione o pacote Autofac via NuGet. Defina as camadas de enterfaces e implementações conforme descrito.

Interfaces na camada Domain.Interfaces:

namespace Domain.Interfaces
{
    public interface IAudioInput
    {
    }
}
namespace Domain.Interfaces
{
    public interface IPowerSupply
    {
    }
}
namespace Domain.Interfaces
{
    public interface IAudioOutput
    {
    }
}

Implemantações na camada Domain.Services:

using Domain.Interfaces;

namespace Domain.Services
{
    public class AudioInput : IAudioInput
    {
        public AudioInput()
        {
            Console.WriteLine($"{this.GetType().Name} foi instanciado..");
        }
    }
}
using Domain.Interfaces;

namespace Domain.Services
{
    public class PowerSupply : IPowerSupply
    {
        public PowerSupply(IAudioInput input)
        {
            Console.WriteLine($"{this.GetType().Name} foi instanciado");
        }
    }
}
using Domain.Interfaces;

namespace Domain.Services
{
    public class AudioOutput : IAudioOutput
    {
        public IAudioInput AudioInput { get; set; }
        
        public AudioOutput(IPowerSupply supply)
        {
            Console.WriteLine($"{this.GetType().Name} foi instanciado...");
        }
    }
}

Configuração no Program.cs para ativar a injeção de propriedades:

ContainerBuilder configurador = new ContainerBuilder();
configurador.RegisterType<AudioInput>().As<IAudioInput>();
configurador.RegisterType<PowerSupply>().As<IPowerSupply>();
configurador.RegisterType<AudioOutput>().As<IAudioOutput>().PropertiesAutowired();
IContainer container = configurador.Build();
IAudioOutput output = container.Resolve<IAudioOutput>();

Ao executar com um ponto de interrupção, a propriedade AudioInput será automaticamente preenchida.

  1. Injeção Seletiva com Atributos

Para injetar apenas propriedades marcadas, crie um atributo personalizado e um seletor de propriedades.

Definição do atributo:

using System;

namespace Domain.Framework.Autofac
{
    [AttributeUsage(AttributeTargets.Property)]
    public class InjectRequiredAttribute : Attribute
    {
    }
}

Seletor de propriedades customizado:

using Autofac.Core;
using System.Reflection;
using System.Linq;

namespace Domain.Framework.Autofac
{
    public class CustomInjectorSelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propriedade, object instancia)
        {
            return propriedade.CustomAttributes.Any(c => c.AttributeType == typeof(InjectRequiredAttribute));
        }
    }
}

Modifique a classe AudioOutput para usar o atributo:

using Domain.Framework.Autofac;
using Domain.Interfaces;

namespace Domain.Services
{
    public class AudioOutput : IAudioOutput
    {
        [InjectRequired]
        public IAudioInput AudioInput { get; set; }

        public IPowerSupply PowerSupplyProp { get; set; }
        
        public AudioOutput(IPowerSupply supply)
        {
            Console.WriteLine($"{this.GetType().Name} foi instanciado...");
        }
    }
}

Atualize o Program.cs para aplicar o seletor:

ContainerBuilder configurador = new ContainerBuilder();
configurador.RegisterType<AudioInput>().As<IAudioInput>();
configurador.RegisterType<PowerSupply>().As<IPowerSupply>();
configurador.RegisterType<AudioOutput>().As<IAudioOutput>().PropertiesAutowired(new CustomInjectorSelector());
IContainer container = configurador.Build();
IAudioOutput output = container.Resolve<IAudioOutput>();

Executando, apenas a propriedade com o atributo InjectRequired será injetada; a outra permanceerá nula.

  1. Injeção de Métodos

Para injetar dependências via métodos, adicione um método na classe e configure o container.

Modifique a classe AudioOutput para incluir um método de inicialização:

using Domain.Framework.Autofac;
using Domain.Interfaces;

namespace Domain.Services
{
    public class AudioOutput : IAudioOutput
    {
        public AudioOutput(IPowerSupply supply)
        {
            Console.WriteLine($"{this.GetType().Name} foi instanciado...");
        }

        public void Initialize(IPowerSupply supply)
        {
            Console.WriteLine("Injeção de método realizada");
        }
    }
}

Configuração no Program.cs para injeção via método:

ContainerBuilder configurador = new ContainerBuilder();
configurador.RegisterType<AudioInput>().As<IAudioInput>();
configurador.RegisterType<PowerSupply>().As<IPowerSupply>();
configurador.RegisterType<AudioOutput>().As<IAudioOutput>().OnActivated(   
    ativacao =>
    {
        IPowerSupply supply = ativacao.Context.Resolve<IPowerSupply>();
        ativacao.Instance.Initialize(supply);
    });
IContainer container = configurador.Build();
IAudioOutput output = container.Resolve<IAudioOutput>();

O método Initialize será invocado automaticamente após a atificação da instância.

Tags: Autofac C# Injeção de Dependência Injeção de Propriedades Injeção de Métodos

Publicado em 6-1 13:23 por Thomas