Пример #1
0
        /// <summary>
        /// Converts a property to the given type
        /// </summary>
        /// <param name="name">Name of the property to convert</param>
        /// <param name="type">Type to convert to</param>
        /// <param name="defaultValue">Default value to use if conversion fails</param>
        public MigrationContainer ConvertValueOrDefault(string name, Type type, object defaultValue = null)
        {
            var property = m_PropertyBag.FindProperty(name);

            if (null == property)
            {
                throw new Exception($"{nameof(MigrationContainer)}.{nameof(ConvertValueOrDefault)} no property found with the name `{name}`");
            }

            // @TODO Type check

            // Grab the existing value
            var value = (property as IValueProperty)?.GetObjectValue(this);

            // Setup the backing storage for the value
            if (null != value)
            {
                // Try to convert the object to the new type. If this fails, fallback to the defaultValue
                m_Data[name] = TypeConversion.Convert(value, type) ?? defaultValue;
            }
            else
            {
                // @NOTE We do NOT assign the default value in this path since the value might have been explicitly set to null
                m_Data[name] = null;
            }

            // Replace the property with a newly generated one of the correct type
            m_PropertyBag.ReplaceProperty(name, DynamicProperties.CreateValueProperty(name, type));

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Creates a new dynamic migration container
        /// </summary>
        /// <param name="name">Name of the new property to create</param>
        public MigrationContainer CreateContainer(string name)
        {
            if (null != m_PropertyBag.FindProperty(name))
            {
                throw new Exception($"{nameof(MigrationContainer)}.{nameof(CreateContainer)} property already exists with the `{name}`");
            }

            var container = new MigrationContainer();

            m_Data[name] = container;
            m_PropertyBag.AddProperty(DynamicProperties.CreateValueProperty(name, typeof(MigrationContainer)));

            return(container);
        }
Пример #3
0
        /// <summary>
        /// Creates a new value property of the given type with the default value
        /// </summary>
        /// <param name="name">Name of the property to create</param>
        public MigrationContainer CreateValue <TValue>(string name)
        {
            var property = m_PropertyBag.FindProperty(name);

            if (null != property)
            {
                throw new Exception($"{nameof(MigrationContainer)}.{nameof(CreateValue)} property already exists with the name `{name}`");
            }

            m_Data[name] = default(TValue);
            m_PropertyBag.AddProperty(DynamicProperties.CreateValueProperty(name, typeof(TValue)));

            return(this);
        }
Пример #4
0
        /// <summary>
        /// Gets a container property wrapped as a `MigrationContainer`
        /// </summary>
        /// <param name="name">Name of the property to get</param>
        public MigrationContainer GetContainer(string name)
        {
            var property = m_PropertyBag.FindProperty(name);

            if (null == property)
            {
                throw new Exception($"{nameof(MigrationContainer)}.{nameof(GetContainer)} no property found with the name `{name}`");
            }

            // @TODO Type check

            MigrationContainer container;

            if (m_Data.ContainsKey(name))
            {
                // The value has already been moved to dynamic storage
                var value = m_Data[name];
                Assert.IsTrue(value is IPropertyContainer);

                if (value is MigrationContainer)
                {
                    // Already been promoted to a `MigrationContainer` return the value
                    return((MigrationContainer)m_Data[name]);
                }

                // This value exists in dynamic storage but NOT as a `MigrationContainer`
                // This can happen if the property was renamed
                container    = new MigrationContainer(value as IPropertyContainer);
                m_Data[name] = container;
                m_PropertyBag.ReplaceProperty(name, DynamicProperties.CreateValueProperty(name, typeof(MigrationContainer)));
            }
            else
            {
                // The value has not been moved to dynamic storage
                var backing = (property as IValueProperty)?.GetObjectValue(this) as IPropertyContainer;
                Assert.IsNotNull(backing);

                // Wrap the value in a `MigrationContainer` and store in dynamic storage
                container    = new MigrationContainer(backing);
                m_Data[name] = container;
                m_PropertyBag.ReplaceProperty(name, DynamicProperties.CreateValueProperty(name, typeof(MigrationContainer)));
            }

            return(container);
        }
Пример #5
0
        /// <summary>
        /// Renames a property
        /// </summary>
        /// <param name="name">Name of the property to rename</param>
        /// <param name="newName">New name for the property</param>
        public MigrationContainer Rename(string name, string newName)
        {
            var property = m_PropertyBag.FindProperty(name);

            if (null == property)
            {
                throw new MigrationException($"{nameof(MigrationContainer)}.{nameof(Rename)} no property found with the name `{name}`");
            }

            if (null != m_PropertyBag.FindProperty(newName))
            {
                throw new MigrationException($"{nameof(MigrationContainer)}.{nameof(Rename)} property already exists with name `{newName}`");
            }

            var valueProperty = property as IValueProperty;

            if (null != valueProperty)
            {
                var value     = (property as IValueProperty).GetObjectValue(this);
                var valueType = valueProperty.ValueType;

                // If needed we promote this object to a migration container
                // This is because we don't support strongly typed dynamic containers (only MigrationContainers)
                if (typeof(IPropertyContainer).IsAssignableFrom(valueProperty.ValueType))
                {
                    value     = new MigrationContainer(value as IPropertyContainer);
                    valueType = typeof(MigrationContainer);
                }

                // Setup the backing storage for the value
                m_Data[newName] = value;
                m_PropertyBag.ReplaceProperty(name, DynamicProperties.CreateValueProperty(newName, valueType));

                // Clear old dynamic value if any
                if (m_Data.ContainsKey(name))
                {
                    m_Data.Remove(name);
                }
            }

            return(this);
        }