Example #1
0
        public IPropertyBag <TContainer> CreatePropertyBag <TContainer>()
        {
            if (!RuntimeTypeInfoCache <TContainer> .IsContainerType || RuntimeTypeInfoCache <TContainer> .IsObjectType)
            {
                throw new InvalidOperationException("Invalid container type.");
            }

            if (typeof(TContainer).IsArray)
            {
                if (typeof(TContainer).GetArrayRank() != 1)
                {
                    throw new InvalidOperationException("Properties does not support multidimensional arrays.");
                }

                return((IPropertyBag <TContainer>)m_CreateListPropertyBagMethod.MakeGenericMethod(typeof(TContainer), typeof(TContainer).GetElementType()).Invoke(this, new object[0]));
            }

            if (typeof(TContainer).IsGenericType && (typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(List <>)) || typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(IList <>))))
            {
                return((IPropertyBag <TContainer>)m_CreateListPropertyBagMethod.MakeGenericMethod(typeof(TContainer), typeof(TContainer).GetGenericArguments().First()).Invoke(this, new object[0]));
            }

            if (typeof(TContainer).IsGenericType && (typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(HashSet <>)) || typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(ISet <>))))
            {
                return((IPropertyBag <TContainer>)m_CreateSetPropertyBagMethod.MakeGenericMethod(typeof(TContainer), typeof(TContainer).GetGenericArguments().First()).Invoke(this, new object[0]));
            }

            if (typeof(TContainer).IsGenericType && (typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary <,>)) || typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(IDictionary <,>))))
            {
                var types = typeof(TContainer).GetGenericArguments().ToArray();
                return((IPropertyBag <TContainer>)m_CreateDictionaryPropertyBagMethod.MakeGenericMethod(typeof(TContainer), types[0], types[1]).Invoke(this, new object[0]));
            }

            if (typeof(TContainer).IsGenericType && typeof(TContainer).GetGenericTypeDefinition().IsAssignableFrom(typeof(KeyValuePair <,>)))
            {
                var types = typeof(TContainer).GetGenericArguments().ToArray();
                return((IPropertyBag <TContainer>)m_CreateKeyValuePairPropertyBagMethod.MakeGenericMethod(types[0], types[1]).Invoke(this, new object[0]));
            }

            var propertyBag = new ReflectedPropertyBag <TContainer>();

            foreach (var(member, nameOverride) in ReflectedPropertyBagUtils.GetPropertyMembers(typeof(TContainer)))
            {
                IMemberInfo info;
                var         memberName = string.IsNullOrEmpty(nameOverride) ? member.Name : nameOverride;

                switch (member)
                {
                case FieldInfo field:
                    info = new FieldMember(field, memberName);
                    break;

                case PropertyInfo property:
                    info = new PropertyMember(property, memberName);
                    break;

                default:
                    throw new InvalidOperationException();
                }

                m_CreatePropertyMethod.MakeGenericMethod(typeof(TContainer), info.ValueType).Invoke(this, new object[]
                {
                    info,
                    propertyBag
                });
            }

            return(propertyBag);
        }