예제 #1
0
        public TSource ConvertFromData <TSource>(object data, ConvertFromDataFlags flags = ConvertFromDataFlags.Default)
        {
            TSource result = default(TSource);

            ConvertFromData(data, ref result, flags);
            return(result);
        }
예제 #2
0
        public void ConvertFromData <TSource>(object data, ref TSource source, ConvertFromDataFlags flags = ConvertFromDataFlags.Default)
        {
            // Special case: null
            if (data == null)
            {
                source = default(TSource);
                return;
            }

            var dataType        = data.GetType();
            var dataIsValueType = dataType.GetTypeInfo().IsValueType;

            var dataConverter = GetDataConverter(dataType, typeof(TSource), ConversionType.DataToObject);

            if (dataConverter == null)
            {
                // Special case: no conversion required
                if (data is TSource)
                {
                    source = (TSource)data;
                    return;
                }

                throw new InvalidOperationException(string.Format("Could not find a valid converter from type {0} to {1}", dataType, typeof(TSource)));
            }

            object sourceObject;
            bool   alreadyStoredInConvertedObjects = ((flags & ConvertFromDataFlags.Construct) == 0);

            if (!dataIsValueType && dataConverter.CacheResult && ((flags & ConvertFromDataFlags.Construct) != 0))
            {
                // Check cache
                object cachedSource;
                if (convertedObjects.TryGetValue(new ConvertedObjectKey(data, dataConverter.ObjectType), out cachedSource))
                {
                    source = (TSource)cachedSource;
                    return;
                }

                sourceObject = source;

                if (dataConverter.CanConstruct)
                {
                    dataConverter.ConstructFromData(this, data, ref sourceObject);

                    // Register information so that if RegisterCurrentObject is called, it will be stored in convertedObjects
                    if (sourceObject != null)
                    {
                        convertedObjects.Add(new ConvertedObjectKey(data, dataConverter.ObjectType), sourceObject);
                        alreadyStoredInConvertedObjects = true;
                    }
                }
            }
            else
            {
                sourceObject = source;
            }

            if (((flags & ConvertFromDataFlags.Convert) != 0))
            {
                dataConverter.ConvertFromData(this, data, ref sourceObject);

                if (!dataIsValueType && dataConverter.CacheResult)
                {
                    // If not stored manually through RegisterCurrentObject, register our object now
                    // Note: we can'ty reuse objectKey as it might have been reentrant
                    if (!alreadyStoredInConvertedObjects)
                    {
                        convertedObjects.Add(new ConvertedObjectKey(data, dataConverter.ObjectType), sourceObject);
                    }
                }
            }

            source = (TSource)sourceObject;
        }