Configuration for Complex (Deep) Objects

Mar 26, 2008 at 2:58 PM
Edited Mar 26, 2008 at 3:11 PM
Is it possible to configure the injection for the following graph:

public interface IFoo {}
public interface IBar {}
 
public class Bar : IBar 
{
  public Bar(int number) { Number = number; }
  public int Number { get; set; }
}
 
public class Foo
{
  public Foo(IBar bar) { Bar = bar; }
  public IBar Bar { get; set; }
}

Let's say I want to allow 2 different IFoo to be configured so that the following test passes:

IFoo foo1 = container.Resolve<IFoo>("Foo1");
IFoo foo2 = container.Resolve<IFoo>("Foo2");
Assert.Equal(1, foo1.Bar.Number;
Assert.Equal(2, foo2.Bar.Number);

So my config would look something like:

<types>
   <type type="IFoo" name="Foo1" mapTo="Foo">
      <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
        <constructor>
          <param name="bar" parameterType="IBar">
            <value>
              <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
                <constructor>
                  <param name="number" parameterType="int">
                    <value value="1">
                  </param>
                </constructor>
              </typeConfig>
            </value>
          </param>
        </constructor>
      </typeConfig>
    </type>
   <type type="IFoo" name="Foo2" mapTo="Foo">
      <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
        <constructor>
          <param name="bar" parameterType="IBar">
            <value>
              <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
                <constructor>
                  <param name="number" parameterType="int">
                    <value value="2"> <!-- Here lies the difference-->
                  </param>
                </constructor>
              </typeConfig>
            </value>
          </param>
        </constructor>
      </typeConfig>
    </type>
</types>

Note I don't want to define both IBar outside the scope of IFoo as they are really contextual (imagine a deep graph) to the object being built.

I imagine it can be solved by defining a new InjectionParameterValueElement-derived class that has a typeConfig nested element?

Thoughts?

Update: After thinking about it, I'm not even sure the underlying model supports that directly. We'd need a new InjectionParameterValue-derived class.
Mar 26, 2008 at 4:17 PM
I was also thinking of something like this earlier today. What is the recommended guidance for injecting properties that are collections and are contextual to just the target object? Having this ability would be cool (but I have the same feeling as you that it will require a new configuration class)...