Exemple #1
0
 /// <summary>
 /// Tries to instantiate an object of a specific type. This performs
 /// application specific instantiation and subclasses should override
 /// this method to perform their own logic. If the instantiated object is
 /// null, then InstantiationData.Null should be returned.
 /// </summary>
 /// <param name="node">JSON node to create the instance from. This
 /// might be used to decide the type of the object or for the arguments
 /// of a constructor.</param>
 /// <param name="targetType">Target type of the object.</param>
 /// <param name="referingType">Refering type that is only set if this
 /// is a substitute type for another type.</param>
 /// <param name="options">Instantiation options.</param>
 /// <param name="deserializer">Deserializer to use for the instantiation.</param>
 protected virtual bool TryInstantiate(
     JSONNode node,
     Type targetType,
     Type referingType,
     NodeOptions options,
     Deserializer deserializer,
     out InstantiationData instantiationData)
 {
     instantiationData = InstantiationData.Null;
     return(false);
 }
Exemple #2
0
        private InstantiationData _InstantiateWithConstructor(
            JSONNode node,
            Type targetType,
            NodeOptions options,
            Deserializer deserializer)
        {
            if (node.IsNull || node.Tag == JSONNodeType.None)
            {
                return(InstantiationData.Null);
            }

            JSONObjectAttribute objectAttribute = Util.GetAttribute <JSONObjectAttribute> (targetType);
            bool useTupleFormat = objectAttribute != null
                                ? objectAttribute.options.ShouldUseTupleFormat() : false;

            if (useTupleFormat && !node.IsArray)
            {
                throw new InstantiationException("Expected JSON array, found " + node.Tag);
            }
            else if (!useTupleFormat && !node.IsObject)
            {
                throw new InstantiationException("Expected JSON object, found " + node.Tag);
            }

            ConstructorInfo[] constructors = targetType.GetConstructors(
                BindingFlags.Instance |
                BindingFlags.Public |
                BindingFlags.NonPublic);
            foreach (ConstructorInfo constructorInfo in constructors)
            {
                var constructorAttribute = Util.GetAttribute <JSONConstructorAttribute> (constructorInfo);
                if (constructorAttribute != null)
                {
                    return(_InstantiateWithConstructor(node, constructorInfo, deserializer, useTupleFormat));
                }
            }

            try {
                InstantiationData instantiationData = new InstantiationData();
                instantiationData.instantiatedObject   = Activator.CreateInstance(targetType);
                instantiationData.needsDeserialization = node.Count != 0;
                return(instantiationData);
            } catch (Exception) {
                return(_HandleError(options, "Type " + targetType
                                    + " does not have a suitable constructor."));
            }
        }
Exemple #3
0
        private InstantiationData _InstantiateWithConstructor(
            JSONNode node,
            ConstructorInfo constructorInfo,
            Deserializer deserializer,
            bool useTupleFormat)
        {
            ParameterInfo[]  parameters      = constructorInfo.GetParameters();
            object[]         parameterValues = new object[parameters.Length];
            HashSet <string> ignoredKeys     = new HashSet <string> ();

            for (int i = 0; i < parameterValues.Length; i++)
            {
                var nodeAttribute     = Util.GetAttribute <JSONNodeAttribute> (parameters [i]);
                var restrictAttribute = Util.GetAttribute <RestrictTypeAttribute> (parameters [i]);

                string key = nodeAttribute != null && nodeAttribute.key != null
                                        ? nodeAttribute.key : parameters [i].Name;
                JSONNode parameterNode = useTupleFormat ? node [i] : node [key];

                ObjectTypes restrictedTypes = restrictAttribute == null
                                        ? ObjectTypes.JSON : restrictAttribute.types;
                Type[] customTypes = restrictAttribute == null ? null : restrictAttribute.customTypes;

                parameterValues [i] = deserializer.Deserialize(
                    parameterNode,
                    parameters [i].ParameterType,
                    nodeAttribute == null ? NodeOptions.Default : nodeAttribute.options,
                    restrictedTypes,
                    customTypes);

                if (!useTupleFormat)
                {
                    ignoredKeys.Add(key);
                }
            }

            InstantiationData instantiationData = new InstantiationData();

            instantiationData.instantiatedObject   = constructorInfo.Invoke(parameterValues);
            instantiationData.needsDeserialization = !useTupleFormat && ignoredKeys.Count != node.Count;
            instantiationData.ignoredKeys          = ignoredKeys;
            return(instantiationData);
        }