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); }
/// <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)); } } }