One approach you could use is to replace the configuration parameters inspector with your own variant that can introduce some additional behaviour - here's a quick prototype:
public class ExtendedConfigurationParametersInspector : IContributeComponentModelConstruction
{
#region IContributeComponentModelConstruction Members
public virtual void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Configuration == null) return;
IConfiguration parameters = model.Configuration.Children["parameters"];
if (parameters == null) return;
foreach (IConfiguration parameter in parameters.Children)
{
String name = parameter.Name;
String value = parameter.Value;
if (value == null && parameter.Children.Count != 0)
{
IConfiguration parameterValue = parameter.Children[0];
model.Parameters.Add(name, parameterValue);
}
else
{
if (parameter.Attributes["type"] == "static")
{
int lastIndex = parameter.Value.LastIndexOf(".");
string typeName = parameter.Value.Substring(0, lastIndex);
string field = parameter.Value.Substring(lastIndex + 1);
Type ownerType = Type.GetType(typeName);
FieldInfo valueField = ownerType.GetField(field);
value = (string) valueField.GetValue(null);
}
model.Parameters.Add(name, value);
}
}
foreach (ParameterModel parameter in model.Parameters)
{
if (parameter.Value == null || !ReferenceExpressionUtil.IsReference(parameter.Value))
{
continue;
}
String newKey = ReferenceExpressionUtil.ExtractComponentKey(parameter.Value);
model.Dependencies.Add(new DependencyModel(DependencyType.ServiceOverride, newKey, null, false));
}
}
#endregion
}
public class ExtendedComponentBuilder : DefaultComponentModelBuilder
{
public ExtendedComponentBuilder(IKernel kernel) : base(kernel)
{
}
protected override void InitializeContributors()
{
AddContributor(new GenericInspector());
AddContributor(new ConfigurationModelInspector());
AddContributor(new ExtendedConfigurationParametersInspector());
AddContributor(new LifestyleModelInspector());
AddContributor(new ConstructorDependenciesModelInspector());
AddContributor(new PropertiesDependenciesModelInspector());
AddContributor(new LifecycleModelInspector());
AddContributor(new InterceptorInspector());
AddContributor(new ComponentActivatorInspector());
AddContributor(new ComponentProxyInspector());
}
}
public class ExtendedWindsorContainer : WindsorContainer
{
public ExtendedWindsorContainer(IConfigurationInterpreter interpreter)
: base(CreateKernel(), new Castle.Windsor.Installer.DefaultComponentInstaller())
{
if (interpreter == null) throw new ArgumentNullException("interpreter");
interpreter.ProcessResource(interpreter.Source, Kernel.ConfigurationStore);
RunInstaller();
}
private static IKernel CreateKernel()
{
DefaultKernel kernel = new DefaultKernel();
kernel.ComponentModelBuilder = new ExtendedComponentBuilder(kernel);
return kernel;
}
}
You could then wire up the properties in your container like so, where specifying a type of "static" for the parameter would cause the value to be replaced with the static field that was referenced by the parameters value.
<castle>
<components>
<component id="test"
type="SomeNamespace.TestComponent,Example">
<parameters>
<value type="static">SomeNamespace.SomeClass.TheStaticFieldValue</value>
</parameters>
</component>
</components>
</castle>
Unfortunately you generally can't do this through simpler means (such as the model created kernel event) due to the fact that parameters in the component model are immutable.