public override bool CanConvert(Type objectType)
        {
            var canConvert = objectType.IsGenericType() &&
                             objectType.GetGenericTypeDefinition() == typeof(GroupedResult<,>);

            return canConvert;
        }
Example #2
0
 private static Type FindIEnumerable(Type seqType)
 {
     if (seqType == null || seqType == typeof(string))
         return null;
     if (seqType.IsArray)
         return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());
     if (seqType.IsGenericType())
     {
         foreach (Type arg in seqType.GetGenericArguments())
         {
             Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
             if (ienum.IsAssignableFrom(seqType))
                 return ienum;
         }
     }
     var ifaces = seqType.GetInterfaces();
     if (ifaces != null && ifaces.Any())
     {
         foreach (Type iface in ifaces)
         {
             Type ienum = FindIEnumerable(iface);
             if (ienum != null)
                 return ienum;
         }
     }
     if (seqType.BaseType() != null && seqType.BaseType() != typeof(object))
         return FindIEnumerable(seqType.BaseType());
     return null;
 }
Example #3
0
    /// <summary>
    /// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
    /// </summary>
    /// <param name="underlyingType">The underlying type for the contract.</param>
    public JsonArrayContract(Type underlyingType)
      : base(underlyingType)
    {
      ContractType = JsonContractType.Array;
      
      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
      {
        CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
      }
      else if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
      {
        _genericCollectionDefinitionType =  typeof (IEnumerable<>);
        CollectionItemType = underlyingType.GetGenericArguments()[0];
      }
      else
      {
        CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
      }

      if (CollectionItemType != null)
        _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);

      if (IsTypeGenericCollectionInterface(UnderlyingType))
        CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
#if !(PORTABLE || NET20 || NET35 || WINDOWS_PHONE)
      else if (IsTypeGenericSetnterface(UnderlyingType))
        CreatedType = ReflectionUtils.MakeGenericType(typeof(HashSet<>), CollectionItemType);
#endif

      IsMultidimensionalArray = (UnderlyingType.IsArray && UnderlyingType.GetArrayRank() > 1);
    }
        // This method takes generic type and returns a 'partially' generic type definition of that same type,
        // where all generic arguments up to the given nesting level. This allows us to group generic types
        // by their partial generic type definition, which allows a much nicer user experience.
        internal static Type MakeTypePartiallyGenericUpToLevel(Type type, int nestingLevel)
        {
            if (nestingLevel > 100)
            {
                // Stack overflow prevention
                throw new ArgumentException("nesting level bigger than 100 too high. Type: " +
                    type.ToFriendlyName(), nameof(nestingLevel));
            }

            // example given type: IEnumerable<IQueryProcessor<MyQuery<Alpha>, int[]>>
            // nestingLevel 4 returns: IEnumerable<IQueryHandler<MyQuery<Alpha>, int[]>
            // nestingLevel 3 returns: IEnumerable<IQueryHandler<MyQuery<Alpha>, int[]>
            // nestingLevel 2 returns: IEnumerable<IQueryHandler<MyQuery<T>, int[]>
            // nestingLevel 1 returns: IEnumerable<IQueryHandler<TQuery, TResult>>
            // nestingLevel 0 returns: IEnumerable<T>
            if (!type.IsGenericType())
            {
                return type;
            }

            if (nestingLevel == 0)
            {
                return type.GetGenericTypeDefinition();
            }

            return MakeTypePartiallyGeneric(type, nestingLevel);
        }
Example #5
0
		/// <summary>
		/// Gets the full name without version information.
		/// </summary>
		/// <param name="entityType">Type of the entity.</param>
		/// <returns></returns>
		public static string GetFullNameWithoutVersionInformation(Type entityType)
		{
			string result;
			var localFullName = fullnameCache;
			if (localFullName.TryGetValue(entityType, out result))
				return result;

			var asmName = new AssemblyName(entityType.Assembly().FullName).Name;
			if (entityType.IsGenericType())
			{
				var genericTypeDefinition = entityType.GetGenericTypeDefinition();
				var sb = new StringBuilder(genericTypeDefinition.FullName);
				sb.Append("[");
				foreach (var genericArgument in entityType.GetGenericArguments())
				{
					sb.Append("[")
						.Append(GetFullNameWithoutVersionInformation(genericArgument))
						.Append("]");
				}
				sb.Append("], ")
					.Append(asmName);
				result = sb.ToString();
			}
			else
			{
				result = entityType.FullName + ", " + asmName;
			}

			fullnameCache = new Dictionary<Type, string>(localFullName)
			{
				{entityType, result}
			};

			return result;
		}
 public InvocationWithGenericDelegateContributor(Type delegateType, MetaMethod method, Reference targetReference)
 {
     Debug.Assert(delegateType.IsGenericType(), "delegateType.IsGenericType");
     this.delegateType = delegateType;
     this.method = method;
     this.targetReference = targetReference;
 }
