Configuring injection looks like this:

container.Configure<InjectedMembers>()
.ConfigureInjectionFor<Foo>(
new InjectionConstructor(12, "Hello"),
new InjectionProperty("MyProperty"),
new InjectionProperty("MyStringProperty", "nifty"),
new InjectionMethod("InitializeMe", 42.0, new ResolvedParameter(typeof(ILogger), "SpecialLogger"));

So what does that do?

The "InjectionConstructor" line says "call the constructor that takes an int and a string. Pass 12 for the int, and "Hello for the string".

The InjectionProperty lines configure properties to be injected. The first one say to inject the MyProperty property. Resolve the value for this property through the container. The second line says to inject MyStringProperty, and pass "nifty" as the value.

Finally, the InjectionMethod line configures the "InitializeMe" method to be injected. It will look for one that takes a double and an ILogger. The value 42.0 will be passed to the double, and the ResolvedParameter object says to resolve the logger through the container, and do Resolve<ILogger>("SpecialLogger").

The API style was inspired by the functional construction approach used in the Linq to XML stuff in VS 2008. The intent was to provide sufficient flexibility, while still making the easy stuff easy.

The API lets you pass arbitrary objects to the various constructors, and there is a small set of rules for how to handle them. The implementation is in the InjectionParameterValue.ToParameter method, if you want to look at the code. The rules are: if the object is an instance of InjectionParameterValue, then just use that. If the object is of type Type, then create a ResolvedParameter, so that the container will be used to resolve an instance of that type. Otherwise, create an InjectionParameter object, which says that "container, use this value".

For extensibility, you can create new InjectionMember types to do whatever you want (InjectionConstructor, InjectionProperty, and InjectionMethod are subclasses of InjectionMember). You can create new InjectionParameterValue objects to customize the handling of individual parameters.

There's a great deal of flexibility here in a small number of objects. Please let us know what you think!

Last edited Mar 13, 2008 at 1:24 AM by ctavares, version 1