public override void Inject(Object target, string objectName, IPropertyValues pvs) { MethodInfo method = _member as MethodInfo; try { Object[] arguments; if (_cached) { arguments = ResolveCachedArguments(objectName); } else { Type[] paramTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); arguments = new Object[paramTypes.Length]; var descriptors = new DependencyDescriptor[paramTypes.Length]; IList autowiredBeanNames = new ArrayList(); for (int i = 0; i < arguments.Length; i++) { MethodParameter methodParam = new MethodParameter(method, i); descriptors[i] = new DependencyDescriptor(methodParam, _required); arguments[i] = _objectFactory.ResolveDependency(descriptors[i], objectName, autowiredBeanNames); if (arguments[i] == null && !_required) { arguments = null; break; } } lock (this) { if (!_cached) { if (arguments != null) { _cachedMethodArguments = new Object[arguments.Length]; for (int i = 0; i < arguments.Length; i++) { _cachedMethodArguments[i] = descriptors[i]; } RegisterDependentObjects(objectName, autowiredBeanNames); if (autowiredBeanNames.Count == paramTypes.Length) { for (int i = 0; i < paramTypes.Length; i++) { string autowiredBeanName = autowiredBeanNames[i] as string; if (_objectFactory.ContainsObject(autowiredBeanName)) { if (_objectFactory.IsTypeMatch(autowiredBeanName, paramTypes[i])) { _cachedMethodArguments[i] = new RuntimeObjectReference(autowiredBeanName); } } } } } else { _cachedMethodArguments = null; } _cached = true; } } } if (arguments != null) { method.Invoke(target, arguments); } } catch (Exception ex) { throw new ObjectCreationException("Could not autowire method: " + method, ex); } }
private IDictionary FindAutowireCandidates(string objectName, Type requiredType, DependencyDescriptor descriptor) { string[] candidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.Eager); IDictionary result = new OrderedDictionary(candidateNames.Length); foreach (DictionaryEntry entry in resolvableDependencies) { Type autoWiringType = (Type)entry.Key; if (autoWiringType.IsAssignableFrom(requiredType)) { object autowiringValue = this.resolvableDependencies[autoWiringType]; if (requiredType.IsInstanceOfType(autowiringValue)) { result.Add(ObjectUtils.IdentityToString(autowiringValue), autowiringValue); break; } } } for (int i = 0; i < candidateNames.Length; i++) { string candidateName = candidateNames[i]; if (!candidateName.Equals(objectName) && IsAutowireCandidate(candidateName, descriptor)) { result.Add(candidateName, GetObject(candidateName)); } } return result; }
public override void Inject(Object instance, String objectName, IPropertyValues pvs) { var field = (FieldInfo) _member; try { Object value; if (_cached) { value = ResolvedCachedArgument(objectName, _cachedFieldValue); } else { var descriptor = new DependencyDescriptor(field, _required); IList autowiredObjectNames = new ArrayList(); value = _objectFactory.ResolveDependency(descriptor, objectName, autowiredObjectNames); lock (this) { if (!_cached) { if (value != null || _required) { _cachedFieldValue = descriptor; RegisterDependentObjects(objectName, autowiredObjectNames); if (autowiredObjectNames.Count == 1) { var autowiredBeanName = autowiredObjectNames[0] as string; if (_objectFactory.ContainsObject(autowiredBeanName)) { if (_objectFactory.IsTypeMatch(autowiredBeanName, field.GetType())) { _cachedFieldValue = new RuntimeObjectReference(autowiredBeanName); } } } } else { _cachedFieldValue = null; } _cached = true; } } } if (value != null) { field.SetValue(instance, value); } } catch (Exception ex) { throw new ObjectCreationException("Could not autowire field: " + field, ex); } }
/// <summary> /// Resolve the specified dependency against the objects defined in this factory. /// </summary> /// <param name="descriptor">The descriptor for the dependency.</param> /// <param name="objectName">Name of the object which declares the present dependency.</param> /// <param name="autowiredObjectNames">A list that all names of autowired object (used for /// resolving the present dependency) are supposed to be added to.</param> /// <returns> /// the resolved object, or <code>null</code> if none found /// </returns> /// <exception cref="ObjectsException">if dependency resolution failed</exception> public override object ResolveDependency(DependencyDescriptor descriptor, string objectName, IList autowiredObjectNames) { Type type = descriptor.DependencyType; if (type.IsArray) { Type elementType = type.GetElementType(); IDictionary matchingObjects = FindAutowireCandidates(objectName, elementType, descriptor); if (matchingObjects.Count == 0) { if (descriptor.Required) { RaiseNoSuchObjectDefinitionException(elementType, "array of " + elementType.FullName, descriptor); } return null; } if (autowiredObjectNames != null) { foreach (DictionaryEntry matchingObject in matchingObjects) { autowiredObjectNames.Add(matchingObject.Key); } } return TypeConversionUtils.ConvertValueIfNecessary(type, matchingObjects.Values, null); } else if (typeof(ICollection).IsAssignableFrom(type) && type.IsInterface) { //TODO - handle generic types. return null; } else { IDictionary matchingObjects = FindAutowireCandidates(objectName, type, descriptor); if (matchingObjects.Count == 0) { if (descriptor.Required) { string methodType = (descriptor.MethodParameter.ConstructorInfo != null) ? "constructor" : "method"; throw new NoSuchObjectDefinitionException(type, "Unsatisfied dependency of type [" + type + "]: expected at least 1 matching object to wire the [" + descriptor.MethodParameter.ParameterName() + "] parameter on the " + methodType + " of object [" + objectName + "]"); } return null; } if (matchingObjects.Count > 1) { throw new NoSuchObjectDefinitionException(type, "expected single matching object but found " + matchingObjects.Count + ": " + matchingObjects); } DictionaryEntry entry = (DictionaryEntry)ObjectUtils.EnumerateFirstElement(matchingObjects); if (autowiredObjectNames != null) { autowiredObjectNames.Add(entry.Key); } return entry.Value; } }
/// <summary> /// Raises the no such object definition exception for an unresolvable dependency /// </summary> /// <param name="type">The type.</param> /// <param name="dependencyDescription">The dependency description.</param> /// <param name="descriptor">The descriptor.</param> private void RaiseNoSuchObjectDefinitionException(Type type, string dependencyDescription, DependencyDescriptor descriptor) { throw new NoSuchObjectDefinitionException(type, dependencyDescription, "expected at least 1 object which qualifies as autowire candidate for this dependency. "); }
/// <summary> /// Determines whether the specified object qualifies as an autowire candidate, /// to be injected into other beans which declare a dependency of matching type. /// This method checks ancestor factories as well. /// </summary> /// <param name="objectName">Name of the object to check.</param> /// <param name="descriptor">The descriptor of the dependency to resolve.</param> /// <returns> /// <c>true</c> if the object should be considered as an autowire candidate; otherwise, <c>false</c>. /// </returns> /// <exception cref="NoSuchObjectDefinitionException">if there is no object with the given name.</exception> public bool IsAutowireCandidate(string objectName, DependencyDescriptor descriptor) { //Consider FactoryObjects as autowiring candidates. bool isFactoryObject = (descriptor != null && descriptor.DependencyType != null && typeof(IFactoryObject).IsAssignableFrom(descriptor.DependencyType)); if (isFactoryObject) { objectName = ObjectFactoryUtils.TransformedObjectName(objectName); } if (!ContainsObjectDefinition(objectName)) { if (ContainsSingleton(objectName)) { return true; } else if (ParentObjectFactory is IConfigurableListableObjectFactory) { // No object definition found in this factory -> delegate to parent return ((IConfigurableListableObjectFactory)ParentObjectFactory).IsAutowireCandidate(objectName, descriptor); } } return IsAutowireCandidate(objectName, GetMergedObjectDefinition(objectName, true), descriptor); }
/// <summary> /// Determine whether the specified object definition qualifies as an autowire candidate, /// to be injected into other beans which declare a dependency of matching type. /// </summary> /// <param name="objectName">Name of the object definition to check.</param> /// <param name="rod">The merged object definiton to check.</param> /// <param name="descriptor">The descriptor of the dependency to resolve.</param> /// <returns> /// <c>true</c> if the object should be considered as an autowire candidate; otherwise, <c>false</c>. /// </returns> private bool IsAutowireCandidate(string objectName, RootObjectDefinition rod, DependencyDescriptor descriptor) { ResolveObjectType(rod, objectName); return AutowireCandidateResolver.IsAutowireCandidate( new ObjectDefinitionHolder(rod, objectName, GetAliases(objectName)), descriptor); }
/// <summary> /// Determines whether the given object definition qualifies as an /// autowire candidate for the given dependency. /// </summary> /// <param name="odHolder">The object definition including object name and aliases.</param> /// <param name="descriptor">The descriptor for the target method parameter or field.</param> /// <returns> /// <c>true</c> if the object definition qualifies as autowire candidate; otherwise, <c>false</c>. /// </returns> public bool IsAutowireCandidate(ObjectDefinitionHolder odHolder, DependencyDescriptor descriptor) { return odHolder.ObjectDefinition.IsAutowireCandidate; }
/// <summary> /// Determine whether a default value is suggested for the given dependency. /// </summary> /// <param name="descriptor">The descriptor for the target method parameter or field</param> /// <returns>The value suggested (typically an expression String), /// or <c>null</c> if none found /// </returns> public object GetSuggestedValue(DependencyDescriptor descriptor) { return null; }
/// <summary> /// Resolve the specified dependency against the objects defined in this factory. /// </summary> /// <param name="descriptor">The descriptor for the dependency.</param> /// <param name="objectName">Name of the object which declares the present dependency.</param> /// <param name="autowiredObjectNames">A list that all names of autowired object (used for /// resolving the present dependency) are supposed to be added to.</param> /// <returns> /// the resolved object, or <code>null</code> if none found /// </returns> /// <exception cref="ObjectsException">if dependency resolution failed</exception> public abstract object ResolveDependency(DependencyDescriptor descriptor, string objectName, IList autowiredObjectNames);
/// <summary> /// Determine whether the given dependency carries a value attribute. /// </summary> public Object GetSuggestedValue(DependencyDescriptor descriptor) { Object value = FindValue(descriptor.Attributes); if (value == null) { MethodParameter methodParam = descriptor.MethodParameter; if (methodParam != null) { value = FindValue(methodParam.MethodAttributes); } } return value; }
/// <summary> /// Determine whether the provided object definition is an autowire candidate. /// <p>To be considered a candidate the object's <em>autowire-candidate</em> /// attribute must not have been set to 'false'. Also, if an attribute on /// the field or parameter to be autowired is recognized by this bean factory /// as a <em>qualifier</em>, the object must 'match' against the attribute as /// well as any attributes it may contain. The bean definition must contain /// the same qualifier or match by meta attributes. A "value" attribute will /// fallback to match against the bean name or an alias if a qualifier or /// attribute does not match.</p> /// </summary> public bool IsAutowireCandidate(ObjectDefinitionHolder odHolder, DependencyDescriptor descriptor) { if (!odHolder.ObjectDefinition.IsAutowireCandidate) { // if explicitly false, do not proceed with qualifier check return false; } if (descriptor == null) { // no qualification necessaryodHolder return true; } bool match = CheckQualifiers(odHolder, descriptor.Attributes); if (match) { MethodParameter methodParam = descriptor.MethodParameter; if (methodParam != null) { var method = methodParam.MethodInfo; if (method == null || method.ReturnType == typeof(void)) { match = CheckQualifiers(odHolder, methodParam.MethodAttributes); } } } return match; }