private static Func <string, object> GetParse(MemberInfo info, Type type) { ConvertAttribute convertAttr = info.GetCustomAttribute <ConvertAttribute>(); if (convertAttr != null) { const BindingFlags flags = BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public; MethodInfo convertMth = convertAttr.Type.GetMethod(convertAttr.ParseMethodName, flags, null, CallingConventions.Any, new[] { typeof(string) }, new ParameterModifier[0]); if (convertMth != null) { return(s => convertMth.Invoke(null, new object[] { s })); } } Func <string, object> convert = PackConverter.Instance.GetParse(type); if (convert != null) { return(convert); } throw new Exception("Cannot convert from string to " + type); }
private void BuildConverters() { log.Info("Initialising command parameters converters..."); var factoryBuilder = ImmutableDictionary.CreateBuilder <Type, ParameterConverterFactoryDelegate>(); var defaultBuilder = ImmutableDictionary.CreateBuilder <Type, Type>(); foreach (Type type in Assembly.GetExecutingAssembly().GetTypes()) { if (!typeof(IParameterConvert).IsAssignableFrom(type)) { continue; } ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); if (constructor == null) { continue; } // generic converters are a special case that need handling from the parameter attribute // at this point we have no idea what the generic parameter replacements should be if (type.IsGenericTypeDefinition) { continue; } NewExpression @new = Expression.New(constructor); factoryBuilder.Add(type, Expression.Lambda <ParameterConverterFactoryDelegate>(@new).Compile()); // ConvertAttribute will specify the default type the converter is for ConvertAttribute attribute = type.GetCustomAttribute <ConvertAttribute>(); if (attribute != null) { defaultBuilder.Add(attribute.Type, type); } } // special case for generic converters foreach (MethodInfo method in Assembly.GetExecutingAssembly() .GetTypes() .SelectMany(t => t.GetMethods())) { CommandAttribute attribute = method.GetCustomAttribute <CommandAttribute>(); if (attribute == null) { continue; } foreach (ParameterInfo parameter in method.GetParameters()) { ParameterAttribute parameterAttribute = parameter.GetCustomAttribute <ParameterAttribute>(); if (parameterAttribute == null) { continue; } if (!parameterAttribute.Converter?.IsGenericType ?? true) { continue; } ConstructorInfo constructor = parameterAttribute.Converter.GetConstructor(Type.EmptyTypes); if (constructor == null) { continue; } if (factoryBuilder.ContainsKey(parameterAttribute.Converter)) { continue; } NewExpression @new = Expression.New(constructor); factoryBuilder.Add(parameterAttribute.Converter, Expression.Lambda <ParameterConverterFactoryDelegate>(@new).Compile()); } } converterFactories = factoryBuilder.ToImmutable(); defaultConverterFactories = defaultBuilder.ToImmutable(); }