Пример #1
0
        public void ComplexGenericType()
        {
            var type = CachedType.Get(typeof(Dictionary <string, HashSet <List <string> > >));

            Assert.Equal("Dictionary<String, HashSet<List<String>>>", type.Name);
            Assert.True(type.HasCollectionProperties);
        }
Пример #2
0
        public void GenericTypeTest()
        {
            var type = CachedType.Get(typeof(List <string>));

            Assert.Equal("List<String>", type.Name);
            Assert.False(type.HasCollectionProperties);
        }
Пример #3
0
        public void StringTypeTest()
        {
            var type = CachedType.Get(typeof(string));

            Assert.Equal("String", type.Name);
            Assert.False(type.HasCollectionProperties);
        }
Пример #4
0
        public void NoCollectionTypeTest()
        {
            var type = CachedType.Get(typeof(NoCollectionContainer));

            Assert.Equal("NoCollectionContainer", type.Name);
            Assert.False(type.HasCollectionProperties);
            Assert.True(type.HasProperty("MyValue"));
            Assert.False(type.HasProperty("Property"));
        }
Пример #5
0
        public void CollectionTypeTest()
        {
            var type = CachedType.Get(typeof(CollectionContainer));

            Assert.Equal("CollectionContainer", type.Name);
            Assert.True(type.HasCollectionProperties);
            Assert.True(type.HasProperty("Property"));
            Assert.False(type.HasProperty("AnotherProperty"));
        }
Пример #6
0
        /// <summary>
        ///     Reads the configuration and populates the given instance (or newly created one) properties according to it.<br />
        ///     By default if the instance type has a property, it is considered as mandatory in configuration and value in
        ///     configuration
        ///     should be valid.<br />
        ///     Use <see cref="PropertyConfigurationAttribute" /> or <see cref="IgnoredPropertyAttribute" />
        ///     to changed that behavior.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance">The instance.</param>
        /// <returns></returns>
        /// <exception cref="MissingMandatoryConfigurationException"></exception>
        public T Read <T>(T instance) where T : class
        {
            var type        = CachedType.Get(typeof(T));
            var sectionName = GetSectionName(type);
            var section     = _configuration.GetSection(sectionName);

            if (section == null)
            {
                throw new InvalidOperationException("IConfiguration should never return null section by contract.");
            }
            // If section doesn't exists should throw or at least warn ?
            foreach (var property in type.GetProperties())
            {
                SetPropertyValue(instance, property, section);
            }
            return(instance);
        }
Пример #7
0
        protected Saveable(string saveKey)
        {
            if (saveKey.Length > KeyAttribute.MaxKeyLength)
            {
                throw new Exception($"Saveable key max length={KeyAttribute.MaxKeyLength} ({saveKey})");
            }

            IsModified         = false;
            SaveableProperties = new Dictionary <string, CachedProperty>();
            SaveKey            = saveKey;
            var cachedType = CachedType.Get(GetType());

            foreach (var cachedProperty in cachedType.CachedProperties)
            {
                if (cachedProperty.PropertyInfo.PropertyType.BaseType == null ||
                    cachedProperty.PropertyInfo.PropertyType.IsPrimitive ||
                    cachedProperty.PropertyInfo.PropertyType.IsClass == false ||
                    cachedProperty.PropertyInfo.PropertyType.IsValueType)
                {
                    continue;
                }

                if (cachedProperty.PropertyInfo.PropertyType.IsArray)
                {
                    Debug.LogWarning($"[mSaves] Property '{cachedProperty.PropertyInfo.Name}' in '{cachedType.Type.Name}' is array, skipped");
                    continue;
                }

                if (!cachedProperty.PropertyInfo.PropertyType.BaseType.IsGenericType)
                {
                    continue;
                }

                var enumerable = cachedProperty.PropertyInfo.GetCustomAttributes();
                var attributes = enumerable as Attribute[] ?? enumerable.ToArray();

                if (!IsSaveableValue(cachedProperty.PropertyInfo))
                {
                    // ReSharper disable once PossibleNullReferenceException
                    var genericDefenition = cachedProperty.PropertyInfo.PropertyType.BaseType
                                            .GetGenericTypeDefinition();

                    if (genericDefenition == typeof(SaveableValue <>))
                    {
                        var constructor = cachedProperty.PropertyInfo.PropertyType.GetConstructor(
                            BindingFlags.Instance |
                            BindingFlags.Public, null, Type.EmptyTypes, null);

                        if (constructor != null)
                        {
                            var expression = Expression.New(constructor);
                            var func       = (Func <SaveableValue>)Expression
                                             .Lambda(expression)
                                             .Compile();
                            _saveableValueTypes.Add(cachedProperty.PropertyInfo.PropertyType, func);
                        }
                        else
                        {
                            throw new Exception("SaveableValue must have public constructor without parameters");
                        }
                    }
                    else
                    {
                        continue;
                    }
                }

                if (attributes.OfType <IgnoreAttribute>().Any())
                {
                    Debug.Log($"[mSaves] Property '{cachedProperty.PropertyInfo.Name}' in '{cachedType.Type.Name}' marked as Ignore attribute");
                    continue;
                }

                var keyAttribute = attributes.OfType <KeyAttribute>().FirstOrDefault();
                if (keyAttribute == null)
                {
                    throw new Exception($"[mSaves] Property '{cachedProperty.PropertyInfo.Name}' in '{cachedType.Type.Name}' not have a Key attribute");
                }

                if (SaveableProperties.ContainsKey(keyAttribute.Key))
                {
                    throw new Exception($"[mSaves] Key {keyAttribute.Key} already exist");
                }

                if (cachedProperty.PropertyInfo.CanWrite)
                {
                    cachedProperty.SetValue(this,
                                            cachedProperty.GetValue(this) as SaveableValue ??
                                            _saveableValueTypes[cachedProperty.PropertyInfo.PropertyType]()
                                            );
                }

                SaveableProperties.Add(keyAttribute.Key, cachedProperty);

                //Debug.Log(string.Join("\n", new[]
                //{
                //    $"cachedProperty Name={cachedProperty.PropertyInfo.Name}",
                //    $"Value={cachedProperty.GetValue(this)} ({cachedProperty.GetValue(this)?.GetType().Name ?? "null"})",
                //    $"Type={cachedProperty.PropertyInfo.PropertyType.Name}",
                //    $"BaseType ={cachedProperty.PropertyInfo.PropertyType.BaseType}",
                //    $"HasElementType ={cachedProperty.PropertyInfo.PropertyType.HasElementType}",
                //    $"attributes = {attributes.Select(a => a.GetType().Name).Aggregate((a, b) => a + "," + b)}",
                //}));
            }
        }