コード例 #1
0
        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);
        }
コード例 #2
0
        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();
        }