private object Instantiate(ConstructorInvokeInfo info)
        {
            var constructorParameters = info.ParameterInfos;
            var length         = constructorParameters.Length;
            var parametersList = new object[length];

            for (int i = 0; i < length; i++)
            {
                ParameterInfo parameterInfo = constructorParameters[i];
                object        parameter     = Resolve(parameterInfo.ParameterType);
                if (parameter == null && !parameterInfo.IsOptional)
                {
                    throw new IoCResolutionException(
                              "Failed to instantiate parameter " + parameterInfo.Name);
                }

                parametersList[i] = parameter;
            }

            var constructorFunc = info.ConstructorFunc;

            try
            {
                return(constructorFunc(parametersList));
            }
            catch (Exception ex)
            {
                throw new IoCResolutionException("Failed to resolve " + info.Constructor.DeclaringType, ex);
            }
        }
        private object Instantiate(Type type)
        {
            ConstructorInvokeInfo invokeInfo;

            m_constructorDictionaryLockSlim.EnterReadLock();

            try
            {
                if (m_constructorDictionary.TryGetValue(type, out invokeInfo))
                {
                    return(Instantiate(invokeInfo));
                }
            }
            finally
            {
                m_constructorDictionaryLockSlim.ExitReadLock();
            }

#if NETFX_CORE
            var constructors = type.GetTypeInfo().DeclaredConstructors.Where(x => !x.IsStatic && x.IsPublic).ToArray();
#else
            var constructors = type.GetConstructors();
#endif

            ConstructorInfo constructor = null;

            if (constructors.Length > 0)
            {
                ConstructorInfo bestMatch     = null;
                int             biggestLength = -1;

                foreach (ConstructorInfo constructorInfo in constructors)
                {
                    var dependencyAttributes = constructorInfo.GetCustomAttributes(typeof(InjectConstructorAttribute), false);
#if NETFX_CORE
                    var attributeCount = dependencyAttributes.Count();
#else
                    var attributeCount = dependencyAttributes.Length;
#endif
                    bool hasAttribute = attributeCount > 0;

                    if (hasAttribute)
                    {
                        constructor = constructorInfo;
                        break;
                    }

                    var length = constructorInfo.GetParameters().Length;

                    if (length > biggestLength)
                    {
                        biggestLength = length;
                        bestMatch     = constructorInfo;
                    }
                }

                if (constructor == null)
                {
                    constructor = bestMatch;
                }
            }
            else
            {
#if !NETFX_CORE
                ConstructorInfo bestMatch     = null;
                int             biggestLength = -1;

                constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

                if (constructors.Length > 0)
                {
                    foreach (ConstructorInfo constructorInfo in constructors)
                    {
                        if (constructorInfo.GetCustomAttributes(typeof(InjectConstructorAttribute), false).Length > 0)
                        {
                            constructor = constructorInfo;
                            break;
                        }

                        var length = constructorInfo.GetParameters().Length;

                        if (length <= biggestLength)
                        {
                            continue;
                        }

                        biggestLength = length;
                        bestMatch     = constructorInfo;
                    }

                    if (constructor == null)
                    {
                        constructor = bestMatch;
                    }
                }
#endif
            }

            if (constructor == null)
            {
                throw new IoCResolutionException(
                          "Could not locate a constructor for " + type.FullName);
            }

            invokeInfo = new ConstructorInvokeInfo(constructor);
            m_constructorDictionaryLockSlim.EnterWriteLock();
            try
            {
                m_constructorDictionary[type] = invokeInfo;
            }
            finally
            {
                m_constructorDictionaryLockSlim.ExitWriteLock();
            }

            return(Instantiate(invokeInfo));
        }