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); }
public void GenericTypeTest() { var type = CachedType.Get(typeof(List <string>)); Assert.Equal("List<String>", type.Name); Assert.False(type.HasCollectionProperties); }
public void StringTypeTest() { var type = CachedType.Get(typeof(string)); Assert.Equal("String", type.Name); Assert.False(type.HasCollectionProperties); }
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")); }
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")); }
/// <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); }
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)}", //})); } }