Wednesday, March 30, 2011

Setter / property injection in Unity without attributes

I am working on a project where the Unity framework is used as the IoC container. My question relates to injecting an optional dependency (in this case a logger) into several classes using property- or setter injection.

I do not want to clutter the constructors of all my classes with these optional dependencies, but I cannot find a good way to handle this in Unity. The way you would do this is, according to the MSDN documentation, by adding an attribute to the property:

private ILogger logger; 

[Dependency]
public ILogger Logger
{
get { return logger; }
  set { logger = value; }
}

I find this very ugly. In StructureMap one could do the following to set all properties of a given type:

SetAllProperties(policy => policy.OfType<ILog>());

Does anyone know if it is possible to do something similar in Unity?

Edit:

Kim Major suggests using this approach which can also be achieved through code.

I would be interested in examples of how to do this automatically for all matching properties.

From stackoverflow
  • The following walkthrough shows one way of doing it through configuration. You can of course wire it through code as well. http://aardvarkblogs.wordpress.com/unity-container-tutorials/10-setter-injection/

    LittleBoyLost : Thank you for the tip. I guess I can use this as a fallback solution, but as far as I can see this requires you to create a setup for each class that uses the logger. I wondered if it was a way to just specify this once, so that all classes using the logger would be automatically injected.
    Kim Major : I haven't tried the following so I'm not sure. I think you should be able to register all your classes. Then reflect over the registered classes and add the setter injection registration if the type has an ILogger Setter.
  • I don't like those attributes also

    You can do all using the Configure method of the unity container:

    First register the type

    unityContainer.RegisterType<MyInterface,MyImpl>(
                         new ContainerControlledLifetimeManager());
    

    If you have multiple constructors you'll have to to this so Unity invokes the parameterless constructor (if none set Unity will go for the fattest one)

    unityContainer.Configure<InjectedMembers>()
                                .ConfigureInjectionFor<MyImpl>(
                                    new InjectionConstructor());
    

    Setting property dependency

    unityContainer.Configure<InjectedMembers>()
                        .ConfigureInjectionFor<MyImpl>(
                             new InjectionProperty(
                                 "SomePropertyName",
                                    new ResolvedParameter<MyOtherInterface>()));
    

    Configuring method dependency

    unityContainer.Configure<InjectedMembers>()
                        .ConfigureInjectionFor<MyImpl>(
                            new InjectionMethod(
                                "SomeMethodName",
                                new ResolvedParameter<YetAnotherInterface>()));
    
  • You could try this:

    this code in MyClass

    [InjectionMethod]
    public void Initialize(
                     [Dependency] ILogger logger
    

    and then calling it by:

    unitycontainer.BuildUp<MyClass>(new MyClass());
    

    unity will then call Initialize method with the dependency from the container and then u can save it in a private variable in MyClass or something...

0 comments:

Post a Comment