Class that will use .NET Reflection to serialize and deserialize an Entity to Atom/JSON
Example #1
0
        public static IOfflineEntity GetObjectForType(EntryInfoWrapper wrapper, Type[] knownTypes)
        {
            Type entityType = null;

            ConstructorInfo ctorInfo = null;

            // See if its cached first.
            if (!_stringToCtorInfoMapping.TryGetValue(wrapper.TypeName, out ctorInfo))
            {
                // Its not cached. Try to look for it then in list of known types.
                if (knownTypes != null)
                {
                    entityType = knownTypes.Where((e) => e.FullName.Equals(wrapper.TypeName, StringComparison.InvariantCulture)).FirstOrDefault();

                    if (entityType == null)
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to find a matching type for entry '{0}' in list of KnownTypes.", wrapper.TypeName));
                    }
                }
                else
                {
                    // Try to look for the type in the list of all loaded assemblies.
#if SERVER
                    Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
#elif CLIENT
                    Assembly[] loadedAssemblies = new Assembly[] { Assembly.GetExecutingAssembly(), Assembly.GetCallingAssembly() };
#endif
                    foreach (Assembly assembly in loadedAssemblies)
                    {
#if SERVER
                        entityType = assembly.GetTypes().Where((e) => e.FullName.Equals(wrapper.TypeName, StringComparison.InvariantCulture) &&
                                                               e.GetCustomAttributes(typeof(SyncEntityTypeAttribute), true).Count() > 0).FirstOrDefault();
#elif CLIENT
                        entityType = assembly.GetTypes().Where((e) => e.FullName.Equals(wrapper.TypeName, StringComparison.InvariantCulture) &&
                                                               e.GetInterface("IOfflineEntity", false) != null).FirstOrDefault();
#endif
                        if (entityType != null)
                        {
                            break;
                        }
                    }

                    if (entityType == null)
                    {
                        throw new InvalidOperationException(string.Format("Unable to find a matching type for entry '{0}' in the loaded assemblies. Specify the type name in the KnownTypes argument to the SyncReader instance.", wrapper.TypeName));
                    }
                }

                // Reflect this entity and get necessary info
                ReflectionUtility.GetPropertyInfoMapping(entityType);
                ctorInfo = _stringToCtorInfoMapping[wrapper.TypeName];
            }
            else
            {
                entityType = ctorInfo.ReflectedType;
            }

            // Invoke the ctor
            object obj = ctorInfo.Invoke(null);

            // Set the parameters only for non tombstone items
            if (!wrapper.IsTombstone)
            {
                PropertyInfo[] props = GetPropertyInfoMapping(entityType);
                foreach (PropertyInfo pinfo in props)
                {
                    string value = null;
                    if (wrapper.PropertyBag.TryGetValue(pinfo.Name, out value))
                    {
                        pinfo.SetValue(obj, GetValueFromType(pinfo.PropertyType, value), null);
                    }
                }
            }

            IOfflineEntity entity = (IOfflineEntity)obj;
            entity.ServiceMetadata = new OfflineEntityMetadata(wrapper.IsTombstone, wrapper.Id, wrapper.ETag, wrapper.EditUri);
            return(entity);
        }
Example #2
0
        /// <summary>
        /// This writes the public contents of the Entity to the passed in XElement.
        /// </summary>
        /// <param name="contentElement">The XElement to which the type properties is added to</param>
        /// <param name="entity">Entity</param>
        /// <returns>XElement representation of the properties element</returns>
        void WriteEntityContentsToElement(XElement contentElement, IOfflineEntity entity)
        {
            PropertyInfo[] properties = ReflectionUtility.GetPropertyInfoMapping(entity.GetType());

            // Write individual properties to the feed,
            foreach (PropertyInfo fi in properties)
            {
                object objValue = fi.GetValue(entity, null);
                if (objValue == null)
                {
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.Null),
                                     objValue));
                }
                else if (fi.PropertyType == FormatterConstants.CharType ||
                         fi.PropertyType == FormatterConstants.StringType ||
                         fi.PropertyType == FormatterConstants.GuidType)
                {
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.String),
                                     objValue));
                }
                else if (fi.PropertyType == FormatterConstants.DateTimeType ||
                         fi.PropertyType == FormatterConstants.TimeSpanType ||
                         fi.PropertyType == FormatterConstants.DateTimeOffsetType)
                {
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.String),
                                     FormatterUtilities.ConvertDateTimeForType_Json(objValue, fi.PropertyType)));
                }
                else if (fi.PropertyType == FormatterConstants.BoolType)
                {
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.Boolean),
                                     objValue));
                }
                else if (fi.PropertyType == FormatterConstants.ByteArrayType)
                {
                    byte[] bytes = (byte[])objValue;
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.String),
                                     Convert.ToBase64String(bytes)));
                }
                else if (fi.PropertyType.IsGenericType && fi.PropertyType.Name.Equals(FormatterConstants.NullableTypeName, StringComparison.InvariantCulture))
                {
                    // Its a Nullable<T> property
                    Type genericParamType = fi.PropertyType.GetGenericArguments()[0];

                    string elementType = JsonElementTypes.Number;
                    if (genericParamType == FormatterConstants.BoolType)
                    {
                        elementType = JsonElementTypes.Boolean;
                    }
                    else if (genericParamType == FormatterConstants.DateTimeType ||
                             genericParamType == FormatterConstants.TimeSpanType ||
                             genericParamType == FormatterConstants.DateTimeOffsetType)
                    {
                        contentElement.Add(
                            new XElement(fi.Name,
                                         new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.String),
                                         FormatterUtilities.ConvertDateTimeForType_Json(objValue, genericParamType)));
                        continue;
                    }
                    else if (genericParamType == FormatterConstants.CharType ||
                             genericParamType == FormatterConstants.GuidType)
                    {
                        elementType = JsonElementTypes.String;
                    }

                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, elementType),
                                     objValue));
                }
                else // Its a number
                {
                    contentElement.Add(
                        new XElement(fi.Name,
                                     new XAttribute(FormatterConstants.JsonTypeAttributeName, JsonElementTypes.Number),
                                     objValue));
                }
            }
        }