コード例 #1
0
        /// <summary>
        /// Loads configuration to given Class type
        /// </summary>
        /// <typeparam name="T">Target class</typeparam>
        /// <param name="config">Configuration</param>
        /// <returns>Class, filled with configuration values oe null</returns>
        public static T LoadToClass <T>(ConfigValue config)
            where T : class, new()
        {
            if (config == null)
            {
                return(null);
            }

            if (typeof(T).GetInterfaces().Contains(typeof(ICollection)))
            {
                return(LoadToCollectionWrap <T>(config));
            }

            var instance = new T();

            foreach (var field in typeof(T).GetFields())
            {
                var dataSourceAttribute = field.GetCustomAttribute <ConfigDataSourceAttribute>();
                var path = dataSourceAttribute?.DataPath
                           ?? field.Name.ToLowerInvariant();

                if (!config.ContainsPath(path))
                {
                    // Skipping not relevant fields
                    continue;
                }

                if (field.FieldType.GetTypeInfo().IsPrimitive ||
                    field.FieldType.GetConstructor(Type.EmptyTypes) == null)
                {
                    var configValue     = config.GetByPath(path);
                    var genericAsCustom =
                        configValue.AsConfigList().Count == 1
                            ? MethodAsCustom.MakeGenericMethod(field.FieldType)
                            : MethodAsCustomFromRaw.MakeGenericMethod(field.FieldType);

                    var value = genericAsCustom.Invoke(configValue, null);

                    field.SetValue(instance, value);
                }
                else
                {
                    var fieldType = field.FieldType;

                    var typeSource = field.GetCustomAttribute <ConfigDataTypeSourceAttribute>();
                    var typeName   =
                        config.GetByPath(typeSource?.DataPath)
                        ?.AsString()
                        ?.ToLowerInvariant();
                    if (typeName != null)
                    {
                        var mapping = field.GetCustomAttributes <ConfigDataTypeMappingAttribute>();
                        fieldType = mapping
                                    ?.FirstOrDefault(attr => attr.TypeName == typeName)
                                    ?.FieldType
                                    ?? Assembly
                                    .GetEntryAssembly()
                                    .GetTypes()
                                    .Where(t => field.FieldType.IsAssignableFrom(t))
                                    .FirstOrDefault(t => t.Name.ToLowerInvariant() == typeName)
                                    ?? throw new TypeLoadException(
                                              $"Can not find type with name '{typeName}'"
                                              );
                    }

                    var genericLoadToClass = MethodLoadToClass.MakeGenericMethod(fieldType);
                    var innerInstance      = genericLoadToClass.Invoke(null, new object[] { config.GetByPath(path) });
                    field.SetValue(instance, innerInstance);
                }
            }

            return(instance);
        }