private static bool CanResolveParameter(ICherryServiceLocatorAndRegistry current, ParameterInfo constructorParameterInfo, InjectionParameter[] parameters) { if (parameters == null || parameters.Length == 0) { // Shotcut when no parameters provided return current.CanGet(constructorParameterInfo.ParameterType); } InjectionParameter namedParameter = parameters.SingleOrDefault(p => p.Key == constructorParameterInfo.Name); if (namedParameter != null) { return true; } InjectionParameter unnamedParameter = parameters.SingleOrDefault( p => string.IsNullOrEmpty(p.Key) && !ReferenceEquals(p.Value, null) && constructorParameterInfo.ParameterType.IsInstanceOfType(p.Value)); if (unnamedParameter != null) { return true; } return current.CanGet(constructorParameterInfo.ParameterType); }
public object Get(ICherryServiceLocatorAndRegistry original, ICherryServiceLocatorAndRegistry current, InjectionParameter[] parameters) { ConstructorInfo[] allPublicConstructors = _targetType.GetConstructors(); ConstructorInfo bestConstructor = allPublicConstructors.OrderByDescending( c => c.GetParameters().Count(p => CanResolveParameter(current, p, parameters))) .FirstOrDefault(); if (bestConstructor == null) { throw new InvalidOperationException( string.Format( "Creating an instance of type \"{0}\" failed. This type has no public constructors that can be satisfied.", _targetType)); } ParameterInfo[] constructorParameterInfos = bestConstructor.GetParameters(); ValidateParameters(constructorParameterInfos, parameters); var constructorParameters = new object[constructorParameterInfos.Length]; for (int i = 0; i < constructorParameterInfos.Length; i++) { constructorParameters[i] = ResolveParameter(original, current, constructorParameterInfos, i, parameters); } object instance = bestConstructor.Invoke(constructorParameters); return instance; }
public object Get(ICherryServiceLocatorAndRegistry original, ICherryServiceLocatorAndRegistry current, InjectionParameter[] parameters) { if (parameters != null && parameters.Length > 0) { throw new ArgumentException(string.Format("Since \"{0}\" is a singleton instance, you cannot use parameters to resolve it.", _instance), "parameters"); } return _instance; }
public object Get(ICherryServiceLocatorAndRegistry original, ICherryServiceLocatorAndRegistry current, InjectionParameter[] parameters) { if (parameters != null && parameters.Length > 0) { throw new ArgumentException(string.Format("Since \"{0}\" is a singleton instance, you cannot use parameters to resolve it.", _instance), "parameters"); } if (_instance != null) { return _instance; } lock (_syncRoot) { if (_instance != null) { return _instance; } var instance = (new PerResolveResolver(_targetType)).Get(original, current, parameters); _instance = instance; return instance; } }
private IParameter ResolveParameterName(Type serviceKey, IBinding binding, ref Type resolvedType, InjectionParameter injectionParameter) { resolvedType = resolvedType ?? TypeToGetResolved(serviceKey, binding); var constructorParameter = resolvedType.GetConstructors().SelectMany(c => c.GetParameters()) .First(p => p.ParameterType.IsInstanceOfType(injectionParameter.Value)); return new ConstructorArgument(constructorParameter.Name, injectionParameter.Value); }
private IParameter[] ModifyParameters(Type serviceKey, IBinding binding, InjectionParameter[] parameters) { if (parameters == null || parameters.Length == 0) { return null; } Type resolvedType = null; return parameters.Select( p => string.IsNullOrEmpty(p.Key) ? ResolveParameterName(serviceKey, binding, ref resolvedType, p) : new ConstructorArgument(p.Key, p.Value)) .ToArray(); }
private ResolverOverride ResolveParameterName(Type serviceKey, ContainerRegistration registration, ref Type resolvedType, InjectionParameter injectionParameter) { resolvedType = resolvedType ?? TypeToGetResolved(serviceKey, registration); ParameterInfo constructorParameter = resolvedType.GetConstructors().SelectMany(c => c.GetParameters()) .First(p => p.ParameterType.IsInstanceOfType(injectionParameter.Value)); return new ParameterOverride(constructorParameter.Name, injectionParameter.Value); }
private ResolverOverride[] ModifyParameters(Type serviceKey, ContainerRegistration registration, InjectionParameter[] parameters) { if (parameters == null || parameters.Length == 0) { return null; } Type resolvedType = null; return parameters.Select( p => string.IsNullOrEmpty(p.Key) ? ResolveParameterName(serviceKey, registration, ref resolvedType, p) : new ParameterOverride(p.Key, p.Value)) .ToArray(); }
private static object ResolveParameter(ICherryServiceLocatorAndRegistry original, ICherryServiceLocatorAndRegistry current, ParameterInfo[] constructorParameterInfos, int i, InjectionParameter[] parameters) { ParameterInfo constructorParameterInfo = constructorParameterInfos[i]; if (parameters == null || parameters.Length == 0) { // Shotcut when no parameters provided return current.Get(original, constructorParameterInfo.ParameterType); } InjectionParameter namedParameter = parameters.SingleOrDefault(p => p.Key == constructorParameterInfo.Name); if (namedParameter != null) { return namedParameter.Value; } // No matching named parameter found, so lets try if we have a single parameter that mathes the constructor parameter type InjectionParameter unnamedParameter = parameters.SingleOrDefault( p => string.IsNullOrEmpty(p.Key) && !ReferenceEquals(p.Value, null) && constructorParameterInfo.ParameterType.IsInstanceOfType(p.Value)); if (unnamedParameter != null) { return unnamedParameter.Value; } return current.Get(original, constructorParameterInfo.ParameterType); }
private void ValidateParameters(IEnumerable<ParameterInfo> constructorParameterInfos, InjectionParameter[] parameters) { if (parameters == null || parameters.Length == 0) { return; } var namedParametersWithoutMatchingConstructorParameter = parameters.Where( p => !string.IsNullOrEmpty(p.Key) && constructorParameterInfos.All(cp => cp.Name != p.Key)); if (namedParametersWithoutMatchingConstructorParameter.Any()) { throw new ArgumentException("The provided parameters contain parameter names that cannot be matched to the constructor of type " + _targetType, "parameters"); } var unnamedParametersByType = parameters .Where(p => string.IsNullOrEmpty(p.Key) && !ReferenceEquals(p.Value, null)) .GroupBy(p => p.Value.GetType()) .Select(p => new {Type = p.Key, Count = p.Count()}) .ToArray(); if (unnamedParametersByType.Any(p => p.Count > 1)) { throw new ArgumentException("The provided parameters contain multiple unnamed parameters with the same type", "parameters"); } if ( unnamedParametersByType.Any( p => constructorParameterInfos.Count(cp => cp.ParameterType.IsAssignableFrom(p.Type)) > 1)) { throw new ArgumentException("The provided parameters contain unnamed parameters that cannot be mapped unambiguously to the constructor of type " + _targetType, "parameters"); } }