Example #7
0
        public static Type GetElementType(Type enumerableType, IEnumerable enumerable)
        {
            if (enumerableType.HasElementType)
            {
                return enumerableType.GetElementType();
            }

            if (enumerableType.IsGenericType() &&
                enumerableType.GetGenericTypeDefinition() == typeof (IEnumerable<>))
            {
                return enumerableType.GetTypeInfo().GenericTypeArguments[0];
            }

            Type ienumerableType = GetIEnumerableType(enumerableType);
            if (ienumerableType != null)
            {
                return ienumerableType.GetTypeInfo().GenericTypeArguments[0];
            }

            if (typeof (IEnumerable).IsAssignableFrom(enumerableType))
            {
                var first = enumerable?.Cast<object>().FirstOrDefault();

                return first?.GetType() ?? typeof (object);
            }

            throw new ArgumentException($"Unable to find the element type for type '{enumerableType}'.", nameof(enumerableType));
        }
    /// <summary>
    /// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
    /// </summary>
    /// <param name="underlyingType">The underlying type for the contract.</param>
    public JsonArrayContract(Type underlyingType)
      : base(underlyingType)
    {
      ContractType = JsonContractType.Array;
      
      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
      {
        CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
      }
      else if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
      {
        _genericCollectionDefinitionType =  typeof (IEnumerable<>);
        CollectionItemType = underlyingType.GetGenericArguments()[0];
      }
      else
      {
        CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
      }

      if (CollectionItemType != null)
        _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);

      if (IsTypeGenericCollectionInterface(UnderlyingType))
      {
        CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
      }
    }
