views:

2119

answers:

3

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.

+1  A: 

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/

Kim Major
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.
LittleBoyLost
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.
Kim Major
+4  A: 

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>()));
t3mujin
+1  A: 

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

Johan Leino