/// <summary> /// Tries to get a class instance for a given attribute type. All loaded assemblies are searched for classes that attributeType applies to, /// then for all found classes the instantiation of a class is tried, until a instance is created successfully. Here, the attributeType has /// to implement <see cref="IClassForClassAttribute" />, and creationArg[0] has to match the type in <see cref="IClassForClassAttribute.TargetType" /> /// </summary> /// <param name="attributeType">The type of attribute the class(es) to instantiate must be assigned to.</param> /// <param name="expectedTypes">The expected type of return value.</param> /// <param name="creationArgs">The creation arguments used to instantiate a class.</param> /// <param name="overrideArgs0Type">Usually null. If you provide a type here, it has to be a base type of the typeof(creationArgs[0]). By this you /// can "downgrade" creationArgs[0], so that only attributes for the base type are looked for.</param> /// <returns>The instance of the first class for which the instantiation was successfull and results in the expectedType. Otherwise null.</returns> /// <remarks>The instantiation is tried first with the full argument list. If that fails, the last element of the argument list is chopped and the instantiation is tried again. /// This process is repeated until the instantiation was successfull or the argument list is empty (empty constructor is tried at last).</remarks> public static object GetClassForClassInstanceByAttribute(System.Type attributeType, System.Type[] expectedTypes, object[] creationArgs, System.Type overrideArgs0Type) { // 1st search for all classes that wear the UserControllerForObject attribute IAttributeForClassList list = ReflectionService.GetAttributeInstancesAndClassTypesForClass(attributeType, creationArgs[0], overrideArgs0Type); return(CreateInstanceFromList(list, expectedTypes, creationArgs)); }
/// <summary> /// Tries to get a class instance for a given attribute type. All loaded assemblies are searched for classes that attributeType applies to, /// then for all found classes the instantiation of a class is tried, until a instance is created successfully. Here, the attributeType has /// to implement <see cref="IClassForClassAttribute" />, and creationArg[0] has to match the type in <see cref="IClassForClassAttribute.TargetType" /> /// </summary> /// <param name="list">The list of types to try for creation.</param> /// <param name="expectedTypes">The expected types of return value.</param> /// <param name="creationArgs">The creation arguments used to instantiate a class.</param> /// <returns>The instance of the first class for which the instantiation was successfull and results in the expectedType. Otherwise null.</returns> /// <remarks>The instantiation is tried first with the full argument list. If that fails, the last element of the argument list is chopped and the instantiation is tried again. /// This process is repeated until the instantiation was successfull or the argument list is empty (empty constructor is tried at last).</remarks> public static object CreateInstanceFromList(IAttributeForClassList list, System.Type[] expectedTypes, object[] creationArgs) { object result = null; // evaluate the len of the creation args without null's as arguments int trueArgLen = creationArgs.Length; for (int i = 0; i < creationArgs.Length; i++) { if (creationArgs[i] == null) { trueArgLen = i; break; } } System.Type[][] creationTypes = new Type[trueArgLen + 1][]; foreach (Type definedType in list.Types) { if (!IsSubClassOfOrImplements(definedType, expectedTypes)) { continue; } // try to create the class for (int j = trueArgLen; j >= 0; j--) { if (creationTypes[j] == null) { creationTypes[j] = new Type[j]; for (int k = j - 1; k >= 0; k--) { creationTypes[j][k] = creationArgs[k].GetType(); } } ConstructorInfo cinfo = definedType.GetConstructor(creationTypes[j]); if (cinfo != null) { object[] chopped = null; if (j < creationArgs.Length) { chopped = new object[j]; Array.Copy(creationArgs, chopped, j); } result = cinfo.Invoke(j == creationArgs.Length ? creationArgs : chopped); if (result != null) { return(result); } } } } return(result); }