public ObjectSubclassInfo(Type type, ConstructorInfo constructor) { TypeInfo = type.GetTypeInfo(); ClassName = GetClassName(TypeInfo); Constructor = constructor; PropertyMappings = type.GetProperties() .Select(prop => Tuple.Create(prop, prop.GetCustomAttribute<ParseFieldNameAttribute>(true))) .Where(t => t.Item2 != null) .Select(t => Tuple.Create(t.Item1, t.Item2.FieldName)) .ToDictionary(t => t.Item1.Name, t => t.Item2); }
public bool IsTypeValid(String className, Type type) { ObjectSubclassInfo subclassInfo = null; mutex.EnterReadLock(); registeredSubclasses.TryGetValue(className, out subclassInfo); mutex.ExitReadLock(); return subclassInfo == null ? type == typeof(ParseObject) : subclassInfo.TypeInfo == type.GetTypeInfo(); }
public void RegisterSubclass(Type type) { TypeInfo typeInfo = type.GetTypeInfo(); if (!typeInfo.IsSubclassOf(typeof(ParseObject))) { throw new ArgumentException("Cannot register a type that is not a subclass of ParseObject"); } String className = ObjectSubclassInfo.GetClassName(typeInfo); try { // Perform this as a single independent transaction, so we can never get into an // intermediate state where we *theoretically* register the wrong class due to a // TOCTTOU bug. mutex.EnterWriteLock(); ObjectSubclassInfo previousInfo = null; if (registeredSubclasses.TryGetValue(className, out previousInfo)) { if (typeInfo.IsAssignableFrom(previousInfo.TypeInfo)) { // Previous subclass is more specific or equal to the current type, do nothing. return; } else if (previousInfo.TypeInfo.IsAssignableFrom(typeInfo)) { // Previous subclass is parent of new child, fallthrough and actually register // this class. /* Do nothing */ } else { throw new ArgumentException( "Tried to register both " + previousInfo.TypeInfo.FullName + " and " + typeInfo.FullName + " as the ParseObject subclass of " + className + ". Cannot determine the right class " + "to use because neither inherits from the other." ); } } ConstructorInfo constructor = type.FindConstructor(); if (constructor == null) { throw new ArgumentException("Cannot register a type that does not implement the default constructor!"); } registeredSubclasses[className] = new ObjectSubclassInfo(type, constructor); } finally { mutex.ExitWriteLock(); } Action toPerform = null; if (registerActions.TryGetValue(className, out toPerform)) { toPerform(); } }
public String GetClassName(Type type) { return ObjectSubclassInfo.GetClassName(type.GetTypeInfo()); }
public String GetClassName(Type type) { return type == typeof(ParseObject) ? parseObjectClassName : ObjectSubclassInfo.GetClassName(type.GetTypeInfo()); }