/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="property"></param> /// <returns></returns> private DataPropertyAttribute GetCustomAttribute(Type type, PropertyInfo property) { string key = string.Format("attr:{0}:{1}:{2}", type.FullName, property.Name, typeof(DataPropertyAttribute).Name); DataPropertyAttribute attribute = Cache.Instance.Get(key) as DataPropertyAttribute; if (attribute == null) { attribute = property.GetCustomAttribute <DataPropertyAttribute>(); Cache.Instance.Add(key, attribute); } return(attribute); }
/// <summary> /// Serializes an entity to a BSON document /// </summary> /// <param name="entity"></param> /// <param name="processIndex">True if index should be included. Must be false when updating.</param> /// <returns></returns> private SerializeResult Serialize(object entity, bool processIndex) { Type type = entity.GetType(); IEnumerable <PropertyInfo> properties = this.GetTypeProperties(type); BsonDocument doc = new BsonDocument(); string id = null; bool indexFound = false; foreach (PropertyInfo property in properties) { DataPropertyAttribute attribute = GetCustomAttribute(type, property); if (attribute.IsIndex) { if (indexFound) { throw new Exception(string.Format("{0} has multiple properties marked as index. Only one index is allowed.", type.Name)); } if (property.PropertyType != typeof(string)) { throw new Exception(string.Format("Only a string property can be marked as index.", type.Name)); } id = property.GetValue(entity) as string; if (processIndex) { doc["_id"] = id; } indexFound = true; } else { if (property.PropertyType == typeof(string)) { doc[property.Name] = CastFrom.String(property.GetValue(entity)); } else if (property.PropertyType == typeof(DateTime)) { doc[property.Name] = CastFrom.DateTime(property.GetValue(entity)); } else if (property.PropertyType == typeof(DateTime?)) { doc[property.Name] = CastFrom.NullableDateTime(property.GetValue(entity)); } else if (property.PropertyType == typeof(bool)) { doc[property.Name] = CastFrom.Boolean(property.GetValue(entity)); } else if (property.PropertyType == typeof(bool?)) { doc[property.Name] = CastFrom.NullableBoolean(property.GetValue(entity)); } else if (property.PropertyType == typeof(int)) { doc[property.Name] = CastFrom.Int(property.GetValue(entity)); } else if (property.PropertyType == typeof(int?)) { doc[property.Name] = CastFrom.NullableInt(property.GetValue(entity)); } else if (property.PropertyType == typeof(long)) { doc[property.Name] = CastFrom.Long(property.GetValue(entity)); } else if (property.PropertyType == typeof(long?)) { doc[property.Name] = CastFrom.NullableLong(property.GetValue(entity)); } else if (property.PropertyType == typeof(double)) { doc[property.Name] = CastFrom.Double(property.GetValue(entity)); } else if (property.PropertyType == typeof(double?)) { doc[property.Name] = CastFrom.NullableDouble(property.GetValue(entity)); } else if (property.PropertyType == typeof(Regex)) { doc[property.Name] = CastFrom.Regex(property.GetValue(entity)); } else if (property.PropertyType == typeof(byte[])) { doc[property.Name] = CastFrom.ByteArray(property.GetValue(entity)); } else { throw new Exception(string.Format("CastFrom error - property {0} of type {1} is not a supported data type", property.PropertyType, type.Name)); } } } // todo : check id for null return(new SerializeResult { Document = doc, Id = id }); }
/// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="doc"></param> private void Deserialize(object entity, BsonDocument doc) { Type type = entity.GetType(); IEnumerable <PropertyInfo> properties = this.GetTypeProperties(type); foreach (PropertyInfo property in properties) { DataPropertyAttribute attribute = GetCustomAttribute(type, property); if (attribute.IsIndex) { property.SetValue(entity, doc["_id"].AsString); } else { if (property.PropertyType == typeof(string)) { property.SetValue(entity, CastTo.String(doc, property.Name)); } else if (property.PropertyType == typeof(Boolean)) { property.SetValue(entity, CastTo.Boolean(doc, property.Name)); } else if (property.PropertyType == typeof(Boolean?)) { property.SetValue(entity, CastTo.NullableBoolean(doc, property.Name)); } else if (property.PropertyType == typeof(byte[])) { property.SetValue(entity, CastTo.ByteArray(doc, property.Name)); } else if (property.PropertyType == typeof(Regex)) { property.SetValue(entity, CastTo.Regex(doc, property.Name)); } else if (property.PropertyType == typeof(int)) { property.SetValue(entity, CastTo.Int(doc, property.Name)); } else if (property.PropertyType == typeof(int?)) { property.SetValue(entity, CastTo.NullableInt(doc, property.Name)); } else if (property.PropertyType == typeof(long)) { property.SetValue(entity, CastTo.Long(doc, property.Name)); } else if (property.PropertyType == typeof(long?)) { property.SetValue(entity, CastTo.NullableLong(doc, property.Name)); } else if (property.PropertyType == typeof(double)) { property.SetValue(entity, CastTo.Double(doc, property.Name)); } else if (property.PropertyType == typeof(double?)) { property.SetValue(entity, CastTo.NullableDouble(doc, property.Name)); } else if (property.PropertyType == typeof(DateTime)) { property.SetValue(entity, CastTo.DateTime(doc, property.Name)); } else if (property.PropertyType == typeof(DateTime?)) { property.SetValue(entity, CastTo.NullableDateTime(doc, property.Name)); } else { throw new Exception(string.Format("CastTo error - property {0} of type {1} is not a supported data type", property.PropertyType, type.Name)); } } } }