Complex Build Keys

Feb 26, 2008 at 11:13 PM
Let's say I want to register a policy for a type being build in the context of the ctor of another type being built:

public class Bar
{
  public Bar(ILogger logger) { ... }
}
 
public class Foo
{
  public Foo(Bar bar) { ... }
}

So here what I basically want to do, is define a policy for the "bar" being built when a Foo is being built. It is quite plausible that another "bar" could be built in the context of "zaz".

When comes time to define my policy, I cannot simply register it for "Bar", I need to register it for "Bar" + "bar" parameterInfo of the Foo ctor. During the workshop we defined such a buildKey (KeyValuePair<...>).

However, it is recursive: Foo might actually be built in the context of A and in the context of B, hence two potentially different configurations.

I'm not sure if I'm on the right track, but I believe that it it is easier to assemble complex build keys, it is soon going to be a good think as I don't see myself defining KeyValuePair<PropertyInfo, KeyValuePair<PropertyInfo, object>> buildKey = ...

Or, I just wait until you get the config right and I start complaining just then ;)
Feb 27, 2008 at 2:17 AM
Actually register the policy in the ConstructorSelectorPolicy, not from outside. See the current code for an example.

It's not ideal, but I think it's the best we're going to get since we can't easily generate IL to put arbitrary objects on the stack, as we ran into at the workshop.

The current implementation uses completely synthetic keys (actually, they're guids converted to strings) to look up the resolvers for each parameter. It's a little bit of a hack, but it turns out to work really well.
Feb 27, 2008 at 3:07 AM
Oh cool! I didn't notice you had all that done already... .

I'll give it a thourough look and come back to you.
Feb 28, 2008 at 3:08 AM
Ok I've seen what you've done.

I'll try to rephrase using the new naming:

When planning to support configuration, it is important to note that a "SelectedConstructor" might exist in the scope of a "parent SelectedConstructor". That is, if we're to provide values (probably another implementation of IDependencyResolver) through config, we need to register ctor parameter key based on the parent selected ctor as well:

class Foo
{
  public Foo(int i) { ... }
}
 
class Bar
{
  public Bar(Foo foo) { ... }
}
 
class Zaz
{
  public Zaz(Foo foo) { ... }
}

The Foo ctor when building a Bar and when building a Zaz might receive different values for the "i" parameter.

But I think I'll have to wait what you come up with for the config first because I can't remember exactly how we addressed it during the workshop.