public bool IsTypeValid(String className, Type type)
        {
            ObjectSubclassInfo subclassInfo = null;

            mutex.EnterReadLock();
            registeredSubclasses.TryGetValue(className, out subclassInfo);
            mutex.ExitReadLock();

            return(subclassInfo == null
        ? type == typeof(AVObject)
        : subclassInfo.TypeInfo == type.GetTypeInfo());
        }
        public Type GetType(String className)
        {
            ObjectSubclassInfo info = null;

            mutex.EnterReadLock();
            registeredSubclasses.TryGetValue(className, out info);
            mutex.ExitReadLock();

            return(info != null
        ? info.TypeInfo.AsType()
        : null);
        }
        public AVObject Instantiate(String className)
        {
            ObjectSubclassInfo info = null;

            mutex.EnterReadLock();
            registeredSubclasses.TryGetValue(className, out info);
            mutex.ExitReadLock();

            return(info != null
        ? info.Instantiate()
        : new AVObject(className));
        }
        public IDictionary <String, String> GetPropertyMappings(String className)
        {
            ObjectSubclassInfo info = null;

            mutex.EnterReadLock();
            registeredSubclasses.TryGetValue(className, out info);
            if (info == null)
            {
                registeredSubclasses.TryGetValue(parseObjectClassName, out info);
            }
            mutex.ExitReadLock();

            return(info.PropertyMappings);
        }
        public void RegisterSubclass(Type type)
        {
            TypeInfo typeInfo = type.GetTypeInfo();

            if (!typeof(AVObject).GetTypeInfo().IsAssignableFrom(typeInfo))
            {
                throw new ArgumentException("Cannot register a type that is not a subclass of AVObject");
            }

            String className = GetClassName(type);

            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 AVObject 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;

            mutex.EnterReadLock();
            registerActions.TryGetValue(className, out toPerform);
            mutex.ExitReadLock();

            if (toPerform != null)
            {
                toPerform();
            }
        }
 public String GetClassName(Type type)
 {
     return(type == typeof(AVObject)
 ? parseObjectClassName
 : ObjectSubclassInfo.GetClassName(type.GetTypeInfo()));
 }
        public void RegisterSubclass(Type type)
        {
            TypeInfo typeInfo = type.GetTypeInfo();
              if (!typeof(AVObject).GetTypeInfo().IsAssignableFrom(typeInfo)) {
            throw new ArgumentException("Cannot register a type that is not a subclass of AVObject");
              }

              String className = GetClassName(type);

              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 AVObject 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;

              mutex.EnterReadLock();
              registerActions.TryGetValue(className, out toPerform);
              mutex.ExitReadLock();

              if (toPerform != null) {
            toPerform();
              }
        }