private MethodInfo MatchMethods(FactoryConfiguration factory, Type type, string methodName, bool isStatic)
        {
            MethodInfo[] methods         = type.GetMethods();
            MethodInfo   bestMethodMatch = null;
            int          bestScore       = int.MaxValue;


            foreach (MethodInfo method in methods)
            {
                if (method.Name != methodName)
                {
                    continue;
                }

                int             score      = 0;
                ParameterInfo[] parameters = method.GetParameters();

                //if param count doesnt match , move to next ctor
                if (parameters.Length != factory.ParameterConfigurations.Count)
                {
                    continue;
                }

                if (parameters.Length == 0)
                {
                    return(method);
                }

                #region Match parameters

                for (int i = 0; i < parameters.Length; i++)
                {
                    ParameterConfiguration parameterConfig = (ParameterConfiguration)factory.ParameterConfigurations[i];
                    Type type1 = parameters[i].ParameterType;
                    Type type2 = parameterConfig.Type;
                    if (type2 == null)
                    {
                        //untyped parameter
                        try
                        {
                            ValueConfiguration parameterValueConfig = (ValueConfiguration)parameterConfig.Value;
                            object             res = Convert.ChangeType(parameterValueConfig.Value, type1);
                        }
                        catch
                        {
                            continue;
                        }
                        score++;
                    }
                    else
                    {
                        //typed parameter

                        if (type1.IsAssignableFrom(type2))
                        {
                            if (type1 == type2)
                            {
                                //same type
                                score++;
                            }
                            else if (type2.IsSubclassOf(type1))
                            {
                                //subclass
                                Type tmpType = type2;
                                while (tmpType != type1)
                                {
                                    score++;
                                    tmpType = tmpType.BaseType;
                                }
                            }
                            else
                            {
                                //interface
                                score++;
                            }
                        }
                        else
                        {
                            //ignore this
                            continue;
                        }
                    }
                }

                #endregion

                if (score < bestScore && score != 0)
                {
                    bestMethodMatch = method;
                    bestScore       = score;
                }
            }
            return(bestMethodMatch);
        }
        private void ConfigureElement(XmlNode node, ElementConfiguration config, IContainer container, Type valueType)
        {
            config.Type = valueType;

            if (node.Attributes["value"] != null)
            {
                string propertyValueString = node.Attributes["value"].Value;

                ValueConfiguration propertyValueConfig = new ValueConfiguration();
                propertyValueConfig.Value = propertyValueString;
                config.Value = propertyValueConfig;

                if (node.Attributes["type-converter"] != null)
                {
                    string typeConverterString = node.Attributes["type-converter"].Value;
                    Type   typeConverterType   = ResolveType(typeConverterString);

                    TypeConverter typeConverter = (TypeConverter)Activator.CreateInstance(typeConverterType);
                    propertyValueConfig.TypeConverter = typeConverter;
                }

                if (node.Attributes["type"] != null)
                {
                    string typeString = node.Attributes["type"].Value;
                    Type   type       = ResolveType(typeString);

                    config.Type = type;
                }
            }

            if (node.Attributes["object"] != null)
            {
                string propertyObjectName = node.Attributes["object"].Value;
                IObjectConfiguration propertyObjectConfig = GetObjectConfiguration(propertyObjectName, container);

                config.Value = propertyObjectConfig;

                //done
                if (node.Attributes["instance-mode"] != null)
                {
                    string instanceModeString = node.Attributes["instance-mode"].Value;
                    config.InstanceMode = (InstanceMode)InstanceMode.Parse(typeof(InstanceMode), instanceModeString);
                }
            }

            if (node.Attributes["list"] != null)
            {
                string             propertyListName   = node.Attributes["list"].Value;
                IListConfiguration propertyListConfig = GetListConfiguration(propertyListName, container);

                config.Value = propertyListConfig;
                config.Type  = typeof(IList);
            }

            if (node.Attributes["factory"] != null)
            {
                string itemFactoryName = node.Attributes["factory"].Value;
                IFactoryConfiguration propertyFactoryConfig = GetFactoryConfiguration(itemFactoryName, container);

                config.Value = propertyFactoryConfig;
            }
        }
        private ConstructorInfo MatchConstructors(ObjectConfiguration objectConfig)
        {
            try
            {
                ConstructorInfo[] constructors  = objectConfig.Type.GetConstructors();
                ConstructorInfo   bestCtorMatch = null;
                int bestScore = int.MaxValue;


                foreach (ConstructorInfo constructor in constructors)
                {
                    int             score          = 0;
                    ParameterInfo[] ctorParameters = constructor.GetParameters();

                    //if param count doesnt match , move to next ctor
                    if (ctorParameters.Length != objectConfig.CtorParameterConfigurations.Count)
                    {
                        continue;
                    }

                    if (ctorParameters.Length == 0)
                    {
                        return(constructor);
                    }

                    #region Match parameters

                    for (int i = 0; i < ctorParameters.Length; i++)
                    {
                        ParameterConfiguration parameterConfig = (ParameterConfiguration)objectConfig.CtorParameterConfigurations[i];
                        Type type1 = ctorParameters[i].ParameterType;
                        Type type2 = parameterConfig.Type;
                        if (type2 == null)
                        {
                            ValueConfiguration parameterValueConfig = (ValueConfiguration)parameterConfig.Value;

                            if (parameterValueConfig.TypeConverter != null)
                            {
                                if (parameterValueConfig.TypeConverter.CanConvertTo(type1))
                                {
                                    score++;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                //untyped parameter
                                try
                                {
                                    if (type1.IsEnum && parameterValueConfig.Value is string)
                                    {
                                        object res = Enum.Parse(type1, parameterValueConfig.Value.ToString());
                                    }
                                    else
                                    {
                                        object res = Convert.ChangeType(parameterValueConfig.Value, type1);
                                    }
                                }
                                catch
                                {
                                    break;
                                }
                                score++;
                            }
                        }
                        else
                        {
                            //typed parameter

                            if (type1.IsAssignableFrom(type2))
                            {
                                if (type1 == type2)
                                {
                                    //same type
                                    score++;
                                }
                                else if (type2.IsSubclassOf(type1))
                                {
                                    //subclass
                                    Type tmpType = type2;
                                    while (tmpType != type1)
                                    {
                                        score++;
                                        tmpType = tmpType.BaseType;
                                    }
                                }
                                else
                                {
                                    //interface
                                    score++;
                                }
                            }
                            else
                            {
                                //ignore this
                                break;
                            }
                        }
                    }

                    #endregion

                    if (score < bestScore && score != 0)
                    {
                        bestCtorMatch = constructor;
                        bestScore     = score;
                    }
                }
                return(bestCtorMatch);
            }
            catch (Exception x)
            {
                throw new Exception(string.Format("could not match constructor for object '{0}'", objectConfig.Name), x);
            }
        }
        private IFactoryConfiguration ConfigureFactory(XmlNode configNode, IContainer container)
        {
            string factoryName                  = configNode.Attributes["name"].Value;
            string factoryMethodName            = configNode.Attributes["method"].Value;
            IFactoryConfiguration factoryConfig = GetFactoryConfiguration(factoryName, container);

            factoryConfig.Name       = factoryName;
            factoryConfig.MethodName = factoryMethodName;


            if (configNode.Attributes["type"] != null)             //
            {
                string objectTypeString = configNode.Attributes["type"].Value;
                Type   objectType       = ResolveType(objectTypeString);

                factoryConfig.Type = objectType;
            }
            else if (configNode.Attributes["object"] != null)             //instance
            {
                string objectName = configNode.Attributes["object"].Value;
                IObjectConfiguration objectConfig = GetObjectConfiguration(objectName, container);
                factoryConfig.Object = objectConfig;
            }

            foreach (XmlNode factoryNode in configNode)
            {
                #region Parameter

                if (factoryNode.Name == "parameter")
                {
                    ParameterConfiguration parameterConfig = new ParameterConfiguration();
                    parameterConfig.Index = Convert.ToInt32(factoryNode.Attributes["index"].Value);


                    if (factoryNode.Attributes["value"] != null)
                    {
                        string             propertyValueString = factoryNode.Attributes["value"].Value;
                        ValueConfiguration propertyValueConfig = new ValueConfiguration();
                        if (factoryNode.Attributes["type"] != null)
                        {
                            //typed parameter
                            string parameterTypeString = factoryNode.Attributes["type"].Value;
                            Type   parameterType       = ResolveType(parameterTypeString);
                            parameterConfig.Type      = parameterType;
                            propertyValueConfig.Value = Convert.ChangeType(propertyValueString, parameterConfig.Type);
                        }
                        else
                        {
                            //untyped parameter
                            propertyValueConfig.Value = propertyValueString;
                            //		parameterConfig.UntypedStringValue = propertyValueString;
                            parameterConfig.Type = null;
                        }

                        parameterConfig.Value = propertyValueConfig;
                    }

                    if (factoryNode.Attributes["object"] != null)
                    {
                        string parameterObjectName = factoryNode.Attributes["object"].Value;
                        IObjectConfiguration propertyObjectConfig = GetObjectConfiguration(parameterObjectName, container);

                        parameterConfig.Value = propertyObjectConfig;

                        //done
                        if (factoryNode.Attributes["instance-mode"] != null)
                        {
                            string instanceModeString = factoryNode.Attributes["instance-mode"].Value;
                            parameterConfig.InstanceMode = (InstanceMode)InstanceMode.Parse(typeof(InstanceMode), instanceModeString);
                        }
                    }

                    factoryConfig.ParameterConfigurations.Add(parameterConfig);
                }

                #endregion
            }

            return(factoryConfig);
        }