/// <summary> /// Ctor /// </summary> public FactoryMap(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (FactoryMap.IsInvalidType(type)) { throw new TypeLoadException(String.Format( FactoryMap.ErrorCannotInstantiate, type.FullName)); } this.Ctor = DynamicMethodGenerator.GetTypeFactory(type); ConstructorInfo[] ctors; if (!typeof(IEnumerable).IsAssignableFrom(type)) { if (this.Ctor != null) { return; } ctors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (ctors.Length == 1) { ConstructorInfo ctor = ctors[0]; this.Ctor = DynamicMethodGenerator.GetTypeFactory(ctor); this.CtorArgs = ctor.GetParameters(); } return; } // many ICollection types take an IEnumerable or ICollection // as a constructor argument. look through constructors for // a compatible match. ctors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); this.CollectionCtors = new Dictionary <Type, FactoryDelegate>(ctors.Length); foreach (ConstructorInfo ctor in ctors) { ParameterInfo[] paramList = ctor.GetParameters(); if (paramList.Length != 1) { continue; } Type argType = paramList[0].ParameterType; if ((argType == typeof(string)) || ( #if !NETCF (argType.GetInterface(TypeCoercionUtility.TypeGenericIEnumerable, false) == null) && #endif (typeof(IEnumerable).IsAssignableFrom(argType)))) { continue; } // save all constructors that can take an enumerable of objects this.CollectionCtors[argType] = DynamicMethodGenerator.GetTypeFactory(ctor); } if (this.Ctor == null) { // try to grab a private ctor if exists this.Ctor = DynamicMethodGenerator.GetTypeFactory(type); } // many collection types have an AddRange method // which adds a collection of items at once MethodInfo methodInfo = type.GetMethod("AddRange"); if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1) { this.AddRange = DynamicMethodGenerator.GetMethodProxy(methodInfo); this.AddRangeType = parameters[0].ParameterType; } } // many collection types have an Add method // which adds items one at a time Type collectionType = null; #if !NETCF collectionType = type.GetInterface(TypeCoercionUtility.TypeGenericICollection, false); #endif if (collectionType != null) { methodInfo = collectionType.GetMethod("Add"); } else { methodInfo = type.GetMethod("Add"); } if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1) { this.Add = DynamicMethodGenerator.GetMethodProxy(methodInfo); this.AddType = parameters[0].ParameterType; } } }