Example #9
0
        public static bool IsGenericTypeOf(this Type t, Type genericDefinition, out Type[] genericParameters)
        {
            genericParameters = new Type[] { };
            if (!genericDefinition.IsGenericType())
            {
                return false;
            }

            var isMatch = t.IsGenericType() && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
            if (!isMatch && t.GetBaseType() != null)
            {
                isMatch = IsGenericTypeOf(t.GetBaseType(), genericDefinition, out genericParameters);
            }
            if (!isMatch && genericDefinition.IsInterface() && t.GetInterfaces().Any())
            {
                foreach (var i in t.GetInterfaces())
                {
                    if (i.IsGenericTypeOf(genericDefinition, out genericParameters))
                    {
                        isMatch = true;
                        break;
                    }
                }
            }

            if (isMatch && !genericParameters.Any())
            {
                genericParameters = t.GetGenericArguments();
            }
            return isMatch;
        }
        /// <summary>
        /// Returns true if the given type will be excluded from the default model validation. 
        /// </summary>
        public bool IsTypeExcluded(Type type)
        {
            Type[] actualTypes;

            if (type.IsGenericType() &&
                type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
            {
                actualTypes = type.GenericTypeArguments;
            }
            else
            {
                actualTypes = new Type[] { type };
            }

            foreach (var actualType in actualTypes)
            {
                var underlyingType = Nullable.GetUnderlyingType(actualType) ?? actualType;
                if (!IsSimpleType(underlyingType))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        ///     Bind to the given model type
        /// </summary>
        /// <param name="context">Current context</param>
        /// <param name="modelType">Model type to bind to</param>
        /// <param name="instance">Optional existing instance</param>
        /// <param name="configuration">The <see cref="BindingConfig" /> that should be applied during binding.</param>
        /// <param name="blackList">Blacklisted property names</param>
        /// <returns>Bound model</returns>
        public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration,
            params string[] blackList)
        {
            Type genericType = null;
            if (modelType.IsArray() || modelType.IsCollection() || modelType.IsEnumerable())
            {
                //make sure it has a generic type
                if (modelType.IsGenericType())
                {
                    genericType = modelType.GetGenericArguments().FirstOrDefault();
                }
                else
                {
                    var implementingIEnumerableType =
                        modelType.GetInterfaces().Where(i => i.IsGenericType()).FirstOrDefault(
                            i => i.GetGenericTypeDefinition() == typeof (IEnumerable<>));
                    genericType = implementingIEnumerableType == null ? null : implementingIEnumerableType.GetGenericArguments().FirstOrDefault();
                }

                if (genericType == null)
                {
                    throw new ArgumentException("When modelType is an enumerable it must specify the type", "modelType");
                }
            }

            var bindingContext =
                CreateBindingContext(context, modelType, instance, configuration, blackList, genericType);

            var bodyDeserializedModel = DeserializeRequestBody(bindingContext);

            return (instance as IEnumerable<string>) ?? bodyDeserializedModel;
        }
Example #12
0
        /// <summary>Checks whether the specified type is a generic nullable type.</summary>
        /// <param name="type">Type to check.</param>
        /// <returns>true if <paramref name="type"/> is nullable; false otherwise.</returns>
        internal static bool IsNullableType(Type type)
        {
            DebugUtils.CheckNoExternalCallers();

            //// This is a copy of WebUtil.IsNullableType from the product.

            return type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>);
        }
        private ContainerControlledItem[] GetClosedContainerControlledItemsFor(Type serviceType)
        {
            var items = this.GetItemsFor(serviceType);

            return serviceType.IsGenericType()
                ? Helpers.GetClosedGenericImplementationsFor(serviceType, items)
                : items.ToArray();
        }
        public InvocationWithDelegateContributor(Type delegateType, Type targetType, MetaMethod method,
		                                         INamingScope namingScope)
        {
            Debug.Assert(delegateType.IsGenericType() == false, "delegateType.IsGenericType == false");
            this.delegateType = delegateType;
            this.targetType = targetType;
            this.method = method;
            this.namingScope = namingScope;
        }
        private string FormatType(Type type)
        {
            var typeName = type.Name;
            if (!type.IsGenericType()) return typeName;

            typeName = typeName.Substring(0, typeName.IndexOf('`'));
            var genericArgTypes = type.GetGenericArguments().Select(x => FormatType(x));
            return string.Format("{0}<{1}>", typeName, string.Join(", ", genericArgTypes.ToArray()));
        }
Example #16
0
        /// <summary>
        /// Determines whether the specified type is primitive
        /// </summary>
        /// <param name="type">The type to check</param>
        /// <returns>
        /// <c>true</c> if the specified type is primitive; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsPrimitiveType(Type type)
        {
            ExceptionUtilities.CheckArgumentNotNull(type, "type");
            if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                type = type.GetGenericArguments()[0];
            }

            return primitiveTypes.Contains(type) || type.FullName.StartsWith("Microsoft.Spatial", StringComparison.Ordinal);
        }
