Ejemplo n.º 1
0
        /// <summary>
        /// Handles instantiation of Request-scoped components.
        /// </summary>
        /// <param name="component"></param>
        /// <returns></returns>
        internal static object InstanceRequestScoped(Type component)
        {
            // Check if type is an alias
            if (Container.Aliases.ContainsKey(component))
            {
                component = Container.Aliases[component];
            }

            // Locate the autowiring constructor, if present
            var constructor = LocateAutowiredConstructor(component);

            // Missing constructor: Create default instance and return
            if (constructor is null)
            {
                var instance = SnowActivator.CreateInstance(component);
                if (instance == null)
                {
                    throw new NoSuitableConstructorFound(component.FullName);
                }

                ReadyInstance(component, instance);
                return(instance);
            }

            // Found constructor: Locate and inject dependencies
            var parameters   = constructor.GetParameters();
            var paramObjects = new List <object>();

            foreach (var parameter in parameters)
            {
                // Parameter must be a component
                if (parameter.ParameterType.CustomAttributes.Any(ca => typeof(ComponentAttribute).IsAssignableFrom(ca.AttributeType)))
                {
                    // At this point, all dependencies have been registered
                    // during the initial launch pass.
                    paramObjects.Add(Container.Retrieve(parameter.ParameterType));
                }
                else
                {
                    throw new AutowiringConstructorException($@"Parameter {parameter.ParameterType} is not a component.
All parameters in an Autowired Constructor must be components.");
                }
            }

            // Invoke constructor and register component
            var newInstance = constructor.Invoke(paramObjects.ToArray());

            ReadyInstance(component, newInstance);
            return(newInstance);
        }
Ejemplo n.º 2
0
        private static void InstanceComponent(Type component)
        {
            // Check if type is an alias
            if (Container.Aliases.ContainsKey(component))
            {
                component = Container.Aliases[component];
            }

            // The component may have been initialized by the
            // autowiring constructor on one of the previous components.
            if (Container.Dependencies.Keys.Contains(component))
            {
                return;
            }

            // Locate the autowiring constructor, if present
            var constructor = LocateAutowiredConstructor(component);

            // Missing constructor: Create default instance and store
            if (constructor is null)
            {
                var instance = SnowActivator.CreateInstance(component);
                if (instance == null)
                {
                    throw new NoSuitableConstructorFound(component.FullName);
                }
                Container.Register(component, instance);

                // Look for type aliases
                var defAliases = component.CustomAttributes.Where(ca => typeof(TypeAliasAttribute).IsAssignableFrom(ca.AttributeType))
                                 .SelectMany(ca => ca.ConstructorArguments)
                                 .Select(ca => ca.Value)
                                 .Cast <Type>();

                foreach (var alias in defAliases)
                {
                    // The component must be assignable to alias type
                    if (!alias.IsAssignableFrom(component))
                    {
                        throw new InvalidTypeAliasException($"{component} cannot have {alias} as a Type Alias.");
                    }

                    Container.Register(alias, instance);
                    Container.Aliases.Add(alias, component);
                }

                return;
            }

            // Found constructor: Locate and inject dependencies
            var parameters   = constructor.GetParameters();
            var paramObjects = new List <object>();

            foreach (var parameter in parameters)
            {
                var parameterType = parameter.ParameterType;
                // Check if parameter is an alias
                if (Container.Aliases.ContainsKey(parameterType))
                {
                    parameterType = Container.Aliases[parameterType];
                }

                // Parameter must be a component
                if (parameterType.CustomAttributes.Any(ca => typeof(ComponentAttribute).IsAssignableFrom(ca.AttributeType)))
                {
                    // Check if the type is already instanced
                    if (!Container.Dependencies.Keys.Contains(parameterType))
                    {
                        // Instance the type before injecting it
                        InstanceComponent(parameterType);
                    }

                    paramObjects.Add(Container.Retrieve(parameterType));
                }
                else
                {
                    throw new AutowiringConstructorException($@"Parameter {parameterType} is not a component.
All parameters in an Autowired Constructor must be components.");
                }
            }

            // Invoke constructor and register component
            var newInstance = constructor.Invoke(paramObjects.ToArray());

            Container.Register(component, newInstance);

            // Look for type aliases
            var aliases = component.CustomAttributes.Where(ca => typeof(TypeAliasAttribute).IsAssignableFrom(ca.AttributeType));
        }