Exemplo n.º 1
0
        /// <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));
        }
Exemplo n.º 2
0
        /// <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);
        }