Nov 20, 2006 at 1:48 PM
I'm currently trying to get my head around ObjectBuilder's internals in the hopes I can use it as the foundation for a dependency injection container I'm creating. I've run into something that confused me, and I hope someone here can clear it up. I've tagged a "contract" interface, ISimpleObject, with a DependencyAttribute like so:

public interface ISimpleObject
IUsefulService UsefulService { get; set; }

When I attempt to create a concrete instance of this type, OB doesn't inject the IUsefulService instance as I would expect. The PropertyReflectionStrategy correctly captures the DependencyAttribute and creates a PropertySetterPolicy, but then when the PropertySetterStrategy is run, it doesn't inject the property.

As far as I can tell this is because the property on the interface is attributed, but in the InjectProperties() method of PropertySetterStrategy, GetType() is called on the existing object. Then, the policy is looked up using a BuilderPolicyKey that involves the concrete type rather than the interface type.

This leads to a couple of questions:

1. Is this the intended behavior? If so, why?
2. Why doesn't InjectProperties in PropertySetterStrategy use the typeToBuild parameter that's passed in through the BuildUp call?

I'm sure I'm probably just missing something... is there another way to accomplish what I'm trying to do?

Nate Kohari
Nov 20, 2006 at 3:26 PM
The behavior you're seeing is as intended, although you could easily change it by changing the order of the strategies.

The type mapping strategy is coming before the reflection strategies, so the IFoo has been changed to the concrete Foo before the reflection is run. If you move the reflection strategies before the type mapping strategies, then it will reflect based on the interface, not the concrete type.

Bear in mind what this means, though: the ONLY attributes it will read will be those that it sees on the interface, and not the concrete type. You will no longer be able to put the attributes on the classes themselves, because the reflection won't see them.

We made the choice to read the concrete classes rather than the interfaces, because that seemed like the overwhelmingly common case.
Nov 20, 2006 at 5:06 PM
Gotcha. Thanks for the response. I understand why you guys implemented it this way, and I definitely agree that decorating the concrete type is more common than decorating the interface. I'm working with a different set of parameters -- for example, objects that are added to the DI container can be COM components, so I can only guarantee that I have access to decorate the interface type. I've been able to make it do what I need by removing the TypeMappingStrategy from the chain and replacing it with my own FactoryGeneratedObjectStrategy, which is more in-tune with my requirements. I'll see if I can add it back in the manner you described to open the possibility up for constructor injection.

Thanks again!