示例#1
0
        /// <summary>
        /// Gets a list of ConfigFields for the given type
        /// </summary>
        /// <param name="TargetObjectType">Type to get configurable fields for</param>
        /// <returns>List of config fields for the given type</returns>
        static List <ConfigField> FindConfigFieldsForType(Type TargetObjectType)
        {
            List <ConfigField> Fields;

            lock (TypeToConfigFields)
            {
                if (!TypeToConfigFields.TryGetValue(TargetObjectType, out Fields))
                {
                    Fields = new List <ConfigField>();
                    if (TargetObjectType.BaseType != null)
                    {
                        Fields.AddRange(FindConfigFieldsForType(TargetObjectType.BaseType));
                    }
                    foreach (FieldInfo FieldInfo in TargetObjectType.GetFields(BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
                    {
                        IEnumerable <ConfigFileAttribute> Attributes = FieldInfo.GetCustomAttributes <ConfigFileAttribute>();
                        foreach (ConfigFileAttribute Attribute in Attributes)
                        {
                            // Copy the field
                            ConfigField Setter = new ConfigField();
                            Setter.FieldInfo = FieldInfo;
                            Setter.Attribute = Attribute;

                            // Check if the field type implements ICollection<>. If so, we can take multiple values.
                            foreach (Type InterfaceType in FieldInfo.FieldType.GetInterfaces())
                            {
                                if (InterfaceType.IsGenericType && InterfaceType.GetGenericTypeDefinition() == typeof(ICollection <>))
                                {
                                    MethodInfo MethodInfo = InterfaceType.GetRuntimeMethod("Add", new Type[] { InterfaceType.GenericTypeArguments[0] });
                                    Setter.AddElement  = (Target, Value) => { MethodInfo.Invoke(Setter.FieldInfo.GetValue(Target), new object[] { Value }); };
                                    Setter.ElementType = InterfaceType.GenericTypeArguments[0];
                                    break;
                                }
                            }

                            // Add it to the output list
                            Fields.Add(Setter);
                        }
                    }
                    TypeToConfigFields.Add(TargetObjectType, Fields);
                }
            }
            return(Fields);
        }