- 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.
- 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.
- 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.