I want to perform this CODE equivlant in the castle xml config file.
// Foo(string name)
IFoo f = new Foo(StaticBarClass.Name);
XML
Now for the XML, I know everything (e.g. the blah) except for the stuff inside the parameter part.
What would the parameter part look like?
<component id="blah"
service="blah"
type="blah">
<parameters>
<name>StaticBarClas.Name_THAT_I_NEED_HELP_WITH</name>
</parameters>
-
You can't set it up like that from xml alone. But you could use the factory facility to do this.
-
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.
0 comments:
Post a Comment