Example #17
0
        public static Type[] GetElementTypes(Type enumerableType, IEnumerable enumerable,
            ElemntTypeFlags flags = ElemntTypeFlags.None)
        {
            if (enumerableType.HasElementType)
            {
                return new[] {enumerableType.GetElementType()};
            }

            if (flags.HasFlag(ElemntTypeFlags.BreakKeyValuePair) && enumerableType.IsGenericType() &&
                enumerableType.IsDictionaryType())
            {
                return enumerableType.GetTypeInfo().GenericTypeArguments;
            }

            if (enumerableType.IsGenericType() &&
                enumerableType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            {
                return enumerableType.GetTypeInfo().GenericTypeArguments;
            }

            Type idictionaryType = enumerableType.GetDictionaryType();
            if (idictionaryType != null && flags.HasFlag(ElemntTypeFlags.BreakKeyValuePair))
            {
                return idictionaryType.GetTypeInfo().GenericTypeArguments;
            }

            Type ienumerableType = GetIEnumerableType(enumerableType);
            if (ienumerableType != null)
            {
                return ienumerableType.GetTypeInfo().GenericTypeArguments;
            }

            if (typeof(IEnumerable).IsAssignableFrom(enumerableType))
            {
                var first = enumerable?.Cast<object>().FirstOrDefault();

                return new[] {first?.GetType() ?? typeof(object)};
            }

            throw new ArgumentException($"Unable to find the element type for type '{enumerableType}'.",
                nameof(enumerableType));
        }
        internal GenericTypeBuilder(Type closedGenericBaseType, Type openGenericImplementation)
        {
            this.closedGenericBaseType = closedGenericBaseType;

            this.openGenericImplementation = openGenericImplementation;

            if (openGenericImplementation.IsGenericType() && 
                !openGenericImplementation.IsGenericTypeDefinition())
            {
                this.openGenericImplementation = openGenericImplementation.GetGenericTypeDefinition();
                this.partialOpenGenericImplementation = openGenericImplementation;
                this.isPartialOpenGenericImplementation = true;
            }
        }
Example #19
0
        private static bool IsSetType(Type type)
        {
            if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof (ISet<>))
            {
                return true;
            }

            IEnumerable<Type> genericInterfaces = type.GetTypeInfo().ImplementedInterfaces.Where(t => t.IsGenericType());
            IEnumerable<Type> baseDefinitions = genericInterfaces.Select(t => t.GetGenericTypeDefinition());

            var isCollectionType = baseDefinitions.Any(t => t == typeof (ISet<>));

            return isCollectionType;
        }
Example #20
0
        public virtual string CreateResponse(Type type)
        {
            if (type == typeof(string))
                return "(string)";
            if (type == typeof(byte[]))
                return "(byte[])";
            if (type == typeof(Stream))
                return "(Stream)";
            if (type == typeof(HttpWebResponse))
                return "(HttpWebResponse)";
            if (type.IsGenericType() && type.GetGenericTypeDefinition() == typeof(Task<>))
                type = type.GetGenericArguments()[0]; 

            return CreateMessage(type);
        }
Example #21
0
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.Null)
			{
				if (!objectType.IsGenericType() || objectType.GetGenericTypeDefinition() != typeof(Nullable<>))
					throw new JsonSerializationException($"Cannot convert null value to {objectType}.");

				return null;
			}
			if (reader.TokenType == JsonToken.String)
			{
				return TimeSpan.Parse((string)reader.Value);
			}

			throw new JsonSerializationException($"Cannot convert token of type {reader.TokenType} to {objectType}.");
		}
Example #22
0
        private static Type FindIEnumerable(Type type)
        {
            if (type == null || type == typeof(string))
            {
                return null;
            }

            if (type.IsArray)
            {
                return typeof(IEnumerable<>).MakeGenericType(type.GetElementType());
            }

            if (type.IsGenericType())
            {
                foreach (var arg in type.GetGenericArguments())
                {
                    var enumerableType = typeof(IEnumerable<>).MakeGenericType(arg);
                    if (enumerableType.IsAssignableFrom(type))
                    {
                        return enumerableType;
                    }
                }
            }

            var interfaces = type.GetInterfaces();
            if (interfaces != null && interfaces.Any())
            {
                foreach (var interfaceType in interfaces)
                {
                    var enumerableType = FindIEnumerable(interfaceType);
                    if (enumerableType != null)
                    {
                        return enumerableType;
                    }
                }
            }

            var baseType = type.GetBaseType();
            if (baseType != null && baseType != typeof(object))
            {
                return FindIEnumerable(baseType);
            }

            return null;
        }
Example #23
0
 public static string GetEdmType(Type type)
 {
     if (type.IsGenericType())
     {
         return GetEdmType(type.GetGenericArguments()[0]);
     }
     switch (type.Name)
     {
         case "Boolean":
             return "Edm.Boolean";
         case "Byte":
             return "Edm.Byte";
         case "Char":
         case "String":
             return "Edm.String";
         case "DBNull":
             return "null";
         case "DateTime":
             return "Edm.DateTime";
         case "Decimal":
             return "Edm.Decimal";
         case "Double":
             return "Edm.Double";
         case "Int16":
             return "Edm.Int16";
         case "Int32":
             return "Edm.Int32";
         case "Int64":
             return "Edm.Int64";
         case "SByte":
             return "Edm.SByte";
         case "Single":
             return "Edm.Single";
         case "Byte[]":
             return "Edm.Binary";
         case "Guid":
             return "Edm.Guid";
         case "TimeSpan":
             return "Edm.Time";
         case "DateTimeOffset":
             return "Edm.DateTimeOffset";
         default:
             throw new NotSupportedException("TypeCode " + type.Name + " is not a supported type.");
     }
 }
