Property injection with Unity

1.7k views Asked by At

i encoutered problem with unity, i want to use property injection, here is what i had in my code : config of the container :

public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<GTModelContainer, GTModelContainer>(new HttpContextLifetimeManager<GTModelContainer>())
                 .RegisterType<IUnitOfWork, UnitOfWorkGT>()
                 .RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager())                     
                 .RegisterType<ISocieteServices, SocieteServices>() ;
 }

SocieteService Class :

 public class SocieteServices : ISocieteServices
{
    private IUnitOfWork UnitOfWork;

    public SocieteServices(IUnitOfWork unitOfWork)
    {
        UnitOfWork = unitOfWork;
    }

}

i tried to use property injection (i can't use constructor injection with custom data annotation) and here what i had done :

   public class CodeSocieteUniqueAttribute : ValidationAttribute
{
     [Dependency]
    public ISocieteServices SocieteService {get; set;} 

     [InjectionMethod]
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {

        string codeSociete = value as string;

        var societe = SocieteService.getSocieteByCode(codeSociete);
        if (societe == null) return ValidationResult.Success;
        else return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));

    }
}

the problem is that the societeService in CodeSocieteUniqueAttribute class is not injected.

1

There are 1 answers

2
brenton On BEST ANSWER

Assuming that your class for registering types is publicly accessible and has a IUnityContainer object, ie:

public static class Resolver
{

    public static IUnityContainer Container { get; set; }
    public static void RegisterTypes(IUnityContainer container)
    {
        // type registrations here
        container.RegisterType<GTModelContainer, GTModelContainer>(new HttpContextLifetimeManager<GTModelContainer>())
             .RegisterType<IUnitOfWork, UnitOfWorkGT>()
             .RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager())                     
             .RegisterType<ISocieteServices, SocieteServices>() ;

        // Now, set the container
        Container = container;
    }
}

You could access the container you've built up and resolve these types during method execution.

For instance,

public class CodeSocieteUniqueAttribute : ValidationAttribute
{
     [Dependency]
    public ISocieteServices SocieteService { get; set; } 

     [InjectionMethod]
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var societeServices = Resolver.Container.Resolve<ISocieteServices>();
        SocieteService = societeServices; // Or, you know, just use this since it's resolved.
        string codeSociete = value as string;

        var societe = SocieteService.getSocieteByCode(codeSociete);
        if (societe == null) return ValidationResult.Success;
        else return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));

    }
}

This is actually pretty standard practice, and this MSDN article describes resolving items during runtime.

Another option is to pop the resolution into a default constructor like this:

public class CodeSocieteUniqueAttribute : ValidationAttribute
{
    [Dependency]
    public ISocieteServices SocieteService {get; set;} 
    public CodeSocieteUniqueAttribute()
    {
        var societeServices = Resolver.Container.Resolve<ISocieteServices>();
        SocieteService = societeServices; 
    }
     // the rest of the class omitted for brevity
}