protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
        {
            var constructorParameters = constructor.GetParameters();

            JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType);

            foreach (ParameterInfo parameterInfo in constructorParameters)
            {
                JsonProperty matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null;

                // Constructor type must be assignable from property type.
                // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver.
                // In DefaultContractResolver, the types must match exactly.
                if (matchingMemberProperty != null && !parameterInfo.ParameterType.IsAssignableFrom(matchingMemberProperty.PropertyType))
                {
                    matchingMemberProperty = null;
                }

                if (matchingMemberProperty != null || parameterInfo.Name != null)
                {
                    JsonProperty property = CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor);

                    if (property != null)
                    {
                        parameterCollection.AddProperty(property);
                    }
                }
            }

            return(parameterCollection);
        }
Exemple #2
0
        protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
        {
            var constructorParameters = constructor.GetParameters();

            JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType);

            foreach (ParameterInfo parameterInfo in constructorParameters)
            {
                var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null;

                // Constructor type must be assignable from property type.
                // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver.
                // In DefaultContractResolver, the types must match exactly.
                if (matchingMemberProperty != null)
                {
                    var memberType             = matchingMemberProperty.PropertyType;
                    var memberTypeIsGeneric    = memberType.IsGenericType;
                    var memberGenericArguments = memberType.GetGenericArguments();
                    var parameterTypeIsArray   = parameterInfo.ParameterType.IsArray;
                    var parameterElementType   = parameterInfo.ParameterType.GetElementType();
                    if (parameterTypeIsArray &&
                        memberTypeIsGeneric &&
                        memberGenericArguments.Length == 1 &&
                        memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType)))
                    {
                        // NO-OP - this allows for the constructor parameter to be a "params" array while still using a collection property as the source.
                    }
                    else if (memberType.IsAssignableTo(parameterInfo.ParameterType))
                    {
                        // NO-OP - vanilla assignable type to constructor check.
                    }
                    else
                    {
                        // no way to do this so null out and the let the next step error with a clean message.
                        matchingMemberProperty = null;
                    }
                }

                if (matchingMemberProperty != null || parameterInfo.Name != null)
                {
                    var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor);

                    if (property != null)
                    {
                        parameterCollection.AddProperty(property);
                    }
                }
            }

            return(parameterCollection);
        }
 protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
 {
   ParameterInfo[] parameters = constructor.GetParameters();
   JsonPropertyCollection propertyCollection = new JsonPropertyCollection(constructor.DeclaringType);
   foreach (ParameterInfo parameterInfo in parameters)
   {
     JsonProperty matchingMemberProperty = parameterInfo.Name != null ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : (JsonProperty) null;
     if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType)
       matchingMemberProperty = (JsonProperty) null;
     JsonProperty constructorParameter = this.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
     if (constructorParameter != null)
       propertyCollection.AddProperty(constructorParameter);
   }
   return (IList<JsonProperty>) propertyCollection;
 }
        protected override IList <JsonProperty> CreateConstructorParameters(
            ConstructorInfo constructor,
            JsonPropertyCollection memberProperties)
        {
            var constructorParameters = constructor.GetParameters();

            var result = new JsonPropertyCollection(constructor.DeclaringType);

            foreach (var parameterInfo in constructorParameters)
            {
                var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null;

                // Constructor type must be assignable from property type.
                // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver.
                // In DefaultContractResolver, the types must match exactly.
                if (matchingMemberProperty != null)
                {
                    var memberType             = matchingMemberProperty.PropertyType;
                    var memberTypeIsGeneric    = memberType.IsGenericType;
                    var memberGenericArguments = memberType.GenericTypeArguments;
                    var parameterTypeIsArray   = parameterInfo.ParameterType.IsArray;
                    var parameterElementType   = parameterInfo.ParameterType.GetElementType();
                    if (parameterTypeIsArray &&
                        memberTypeIsGeneric &&
                        memberGenericArguments.Length == 1 &&
                        memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType)))
                    {
                        // NO-OP
                        // this allows for the constructor parameter to be a "params" array while still using a collection property as the source.
                    }
                    else if (memberType.IsAssignableTo(parameterInfo.ParameterType))
                    {
                        // NO-OP
                        // The property type and the constructor parameter type are equal.
                        // OR
                        // The property type is assignable to the constructor parameter type.
                        // In this case, the constructor is taking a less derived type and converting it
                        // to a more derived type before assigning to the property
                        // (e.g. constructor takes IEnumerable<string>, but property is an IReadOnlyCollection<string>
                        //       because the constructor calls .ToList() before assigning to the property).
                    }
                    else if (parameterInfo.ParameterType.IsAssignableTo(memberType))
                    {
                        // NO-OP
                        // The constructor parameter type is assignable to the property type.
                        // In this case, the constructor is taking a more derived type and assigning
                        // it to the property that is less derived.
                        // (e.g. constructor takes IReadOnlyCollection<string> and assigns it to a property
                        //       of type IEnumerable<string>).
                    }
                    else
                    {
                        // no way to do this so null out and the let the next step error with a clean message.
                        matchingMemberProperty = null;
                    }
                }

                if (matchingMemberProperty != null || parameterInfo.Name != null)
                {
                    var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor);

                    if (property != null)
                    {
                        result.AddProperty(property);
                    }
                }
            }

            return(result);
        }