Example #24
0
        /// <summary>
        /// Test whether a type is unsupported by the client lib
        /// </summary>
        /// <param name="type">The type to test</param>
        /// <returns>Returns true if the type is not supported</returns>
        internal static bool IsUnsupportedType(Type type)
        {
#if ASTORIA_CLIENT
            if (type.IsGenericType())
#else
            if (type.IsGenericType)
#endif
            {
                type = type.GetGenericTypeDefinition();
            }

            if (unsupportedTypes.Any(t => t.IsAssignableFrom(type)))
            {
                return true;
            }

            Debug.Assert(!type.FullName.StartsWith("System.Tuple", StringComparison.Ordinal), "System.Tuple is not blocked by unsupported type check");
            return false;
        }
Example #25
0
 internal static string GetModelTypeName(Type type)
 {
     if (type.IsGenericType())
     {
         Type[] genericArguments = type.GetGenericArguments();
         StringBuilder builder = new StringBuilder((type.Name.Length * 2) * (1 + genericArguments.Length));
         if (type.IsNested)
         {
             builder.Append(GetModelTypeName(type.DeclaringType));
             builder.Append('_');
         }
         builder.Append(type.Name);
         builder.Append('[');
         for (int i = 0; i < genericArguments.Length; i++)
         {
             if (i > 0)
             {
                 builder.Append(' ');
             }
             if (genericArguments[i].IsGenericParameter)
             {
                 builder.Append(genericArguments[i].Name);
             }
             else
             {
                 string modelTypeNamespace = GetModelTypeNamespace(genericArguments[i]);
                 if (!string.IsNullOrEmpty(modelTypeNamespace))
                 {
                     builder.Append(modelTypeNamespace);
                     builder.Append('.');
                 }
                 builder.Append(GetModelTypeName(genericArguments[i]));
             }
         }
         builder.Append(']');
         return builder.ToString();
     }
     if (type.IsNested)
     {
         return (GetModelTypeName(type.DeclaringType) + "_" + type.Name);
     }
     return type.Name;
 }
Example #26
0
 private void AddGenericsInfo(System.Type type, ref string onlyTypeName)
 {
     if (type.IsGenericType())
     {
         Type[]        gParams = type.GetGenericArguments();
         StringBuilder builder = new StringBuilder(onlyTypeName);
         builder.Append("[");
         for (int i = 0; i < gParams.Length; ++i)
         {
             if (i > 0)
             {
                 builder.Append(", ");
             }
             builder.Append("[");
             builder.Append(BuildTypeName(gParams[i]));
             builder.Append("]");
         }
         builder.Append("]");
         onlyTypeName = builder.ToString();
     }
 }
		public static Type GetGenericElementType(Type genericDefinitionType, Type type)
		{
			Debug.Assert(genericDefinitionType != null);
			Debug.Assert(genericDefinitionType.IsGenericTypeDefinition());
			Debug.Assert(genericDefinitionType.GetGenericArguments().Length == 1);
			Debug.Assert(type != null);

			if (type.IsGenericType() &&
				(type.GetGenericTypeDefinition() == genericDefinitionType))
			{
				return type.GetGenericArguments()[0];
			}

			var realType =
				type.GetInterfaces().
				FirstOrDefault(interfaceType =>
					interfaceType.IsGenericType() &&
					interfaceType.GetGenericTypeDefinition() == genericDefinitionType);

			return (realType != null) ? realType.GetGenericArguments()[0] : null;
		}
