/// <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); }
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)); }