Catel.IoC.TypeFactory.CreateInstanceWithSpecifiedParameters C# (CSharp) Method

CreateInstanceWithSpecifiedParameters() private method

Creates an instance of the specified type using the specified parameters as injection values.
The is null.
private CreateInstanceWithSpecifiedParameters ( Type typeToConstruct, object tag, object parameters, bool autoCompleteDependencies, bool preventCircularDependencies = true ) : object
typeToConstruct System.Type The type to construct.
tag object The preferred tag when resolving dependencies.
parameters object The parameters to inject.
autoCompleteDependencies bool if set to true, the additional dependencies will be auto completed.
preventCircularDependencies bool if set to true, prevent circular dependencies using the .
return object
        private object CreateInstanceWithSpecifiedParameters(Type typeToConstruct, object tag, object[] parameters,
            bool autoCompleteDependencies, bool preventCircularDependencies = true)
        {
            Argument.IsNotNull("typeToConstruct", typeToConstruct);

            if (parameters == null)
            {
                parameters = new object[] { };
            }

            lock (_serviceLocator.LockObject)
            {
                TypeRequestInfo typeRequestInfo = null;

                try
                {
                    if (preventCircularDependencies)
                    {
                        typeRequestInfo = new TypeRequestInfo(typeToConstruct);
                        if (_currentTypeRequestPath == null)
                        {
                            _currentTypeRequestPath = new TypeRequestPath(typeRequestInfo, name: TypeRequestPathName);
                        }
                        else
                        {
                            _currentTypeRequestPath.PushType(typeRequestInfo, true);
                        }
                    }

                    var constructorCache = GetConstructorCache(autoCompleteDependencies);
                    var constructorCacheKey = new ConstructorCacheKey(typeToConstruct, parameters);

                    if (constructorCache.ContainsKey(constructorCacheKey))
                    {
                        var cachedConstructor = constructorCache[constructorCacheKey];
                        var instanceCreatedWithInjection = TryCreateToConstruct(typeToConstruct, cachedConstructor, tag, parameters, false, false);
                        if (instanceCreatedWithInjection != null)
                        {
                            if (preventCircularDependencies)
                            {
                                CompleteTypeRequestPathIfRequired(typeRequestInfo);
                            }

                            return instanceCreatedWithInjection;
                        }

                        Log.Warning("Found constructor for type '{0}' in constructor, but it failed to create an instance. Removing the constructor from the cache", typeToConstruct.FullName);

                        constructorCache.Remove(constructorCacheKey);
                    }

                    Log.Debug("Creating instance of type '{0}' using specific parameters. No constructor found in the cache, so searching for the right one", typeToConstruct.FullName);

                    var typeConstructorsMetadata = GetTypeMetaData(typeToConstruct);
                    var constructors = typeConstructorsMetadata.GetConstructors(parameters.Count(), !autoCompleteDependencies);

                    for (int i = 0; i < constructors.Count; i++)
                    {
                        var constructor = constructors[i];

                        var instanceCreatedWithInjection = TryCreateToConstruct(typeToConstruct, constructor, tag, parameters, true, i < constructors.Count - 1);
                        if (instanceCreatedWithInjection != null)
                        {
                            if (preventCircularDependencies)
                            {
                                CompleteTypeRequestPathIfRequired(typeRequestInfo);
                            }

                            // We found a constructor that works, cache it
                            constructorCache[constructorCacheKey] = constructor;

                            // Only update the rule when using a constructor for the first time, not when using it from the cache
                            ApiCop.UpdateRule<TooManyDependenciesApiCopRule>("TypeFactory.LimitDependencyInjection",
                                x => x.SetNumberOfDependenciesInjected(typeToConstruct, constructor.GetParameters().Count()));

                            return instanceCreatedWithInjection;
                        }
                    }

                    Log.Debug("No constructor could be used, cannot construct type '{0}' with the specified parameters", typeToConstruct.FullName);
                }
                catch (CircularDependencyException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    if (preventCircularDependencies)
                    {
                        CloseCurrentTypeIfRequired(typeRequestInfo);
                    }

                    Log.Warning(ex, "Failed to construct type '{0}'", typeToConstruct.FullName);

                    throw;
                }

                if (preventCircularDependencies)
                {
                    CloseCurrentTypeIfRequired(typeRequestInfo);
                }

                return null;
            }
        }