Misleading "Could Not Locate Dependency" message in Composite UI Block

The project that I have been working on for a number of months uses the Composite UI Application Block (CAB) as the basis for the user interface. If you have never worked with CAB before, it is an interesting framework. In many ways it makes tasks easy that would be incredibly challenging otherwise. This includes the ability to add and remove elements from the user interface by simply adding or removing lines from an XML file. On the other hand, there are parts of CAB that appear to work as if by magic.

One of the 'magic' pieces is dependency injection. As a smart part (the name of the UI element that is part of the composition process) is loaded, the presenter (CAB supports a model-view-presenter pattern) is instantiated with some number of parameters passed into the constructor. The cool feature is that the value of any one of the parameters can be 'injected' into CAB by marking the parameter as follows.

public DemoPresenter([ServiceDependency] WorkItem workItem,
   [ComponentDependency("Target")] string injectedParameter)

In this declaration, the injectedParameter value is taken from the Target item in the work item and automatically passed into the constructor. Someplace earlier (and, in fact, even in another component), someone had to execute the code.

string valueOfInterest = "Hello";
WorkItem.Items.Add(valueOfInterest, "Target");

While this might seem a little convoluted, in the world of composite UI, this injection technique allows disparate components to easily share context.

So much for the background and on to the problem. I had created a presenter constructor that took a parameter of type NamedObject. As well, the ComponentDependency attribute specified that the "Target" item in the work item should be passed in. In the place where the object was added to the WorkItem.Items collection, I instantiated an object of type Profile, where the Profile class derives from the NamedObject class. I added the Profile object to my Items collection with a key of "Target". I expected that the dependency injection mechanism to retrieve the Target item and pass it into the presenter constructor. Instead, I received an "Unable to locate dependency 'NamedObject'" exception being raised.

After digging deep into the injection process, specifically into the ObjectBuilder methods within the CAB project. It turns out that the matching process used by dependency injection is not based solely onthe key passed into the Items.Add method. It is also includes the type of the item. In other words,  the ObjectBuilder not only looks to find an item called "Target", it also ensures that the type of the item matches. And, to make it more annoying, the ObjectBuilder doesn't understand hierarchy. So even though my item was of type Profile, which is a NamedObject (due to the inheritance), the ObjectBuilder says that there was no match and threw an exception.

The solution to this problem (other than to modify how ObjectBuilder performs its matching...a daunting task to say the least) is to extract the item out of the work item directly. There are reasons for wanting to avoid this (there are actually more than one Items collection which can contain the injected value), but it worked in my situation. But I still have a gripe with the message. It's not truly misleading, as ObjectBuilder couldn't find a dependency of the indicated type. However, the message does require a deep understanding of how ObjectBuilder does its thing, and that is a strike against the message in my book.