<PackageReference Include="Castle.Windsor" Version="6.0.0" />

DefaultComplexConverter

using Castle.Core.Configuration; using Castle.Core.Internal; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Globalization; using System.Reflection; namespace Castle.MicroKernel.SubSystems.Conversion { [Serializable] public class DefaultComplexConverter : AbstractTypeConverter { private IConversionManager conversionManager; private IConversionManager ConversionManager { get { if (conversionManager == null) conversionManager = base.Context.Kernel.GetConversionManager(); return conversionManager; } } public override bool CanHandleType(Type type) { return !type.GetTypeInfo().IsPrimitive; } public override object PerformConversion(IConfiguration configuration, Type targetType) { object obj = CreateInstance(targetType, configuration); ConvertPropertyValues(obj, targetType, configuration); return obj; } public override object PerformConversion(string value, Type targetType) { throw new NotImplementedException(); } private object CreateInstance(Type type, IConfiguration configuration) { type = ObtainImplementation(type, configuration); ConstructorInfo constructorInfo = ChooseConstructor(type); object[] ctorArgs = null; if (constructorInfo != (ConstructorInfo)null) ctorArgs = ConvertConstructorParameters(constructorInfo, configuration); return type.CreateInstance<object>(ctorArgs); } private Type ObtainImplementation(Type type, IConfiguration configuration) { string value = ((NameValueCollection)configuration.get_Attributes())["type"]; if (string.IsNullOrEmpty(value)) { if (type.GetTypeInfo().IsInterface) throw new ConverterException("A type attribute must be specified for interfaces"); return type; } Type type2 = base.Context.Composition.PerformConversion<Type>(value); if (!type.IsAssignableFrom(type2)) throw new ConverterException($"""{type2.FullName}""{type.FullName}"); return type2; } private ConstructorInfo ChooseConstructor(Type type) { ConstructorInfo constructorInfo = null; ConstructorInfo[] constructors = type.GetConstructors(); foreach (ConstructorInfo constructorInfo2 in constructors) { if (constructorInfo2.GetParameters().Length != 0) { if (constructorInfo != (ConstructorInfo)null) throw new ConverterException("Classes with more than one non-default constructor are not supported."); constructorInfo = constructorInfo2; } } return constructorInfo; } private object[] ConvertConstructorParameters(ConstructorInfo constructor, IConfiguration configuration) { IConversionManager conversionManager2 = ConversionManager; ParameterInfo[] parameters = constructor.GetParameters(); object[] array = new object[parameters.Length]; int i = 0; for (int num = parameters.Length; i < num; i++) { ParameterInfo parameterInfo = parameters[i]; IConfiguration val = FindChildIgnoreCase(configuration, parameterInfo.Name); if (val == null) throw new ConverterException($"""{parameterInfo.Name}""{configuration.get_Name()}"""); Type parameterType = parameterInfo.ParameterType; if (!ConversionManager.CanHandleType(parameterType)) throw new ConverterException($"""{parameterInfo.Name}""{configuration.get_Name()}""{parameterType.Name}"""); array[i] = ConvertChildParameter(val, parameterType); } return array; } private void ConvertPropertyValues(object instance, Type type, IConfiguration configuration) { IConversionManager conversionManager2 = ConversionManager; foreach (IConfiguration item in (List<IConfiguration>)configuration.get_Children()) { PropertyInfo property = type.GetProperty(item.get_Name(), BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (!(property == (PropertyInfo)null) && property.CanWrite) { Type propertyType = property.PropertyType; if (!ConversionManager.CanHandleType(propertyType)) throw new ConverterException($"""{property.Name}""{configuration.get_Name()}""{propertyType.Name}"""); object value = ConvertChildParameter(item, propertyType); property.SetValue(instance, value, null); } } } private object ConvertChildParameter(IConfiguration config, Type type) { if (config.get_Value() == null && ((List<IConfiguration>)config.get_Children()).Count != 0) return base.Context.Composition.PerformConversion(config, type); return base.Context.Composition.PerformConversion(config.get_Value(), type); } private IConfiguration FindChildIgnoreCase(IConfiguration config, string name) { foreach (IConfiguration item in (List<IConfiguration>)config.get_Children()) { if (CultureInfo.CurrentCulture.CompareInfo.Compare(item.get_Name(), name, CompareOptions.IgnoreCase) == 0) return item; } return null; } } }