Exemple #1
0
 /// <summary>
 /// Ensure no component of the given type is registered yet
 /// </summary>
 /// <param name="type">The type of the component</param>
 private void EnsureNotRegistered(Type type)
 {
     // Ensure the type was not already registered
     if (Registrations.ContainsKey(type))
     {
         throw ComponentResolutionException.AlreadyRegistered(type);
     }
 }
Exemple #2
0
        /// <summary>
        /// Internal method for getting a type by specifying and existing set of pending resolutions, mainly used
        /// to detect circular dependencies
        /// </summary>
        /// <param name="type">The type of the component</param>
        /// <param name="pendingResolutions">A set of pending resolutions</param>
        /// <param name="parameters">The parameters to inject manually</param>
        /// <returns>The component of the requested type</returns>
        private object GetInternal(Type type, IDictionary <Type, ComponentRegistration> pendingResolutions, Hashtable parameters)
        {
            // Get the registration for the given type
            ComponentRegistration registration;

            // Ensure the component is registered
            if (!Registrations.TryGetValue(type, out registration))
            {
                throw ComponentResolutionException.NotRegistered(type);
            }

            // Try and retrieve the instance as a singleton instance when appropriate
            if (registration.Singleton)
            {
                object singleton;

                if (Singletons.TryGetValue(type, out singleton))
                {
                    return(singleton);
                }
            }

            object instance;

            if (registration.Instance != null)
            {
                // Use the instance if provided
                instance = registration.Instance;
            }
            else if (registration.FactoryMethod != null)
            {
                // Use the factory method provided
                instance = registration.FactoryMethod();
            }
            else
            {
                // Find the constructor for the given type
                var ctor = GetConstructor(registration.Type);

                // Ensure there is an eligible constructor
                if (ctor == null)
                {
                    throw ComponentResolutionException.ConstructorNotFound(type);
                }

                var dependencies = ctor.GetParameters().ToList();

                // Create a dictionary of seen type that are not yet resolved
                pendingResolutions = pendingResolutions ?? new Dictionary <Type, ComponentRegistration>();

                // Add an entry for the current type in the pending resolutions
                pendingResolutions.Add(type, registration);

                // The list of resolved dependencies
                var resolvedDependencies   = new object[dependencies.Count];
                var currentDependencyIndex = 0;

                // For every dependency
                foreach (var dependency in dependencies)
                {
                    // Try and get the parameter from the manual parameter list
                    if (parameters != null)
                    {
                        var argument = parameters[dependency.Name];
                        if (argument != null && dependency.ParameterType.IsAssignableFrom(argument.GetType()))
                        {
                            resolvedDependencies[currentDependencyIndex++] = argument;
                            continue;
                        }
                    }

                    // Try and get the parameter from the default parameter list
                    if (registration.Parameters != null)
                    {
                        var argument = registration.Parameters[dependency.Name];
                        if (argument != null && dependency.ParameterType.IsAssignableFrom(argument.GetType()))
                        {
                            resolvedDependencies[currentDependencyIndex++] = argument;
                            continue;
                        }
                    }

                    // The dependency could not be resolved with manually provided parameters.
                    // Resolve it using other components registered

                    var dependencyType = dependency.ParameterType;

                    // Ensure there is no circular dependency
                    if (pendingResolutions.ContainsKey(dependencyType))
                    {
                        throw ComponentResolutionException.CircularDependency(type, dependencyType);
                    }

                    try
                    {
                        // Create an instance of the dependency recursively
                        resolvedDependencies[currentDependencyIndex++] = GetInternal(dependencyType, pendingResolutions, null);
                    }
                    catch (ComponentResolutionException ex)
                    {
                        // Wrap an throw the exception
                        throw ComponentResolutionException.DependencyResolution(type, ex);
                    }
                }

                // Create an instance of the type using the constructor obtained before
                instance = ctor.Invoke(resolvedDependencies);
            }

            // Register the instance as a singleton when appropriate
            if (registration.Singleton)
            {
                Singletons.Add(type, instance);
            }

            // Return the newly created instance
            return(instance);
        }