/// <summary> /// Constructs a new instance /// </summary> /// <param name="context"></param> /// <param name="cache"></param> /// <param name="type"></param> /// <param name="fieldNameConvention"></param> public TypeData(FudgeContext context, TypeDataCache cache, Type type, FudgeFieldNameConvention fieldNameConvention) { Type = type; DefaultConstructor = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); Constructors = type.GetConstructors(); CustomAttributes = type.GetCustomAttributes(true); cache.RegisterTypeData(this); fieldNameConvention = OverrideFieldNameConvention(type, fieldNameConvention); var kind = CalcKind(context, cache, type, fieldNameConvention, out subType, out subType2, out fieldType); var inlineAttrib = GetCustomAttribute <FudgeInlineAttribute>(); if (inlineAttrib != null) { kind = inlineAttrib.Inline ? TypeKind.Inline : TypeKind.Reference; } Kind = kind; if (kind != TypeKind.FudgePrimitive) // If it's primitive we won't need to look inside it to serialize it { ScanProperties(context, cache, fieldNameConvention); ScanFields(context, cache, fieldNameConvention); PublicMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); AllInstanceMethods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); StaticPublicMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); } }
private void ScanFields(FudgeContext context, TypeDataCache cache, FudgeFieldNameConvention fieldNameConvention) { var fields = Type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var list = from field in fields where field.GetCustomAttributes(typeof(FudgeTransientAttribute), true).Length == 0 select new PropertyData(cache, fieldNameConvention, field); Fields = list.ToArray(); }
private void ScanProperties(FudgeContext context, TypeDataCache cache, FudgeFieldNameConvention fieldNameConvention) { var props = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance); var list = from prop in props where prop.GetIndexParameters().Length == 0 && // We don't want to deal with anything with indices - e.g. this[string] prop.GetCustomAttributes(typeof(FudgeTransientAttribute), true).Length == 0 select new PropertyData(cache, fieldNameConvention, prop); Properties = list.ToArray(); }
public override IFudgeSerializationSurrogate GetSurrogate(Type type, FudgeFieldNameConvention fieldNameConvention) { var fudgeSerializationSurrogate = _memoizer.Get(type, fieldNameConvention); if (fudgeSerializationSurrogate == null) { throw new ArgumentException("Found a null surrogate for this type", "type"); // May expose our bugs } return(fudgeSerializationSurrogate); }
/// <summary> /// Creates a surrogate for a given type. /// </summary> /// <param name="type">Type for which to get surrogate.</param> /// <param name="fieldNameConvention">Convention for mapping .net property names to serialized field names.</param> /// <returns>Surrogate for the type.</returns> /// <exception cref="FudgeRuntimeException">Thrown if no surrogate can be automatically created.</exception> public virtual IFudgeSerializationSurrogate GetSurrogate(Type type, FudgeFieldNameConvention fieldNameConvention) { var typeData = typeDataCache.GetTypeData(type, fieldNameConvention); foreach (var selector in selectors) { IFudgeSerializationSurrogate surrogate = selector(context, typeData); if (surrogate != null) { return(surrogate); } } throw new FudgeRuntimeException("Cannot automatically determine surrogate for type " + type.FullName); }
/// <summary> /// Gets the type data for a given type, constructing if necessary. /// </summary> /// <param name="type">Type for which to get data.</param> /// <param name="fieldNameConvention">Convention for mapping .net property names to serialized field names.</param> /// <returns><see cref="TypeData"/> for the given type.</returns> public TypeData GetTypeData(Type type, FudgeFieldNameConvention fieldNameConvention) { if (type == null) throw new ArgumentNullException("type"); TypeData result; lock (cache) { if (!cache.TryGetValue(type, out result)) { result = new TypeData(context, this, type, fieldNameConvention); Debug.Assert(cache.ContainsKey(type)); // TypeData registers itself during construction } } return result; }
private PropertyData(TypeDataCache typeCache, FudgeFieldNameConvention fieldNameConvention, MemberInfo info, Type memberType) { this.info = info; this.name = info.Name; this.typeData = typeCache.GetTypeData(memberType, fieldNameConvention); this.serializedName = GetSerializedName(info, fieldNameConvention); var inlineAttrib = GetCustomAttribute <FudgeInlineAttribute>(); if (inlineAttrib == null) { this.kind = typeData.Kind; } else { this.kind = inlineAttrib.Inline ? TypeKind.Inline : TypeKind.Reference; } }
/// <summary> /// Gets the type data for a given type, constructing if necessary. /// </summary> /// <param name="type">Type for which to get data.</param> /// <param name="fieldNameConvention">Convention for mapping .net property names to serialized field names.</param> /// <returns><see cref="TypeData"/> for the given type.</returns> public TypeData GetTypeData(Type type, FudgeFieldNameConvention fieldNameConvention) { if (type == null) { throw new ArgumentNullException("type"); } TypeData result; lock (cache) { if (!cache.TryGetValue(type, out result)) { result = new TypeData(context, this, type, fieldNameConvention); Debug.Assert(cache.ContainsKey(type)); // TypeData registers itself during construction } } return(result); }
private string GetSerializedName(MemberInfo info, FudgeFieldNameConvention fieldNameConvention) { string name = info.Name; var fieldNameAttrib = GetCustomAttribute <FudgeFieldNameAttribute>(); if (fieldNameAttrib != null) { name = fieldNameAttrib.Name; } var dataMemberAttrib = GetCustomAttribute <DataMemberAttribute>(); if (dataMemberAttrib != null && dataMemberAttrib.Name != null) { name = dataMemberAttrib.Name; } // Now apply the naming convention switch (fieldNameConvention) { case FudgeFieldNameConvention.Identity: return(name); case FudgeFieldNameConvention.AllLowerCase: return(name.ToLower()); case FudgeFieldNameConvention.AllUpperCase: return(name.ToUpper()); case FudgeFieldNameConvention.CamelCase: return(name.Substring(0, 1).ToLower() + name.Substring(1)); case FudgeFieldNameConvention.PascalCase: return(name.Substring(0, 1).ToUpper() + name.Substring(1)); default: throw new FudgeRuntimeException("Unknown FudgeFieldNameConvention: " + fieldNameConvention.ToString()); } }
private static FudgeFieldNameConvention OverrideFieldNameConvention(Type type, FudgeFieldNameConvention fieldNameConvention) { var attribs = type.GetCustomAttributes(typeof(FudgeFieldNameConventionAttribute), true); if (attribs.Length > 0) { fieldNameConvention = ((FudgeFieldNameConventionAttribute)attribs[0]).Convention; } return(fieldNameConvention); }
private IFudgeSerializationSurrogate GetSurrogateImpl(Type type, FudgeFieldNameConvention fieldNameConvention) { return(base.GetSurrogate(type, fieldNameConvention)); }
/// <summary> /// Determines whether this kind of surrogate can handle a given type /// </summary> /// <param name="cache"><see cref="TypeDataCache"/> for type data.</param> /// <param name="fieldNameConvention">Convention to use for renaming fields.</param> /// <param name="type">Type to test.</param> /// <returns>True if this kind of surrogate can handle the type.</returns> public static bool CanHandle(TypeDataCache cache, FudgeFieldNameConvention fieldNameConvention, Type type) { return(CanHandle(cache.GetTypeData(type, fieldNameConvention))); }
/// <summary> /// Creates a surrogate for a given type. /// </summary> /// <param name="type">Type for which to get surrogate.</param> /// <param name="fieldNameConvention">Convention for mapping .net property names to serialized field names.</param> /// <returns>Surrogate for the type.</returns> /// <exception cref="FudgeRuntimeException">Thrown if no surrogate can be automatically created.</exception> public IFudgeSerializationSurrogate GetSurrogate(Type type, FudgeFieldNameConvention fieldNameConvention) { var typeData = typeDataCache.GetTypeData(type, fieldNameConvention); foreach (var selector in selectors) { IFudgeSerializationSurrogate surrogate = selector(context, typeData); if (surrogate != null) return surrogate; } throw new FudgeRuntimeException("Cannot automatically determine surrogate for type " + type.FullName); }
/// <summary> /// Determines whether this kind of surrogate can handle a given type /// </summary> /// <param name="cache"><see cref="TypeDataCache"/> for type data.</param> /// <param name="fieldNameConvention">Convention to use for renaming fields.</param> /// <param name="type">Type to test.</param> /// <returns>True if this kind of surrogate can handle the type.</returns> public static bool CanHandle(TypeDataCache cache, FudgeFieldNameConvention fieldNameConvention, Type type) { return CanHandle(cache.GetTypeData(type, fieldNameConvention)); }
private static TypeKind CalcKind(FudgeContext context, TypeDataCache typeCache, Type type, FudgeFieldNameConvention fieldNameConvention, out TypeData subType, out TypeData subType2, out FudgeFieldType fieldType) { // REVIEW 2010-02-14 t0rx -- There seems to be some duplication here with the FudgeSurrogateSelector, should look at joining up subType = null; subType2 = null; fieldType = context.TypeDictionary.GetByCSharpType(type); if (fieldType != null) { // Just a simple field return(TypeKind.FudgePrimitive); } // Check for arrays if (type.IsArray) { subType = typeCache.GetTypeData(type.GetElementType(), fieldNameConvention); return(TypeKind.Inline); } // Check for dictionaries Type keyType, valueType; if (DictionarySurrogate.IsDictionary(type, out keyType, out valueType)) { subType = typeCache.GetTypeData(keyType, fieldNameConvention); subType2 = typeCache.GetTypeData(valueType, fieldNameConvention); return(TypeKind.Inline); } // Check for lists Type elementType; if (ListSurrogate.IsList(type, out elementType)) { subType = typeCache.GetTypeData(elementType, fieldNameConvention); return(TypeKind.Inline); } return(TypeKind.Reference); }
/// <summary> /// Initializes a new instance of the <see cref="FudgeFieldNameConventionAttribute"/> class. /// </summary> /// <param name="convention">Field name to use for this property.</param> public FudgeFieldNameConventionAttribute(FudgeFieldNameConvention convention) { this.Convention = convention; }
/// <summary> /// Contructs a new instance based on a field /// </summary> /// <param name="typeCache"></param> /// <param name="fieldNameConvention"></param> /// <param name="info"></param> public PropertyData(TypeDataCache typeCache, FudgeFieldNameConvention fieldNameConvention, FieldInfo info) : this(typeCache, fieldNameConvention, info, info.FieldType) { this.getter = ReflectionUtil.CreateGetterDelegate(info); this.setter = ReflectionUtil.CreateSetterDelegate(info); }