There are probably more ways to do this since Windsor is ridiculously flexible, but here are three off the top of my head:
Option 1:
If IConfiguration
is a singleton or somehow can populate Name
without any other assistance, you could do the following:
container.Register(Component.For<IConfiguration>().ImplementedBy<Configuration>());
container.Register(Component
.For<Person>()
.DynamicParameters((DynamicParametersDelegate)ResolvePersonName));
// This should be a private method in your bootstrapper
void ResolvePersonName(IKernel kernel, IDictionary parameters)
{
parameters["name"] = kernel.Resolve<IConfiguration>().Name;
}
This method is invoked before resolving the Person
, and is setting the name
key/value pair to be the desired value. Windsor then uses this dictionary to override any dependencies in the constructor. I'd probably just make it a lambda to be terser:
.DynamicParameters((k,p) => p["name"] = k.Resolve<IConfiguration>().Name));
Option 2:
If the Name
value is actually defined in the applications settings file, Windsor has a built-in option for that:
container.Register(
Component.For<Person>()
.DependsOn(Dependency.OnAppSettingsValue("name", "configSettingKeyName")));
Option 3:
You say you don't want to use Typed Factories, but I think this is a reasonable siutation for using one. It wouldn't complicate the Person
class at all, but it would add a bit to the code creating the Person
objects (people?). Here's an example:
Define the factory interface:
public interface IPersonFactory
{
Person Create(string name);
}
Then where you are creating your Person
, inject the factory and use that instead:
public class PersonUser
{
public Personuser(IConfiguration configuration, IPersonFactory personFactory)
{
Person person = personFactory.Create(configuration.Name);
}
}
You'll have to add the facility and register the interface, but it's easy:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IPersonFactory>().AsFactory());