Example #28
0
        public object GetValue(Type targetType)
        {
            var stringValue = _underlyingValue as string;
            if (_underlyingValue == null)
            {
                if (targetType.IsValueType() && !(targetType.IsGenericType() && targetType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                {
                    var valueAsString = string.IsNullOrEmpty(stringValue) ? "<null>" : string.Format("\"{0}\"", _underlyingValue);
                    throw new ArgumentException(string.Format("Cannot convert {0} to {1} (Column: '{2}', Row: {3})", valueAsString, targetType.Name, Header, Row));
                }

                ValueHasBeenUsed = true;
                return null;
            }

            ValueHasBeenUsed = true;
            if (targetType.IsInstanceOfType(_underlyingValue))
                return _underlyingValue;

            if (targetType.IsEnum() && _underlyingValue is string)
                return Enum.Parse(targetType, (string)_underlyingValue);

            if (targetType == typeof(DateTime))
                return DateTime.Parse(stringValue);

            try
            {
                return Convert.ChangeType(_underlyingValue, targetType);
            }
            catch (InvalidCastException ex)
            {
                throw new UnassignableExampleException(string.Format(
                    "{0} cannot be assigned to {1} (Column: '{2}', Row: {3})", 
                    _underlyingValue == null ? "<null>" : _underlyingValue.ToString(),
                    targetType.Name, Header, Row), ex, this);
            }
        }
        /// <param name="type">The type to construct.</param>
        /// <param name="getClosedGenericInterfaceType">
        /// For generic interfaces, the only way to reliably determine the implementing type's generic type arguments
        /// is to know the closed type of the desired interface implementation since there may be multiple implementations
        /// of the same generic interface on this type.
        /// </param>
        //public static Func<ResolutionContext, TServiceType> BuildCtor<TServiceType>(this Type type, Func<ResolutionContext, Type> getClosedGenericInterfaceType = null)
        //{
        //    return context =>
        //    {
        //        if (type.IsGenericTypeDefinition())
        //        {
        //            if (getClosedGenericInterfaceType == null) throw new ArgumentNullException(nameof(getClosedGenericInterfaceType), "For generic interfaces, the desired closed interface type must be known.");
        //            var closedInterfaceType = getClosedGenericInterfaceType.Invoke(context);
        //            var implementationTypeArguments = type.GetImplementedInterface(closedInterfaceType.GetGenericTypeDefinition(), closedInterfaceType.GenericTypeArguments).GenericTypeArguments;

        //            var genericParameters = type.GetTypeInfo().GenericTypeParameters;
        //            var deducedTypeArguments = new Type[genericParameters.Length];
        //            DeduceGenericArguments(genericParameters, deducedTypeArguments, implementationTypeArguments[0], context.SourceType);
        //            DeduceGenericArguments(genericParameters, deducedTypeArguments, implementationTypeArguments[1], context.DestinationType);

        //            if (deducedTypeArguments.Any(_ => _ == null)) throw new InvalidOperationException($"One or more type arguments to {type.Name} cannot be determined.");
        //            type = type.MakeGenericType(deducedTypeArguments);
        //        }

        //        var obj = context.Options.ServiceCtor.Invoke(type);

        //        return (TServiceType)obj;
        //    };
        //}

        private static void DeduceGenericArguments(Type[] genericParameters, Type[] deducedGenericArguments, Type typeUsingParameters, Type typeUsingArguments)
        {
            if (typeUsingParameters.IsByRef)
            {
                DeduceGenericArguments(genericParameters, deducedGenericArguments, typeUsingParameters.GetElementType(), typeUsingArguments.GetElementType());
                return;
            }

            var index = Array.IndexOf(genericParameters, typeUsingParameters);
            if (index != -1)
            {
                if (deducedGenericArguments[index] == null)
                    deducedGenericArguments[index] = typeUsingArguments;
                else if (deducedGenericArguments[index] != typeUsingArguments)
                    throw new NotImplementedException("Generic variance is not implemented.");
            }
            else if (typeUsingParameters.IsGenericType() && typeUsingArguments.IsGenericType())
            {
                var childArgumentsUsingParameters = typeUsingParameters.GenericTypeArguments;
                var childArgumentsUsingArguments = typeUsingArguments.GenericTypeArguments;
                for (var i = 0; i < childArgumentsUsingParameters.Length; i++)
                    DeduceGenericArguments(genericParameters, deducedGenericArguments, childArgumentsUsingParameters[i], childArgumentsUsingArguments[i]);
            }
        }
Example #30
0
        /// <summary>
        /// Bind to the given model type
        /// </summary>
        /// <param name="context">Current context</param>
        /// <param name="modelType">Model type to bind to</param>
        /// <param name="instance">Optional existing instance</param>
        /// <param name="configuration">The <see cref="BindingConfig"/> that should be applied during binding.</param>
        /// <param name="blackList">Blacklisted property names</param>
        /// <returns>Bound model</returns>
        public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration, params string[] blackList)
        {
            Type genericType = null;
            if (modelType.IsArray() || modelType.IsCollection() || modelType.IsEnumerable())
            {
                //make sure it has a generic type
                if (modelType.IsGenericType())
                {
                    genericType = modelType.GetGenericArguments().FirstOrDefault();
                }
                else
                {
                    var ienumerable =
                        modelType.GetInterfaces().Where(i => i.IsGenericType()).FirstOrDefault(
                            i => i.GetGenericTypeDefinition() == typeof(IEnumerable<>));
                    genericType = ienumerable == null ? null : ienumerable.GetGenericArguments().FirstOrDefault();
                }

                if (genericType == null)
                {
                    throw new ArgumentException("when modeltype is an enumerble it must specify the type", "modelType");
                }
            }

            var bindingContext =
                this.CreateBindingContext(context, modelType, instance, configuration, blackList, genericType);

            var bodyDeserializedModel = this.DeserializeRequestBody(bindingContext);

            if (bodyDeserializedModel != null)
            {
                UpdateModelWithDeserializedModel(bodyDeserializedModel, bindingContext);
            }

            var bindingExceptions = new List<PropertyBindingException>();

            if (!bindingContext.Configuration.BodyOnly)
            {
                if (bindingContext.DestinationType.IsCollection() || bindingContext.DestinationType.IsArray() ||
                    bindingContext.DestinationType.IsEnumerable())
                {
                    var loopCount = GetBindingListInstanceCount(context);
                    var model = (IList)bindingContext.Model;
                    for (var i = 0; i < loopCount; i++)
                    {
                        object genericinstance;
                        if (model.Count > i)
                        {
                            genericinstance = model[i];
                        }
                        else
                        {
                            genericinstance = Activator.CreateInstance(bindingContext.GenericType);
                            model.Add(genericinstance);
                        }

                        foreach (var modelProperty in bindingContext.ValidModelProperties)
                        {
                            var existingCollectionValue = modelProperty.GetValue(genericinstance, null);

                            var collectionStringValue = GetValue(modelProperty.Name, bindingContext, i);

                            if (BindingValueIsValid(collectionStringValue, existingCollectionValue, modelProperty,
                                                    bindingContext))
                            {
                                try
                                {
                                    BindProperty(modelProperty, collectionStringValue, bindingContext, genericinstance);
                                }
                                catch (PropertyBindingException ex)
                                {
                                    bindingExceptions.Add(ex);
                                }
                            }
                        }
                    }
                }
                else
                {
                    foreach (var modelProperty in bindingContext.ValidModelProperties)
                    {
                        var existingValue = modelProperty.GetValue(bindingContext.Model, null);

                        var stringValue = GetValue(modelProperty.Name, bindingContext);

                        if (BindingValueIsValid(stringValue, existingValue, modelProperty, bindingContext))
                        {
                            try
                            {
                                BindProperty(modelProperty, stringValue, bindingContext);
                            }
                            catch (PropertyBindingException ex)
                            {
                                bindingExceptions.Add(ex);
                            }
                        }
                    }
                }

                if (bindingExceptions.Any())
                {
                    throw new ModelBindingException(modelType, bindingExceptions);
                }
            }

            if (modelType.IsArray())
            {
                var generictoArrayMethod = toArrayMethodInfo.MakeGenericMethod(new[] { genericType });
                return generictoArrayMethod.Invoke(null, new[] { bindingContext.Model });
            }
            return bindingContext.Model;
        }
 public override bool CanConvert(Type objectType)
 {
     return objectType.IsEnum() || (objectType.IsGenericType() && objectType.GetGenericTypeDefinition() == typeof(SafeEnum<>));
 }