IObjectDefinition IObjectDefinitionParser.ParseElement(XmlElement element, ParserContext parserContext) { AssertUtils.ArgumentNotNull(parserContext, "parserContext"); string id = element.GetAttribute(ObjectDefinitionConstants.IdAttribute); string hostBaseUri = element.GetAttribute(HostBaseUriAttribute); string timeout = element.GetAttribute(TimeOutAttribute); if (hostBaseUri.IsNullOrEmpty()) { Console.WriteLine("创建Rest客户端实例异常:没有填写hostBaseUri配置"); Exception ex = new Exception("创建Rest客户端实例异常:没有填写hostBaseUri配置"); throw ex; } ConstructorArgumentValues cav = new ConstructorArgumentValues(); cav.AddNamedArgumentValue("baseUrl", hostBaseUri); MutablePropertyValues mpv = new MutablePropertyValues(); mpv.Add("TimeOut", timeout); RootObjectDefinition rod = new RootObjectDefinition(typeof(RestClient), cav, mpv); parserContext.Registry.RegisterObjectDefinition(id, rod); return(null); }
/// <summary> /// Constructs the task chain /// </summary> protected virtual void ResolveChain(string chainConfigurationAlias) { // Types from the merchello.config file var typeList = ChainTaskResolver.GetTypesForChain(chainConfigurationAlias).ToArray(); if (!typeList.Any()) { return; } // instantiate each task in the chain TaskHandlers.AddRange( typeList.Select( typeName => new AttemptChainTaskHandler <T>( ActivatorHelper.CreateInstance <AttemptChainTaskBase <T> >( typeName, ConstructorArgumentValues.ToArray()).Result ))); // register the next task for each link (these are linear chains) foreach (var taskHandler in TaskHandlers.Where(task => TaskHandlers.IndexOf(task) != TaskHandlers.IndexOf(TaskHandlers.Last()))) { taskHandler.RegisterNext(TaskHandlers[TaskHandlers.IndexOf(taskHandler) + 1]); } }
private IObjectDefinition ParseExceptionAction(XmlElement element, ParserContext parserContext) { string typeName = "Spring.Validation.Actions.ExceptionAction, Spring.Core"; string throwExpression = GetAttributeValue(element, ValidatorDefinitionConstants.ThrowAttribute); ConstructorArgumentValues ctorArgs = new ConstructorArgumentValues(); ctorArgs.AddGenericArgumentValue(throwExpression); string when = GetAttributeValue(element, ValidatorDefinitionConstants.WhenAttribute); MutablePropertyValues properties = new MutablePropertyValues(); if (StringUtils.HasText(when)) { properties.Add("When", when); } IConfigurableObjectDefinition action = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserContext.ReaderContext.Reader.Domain); action.ConstructorArgumentValues = ctorArgs; action.PropertyValues = properties; return(action); }
protected AbstractObjectDefinition(SerializationInfo info, StreamingContext context) { constructorArgumentValues = (ConstructorArgumentValues)info.GetValue("constructorArgumentValues", typeof(ConstructorArgumentValues)); propertyValues = (MutablePropertyValues)info.GetValue("propertyValues", typeof(MutablePropertyValues)); eventHandlerValues = (EventValues)info.GetValue("eventHandlerValues", typeof(EventValues)); methodOverrides = (MethodOverrides)info.GetValue("methodOverrides", typeof(MethodOverrides)); resourceDescription = info.GetString("resourceDescription"); isSingleton = info.GetBoolean("isSingleton"); isPrototype = info.GetBoolean("isPrototype"); isLazyInit = info.GetBoolean("isLazyInit"); isAbstract = info.GetBoolean("isAbstract"); scope = info.GetString("scope"); role = (ObjectRole)info.GetValue("role", typeof(ObjectRole)); var objectTypeName = info.GetString("objectTypeName"); objectType = objectTypeName != null?Type.GetType(objectTypeName) : null; autowireMode = (AutoWiringMode)info.GetValue("autowireMode", typeof(AutoWiringMode)); dependencyCheck = (DependencyCheckingMode)info.GetValue("dependencyCheck", typeof(DependencyCheckingMode)); dependsOn = (IList <string>)info.GetValue("dependsOn", typeof(IList <string>)); autowireCandidate = info.GetBoolean("autowireCandidate"); primary = info.GetBoolean("primary"); qualifiers = (IDictionary <string, AutowireCandidateQualifier>)info.GetValue("qualifiers", typeof(IDictionary <string, AutowireCandidateQualifier>)); initMethodName = info.GetString("initMethodName"); destroyMethodName = info.GetString("destroyMethodName"); factoryMethodName = info.GetString("factoryMethodName"); factoryObjectName = info.GetString("factoryObjectName"); }
public void ProxyTransparentProxy() { DefaultListableObjectFactory of = new DefaultListableObjectFactory(); ConstructorArgumentValues ctorArgs = new ConstructorArgumentValues(); ctorArgs.AddNamedArgumentValue("objectType", typeof(ITestObject)); of.RegisterObjectDefinition("bar", new RootObjectDefinition(typeof(TransparentProxyFactory), ctorArgs, null)); TestAutoProxyCreator apc = new TestAutoProxyCreator(of); of.AddObjectPostProcessor(apc); ITestObject o = of.GetObject("bar") as ITestObject; Assert.IsTrue(AopUtils.IsAopProxy(o)); // ensure interceptors get called o.Foo(); Assert.AreEqual(1, apc.NopInterceptor.Count); IAdvised advised = (IAdvised)o; // ensure target was called object target = advised.TargetSource.GetTarget(); Assert.AreEqual(1, TransparentProxyFactory.GetRealProxy(target).Count); }
private void InitFactory(DefaultListableObjectFactory factory) { Console.WriteLine("init factory"); RootObjectDefinition tee = new RootObjectDefinition(typeof(Tee), true); tee.IsLazyInit = true; ConstructorArgumentValues teeValues = new ConstructorArgumentValues(); teeValues.AddGenericArgumentValue("test"); tee.ConstructorArgumentValues = teeValues; RootObjectDefinition bar = new RootObjectDefinition(typeof(BBar), false); ConstructorArgumentValues barValues = new ConstructorArgumentValues(); barValues.AddGenericArgumentValue(new RuntimeObjectReference("tee")); barValues.AddGenericArgumentValue(5); bar.ConstructorArgumentValues = barValues; RootObjectDefinition foo = new RootObjectDefinition(typeof(FFoo), false); MutablePropertyValues fooValues = new MutablePropertyValues(); fooValues.Add("i", 5); fooValues.Add("bar", new RuntimeObjectReference("bar")); fooValues.Add("copy", new RuntimeObjectReference("bar")); fooValues.Add("s", "test"); foo.PropertyValues = fooValues; factory.RegisterObjectDefinition("foo", foo); factory.RegisterObjectDefinition("bar", bar); factory.RegisterObjectDefinition("tee", tee); }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Support.RootObjectDefinition"/> class /// for a singleton, providing property values and constructor arguments. /// </summary> /// <param name="typeName"> /// The assembly qualified <see cref="System.Type.FullName"/> of the object to instantiate. /// </param> /// <param name="properties"> /// The <see cref="Spring.Objects.MutablePropertyValues"/> to be applied to /// a new instance of the object. /// </param> /// <param name="arguments"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be applied to a new instance of the object. /// </param> /// <remarks> /// <p> /// Takes an object class name to avoid eager loading of the object class. /// </p> /// </remarks> public RootWebObjectDefinition( string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(typeName, arguments, properties) { }
/// <summary> /// Creates an error message action based on the specified message element. /// </summary> /// <param name="message">The message element.</param> /// <param name="parserContext">The parser helper.</param> /// <returns>The error message action definition.</returns> private static IObjectDefinition ParseErrorMessageAction(XmlElement message, ParserContext parserContext) { string messageId = GetAttributeValue(message, MessageConstants.IdAttribute); string[] providers = GetAttributeValue(message, MessageConstants.ProvidersAttribute).Split(','); ArrayList parameters = new ArrayList(); foreach (XmlElement param in message.ChildNodes) { IExpression paramExpression = Expression.Parse(GetAttributeValue(param, MessageConstants.ParameterValueAttribute)); parameters.Add(paramExpression); } string typeName = "Spring.Validation.Actions.ErrorMessageAction, Spring.Core"; ConstructorArgumentValues ctorArgs = new ConstructorArgumentValues(); ctorArgs.AddGenericArgumentValue(messageId); ctorArgs.AddGenericArgumentValue(providers); string when = GetAttributeValue(message, ValidatorDefinitionConstants.WhenAttribute); MutablePropertyValues properties = new MutablePropertyValues(); if (StringUtils.HasText(when)) { properties.Add("When", when); } if (parameters.Count > 0) { properties.Add("Parameters", parameters.ToArray(typeof(IExpression))); } IConfigurableObjectDefinition action = parserContext.ReaderContext.ObjectDefinitionFactory.CreateObjectDefinition(typeName, null, parserContext.ReaderContext.Reader.Domain); action.ConstructorArgumentValues = ctorArgs; action.PropertyValues = properties; return action; }
/// <summary> /// Creates a new instance of the /// <see cref="Oragon.Spring.Objects.Factory.Support.ChildObjectDefinition"/> /// class. /// </summary> /// <param name="parentName"> /// The name of the parent object. /// </param> /// <param name="typeName"> /// The <see cref="System.Type.AssemblyQualifiedName"/> of the object to /// instantiate. /// </param> /// <param name="arguments"> /// The <see cref="Oragon.Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be applied to a new instance of the object. /// </param> /// <param name="properties"> /// The additional property values (if any) of the child. /// </param> public ChildObjectDefinition( string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(arguments, properties) { this.parentName = parentName; ObjectTypeName = typeName; }
/// <summary> /// Override settings in this object definition from the supplied /// <paramref name="other"/> object definition. /// </summary> /// <param name="other"> /// The object definition used to override the member fields of this instance. /// </param> public virtual void OverrideFrom(IObjectDefinition other) { AssertUtils.ArgumentNotNull(other, "other"); IsAbstract = other.IsAbstract; Scope = other.Scope; IsLazyInit = other.IsLazyInit; ConstructorArgumentValues.AddAll(other.ConstructorArgumentValues); PropertyValues.AddAll(other.PropertyValues.PropertyValues); EventHandlerValues.AddAll(other.EventHandlerValues); if (StringUtils.HasText(other.ObjectTypeName)) { ObjectTypeName = other.ObjectTypeName; } if (StringUtils.HasText(other.InitMethodName)) { InitMethodName = other.InitMethodName; } if (StringUtils.HasText(other.DestroyMethodName)) { DestroyMethodName = other.DestroyMethodName; } if (StringUtils.HasText(other.FactoryObjectName)) { FactoryObjectName = other.FactoryObjectName; } if (StringUtils.HasText(other.FactoryMethodName)) { FactoryMethodName = other.FactoryMethodName; } if (other.DependsOn != null && other.DependsOn.Count > 0) { List <string> deps = new List <string>(other.DependsOn); if (DependsOn != null && DependsOn.Count > 0) { deps.AddRange(DependsOn); } DependsOn = deps; } AutowireMode = other.AutowireMode; ResourceDescription = other.ResourceDescription; IsPrimary = other.IsPrimary; IsAutowireCandidate = other.IsAutowireCandidate; AbstractObjectDefinition aod = other as AbstractObjectDefinition; if (aod != null) { if (aod.HasObjectType) { ObjectType = other.ObjectType; } MethodOverrides.AddAll(aod.MethodOverrides); DependencyCheck = aod.DependencyCheck; CopyQualifiersFrom(aod); } }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Support.AbstractObjectDefinition"/> /// class. /// </summary> /// <remarks> /// <p> /// This is an <see langword="abstract"/> class, and as such exposes no /// public constructors. /// </p> /// </remarks> protected AbstractObjectDefinition(ConstructorArgumentValues arguments, MutablePropertyValues properties) { constructorArgumentValues = (arguments != null) ? arguments : new ConstructorArgumentValues(); propertyValues = (properties != null) ? properties : new MutablePropertyValues(); eventHandlerValues = new EventValues(); DependsOn = StringUtils.EmptyStrings; }
/// <summary> /// Override settings in this object definition from the supplied /// <paramref name="other"/> object definition. /// </summary> /// <param name="other"> /// The object definition used to override the member fields of this instance. /// </param> public virtual void OverrideFrom(IObjectDefinition other) { AssertUtils.ArgumentNotNull(other, "other"); IsAbstract = other.IsAbstract; Scope = other.Scope; IsLazyInit = other.IsLazyInit; ConstructorArgumentValues.AddAll(other.ConstructorArgumentValues); PropertyValues.AddAll(other.PropertyValues.PropertyValues); EventHandlerValues.AddAll(other.EventHandlerValues); if (StringUtils.HasText(other.ObjectTypeName)) { ObjectTypeName = other.ObjectTypeName; } if (StringUtils.HasText(other.InitMethodName)) { InitMethodName = other.InitMethodName; } if (StringUtils.HasText(other.DestroyMethodName)) { DestroyMethodName = other.DestroyMethodName; } if (StringUtils.HasText(other.FactoryObjectName)) { FactoryObjectName = other.FactoryObjectName; } if (StringUtils.HasText(other.FactoryMethodName)) { FactoryMethodName = other.FactoryMethodName; } if (ArrayUtils.HasLength(other.DependsOn)) { ArrayList deps = new ArrayList(other.DependsOn); if (ArrayUtils.HasLength(DependsOn)) { deps.AddRange(DependsOn); } DependsOn = (string[])deps.ToArray(typeof(string)); } AutowireMode = other.AutowireMode; ResourceDescription = other.ResourceDescription; AbstractObjectDefinition aod = other as AbstractObjectDefinition; if (aod != null) { if (aod.HasObjectType) { ObjectType = other.ObjectType; } MethodOverrides.AddAll(aod.MethodOverrides); DependencyCheck = aod.DependencyCheck; } }
/// <summary> /// Resolves the <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// of the supplied <paramref name="definition"/>. /// </summary> /// <param name="objectName">The name of the object that is being resolved by this factory.</param> /// <param name="definition">The rod.</param> /// <param name="wrapper">The wrapper.</param> /// <param name="cargs">The cargs.</param> /// <param name="resolvedValues">Where the resolved constructor arguments will be placed.</param> /// <returns> /// The minimum number of arguments that any constructor for the supplied /// <paramref name="definition"/> must have. /// </returns> /// <remarks> /// <p> /// 'Resolve' can be taken to mean that all of the <paramref name="definition"/>s /// constructor arguments is resolved into a concrete object that can be plugged /// into one of the <paramref name="definition"/>s constructors. Runtime object /// references to other objects in this (or a parent) factory are resolved, /// type conversion is performed, etc. /// </p> /// <p> /// These resolved values are plugged into the supplied /// <paramref name="resolvedValues"/> object, because we wouldn't want to touch /// the <paramref name="definition"/>s constructor arguments in case it (or any of /// its constructor arguments) is a prototype object definition. /// </p> /// <p> /// This method is also used for handling invocations of static factory methods. /// </p> /// </remarks> private int ResolveConstructorArguments(string objectName, RootObjectDefinition definition, ObjectWrapper wrapper, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { // ObjectDefinitionValueResolver valueResolver = new ObjectDefinitionValueResolver(objectFactory); int minNrOfArgs = cargs.ArgumentCount; foreach (DictionaryEntry entry in cargs.IndexedArgumentValues) { int index = Convert.ToInt32(entry.Key); if (index < 0) { throw new ObjectCreationException(definition.ResourceDescription, objectName, "Invalid constructor agrument index: " + index); } if (index > minNrOfArgs) { minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)entry.Value; string argName = "constructor argument with index " + index; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value); resolvedValues.AddIndexedArgumentValue(index, resolvedValue, StringUtils.HasText(valueHolder.Type) ? TypeResolutionUtils.ResolveType(valueHolder.Type). AssemblyQualifiedName : null); } foreach (ConstructorArgumentValues.ValueHolder valueHolder in definition.ConstructorArgumentValues.GenericArgumentValues) { string argName = "constructor argument"; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value); resolvedValues.AddGenericArgumentValue(resolvedValue, StringUtils.HasText(valueHolder.Type) ? TypeResolutionUtils.ResolveType(valueHolder.Type). AssemblyQualifiedName : null); } foreach (DictionaryEntry namedArgumentEntry in definition.ConstructorArgumentValues.NamedArgumentValues) { string argumentName = (string)namedArgumentEntry.Key; string syntheticArgumentName = "constructor argument with name " + argumentName; ConstructorArgumentValues.ValueHolder valueHolder = (ConstructorArgumentValues.ValueHolder)namedArgumentEntry.Value; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, syntheticArgumentName, valueHolder.Value); resolvedValues.AddNamedArgumentValue(argumentName, resolvedValue); } return(minNrOfArgs); }
/// <summary> /// Gets the Spring IDbProvider given the ISessionFactory. /// </summary> /// <remarks>The matching is performed by comparing the assembly qualified /// name string of the hibernate Driver.ConnectionType to those in /// the DbProviderFactory definitions. No connections are created /// in performing this comparison.</remarks> /// <param name="sessionFactory">The session factory.</param> /// <returns>The corresponding IDbProvider, null if no mapping was found.</returns> /// <exception cref="InvalidOperationException">If DbProviderFactory's ApplicaitonContext is not /// an instance of IConfigurableApplicaitonContext.</exception> public static IDbProvider GetDbProvider(ISessionFactory sessionFactory) { ISessionFactoryImplementor sfi = sessionFactory as ISessionFactoryImplementor; if (sfi != null) { IConnectionProvider cp = sfi.ConnectionProvider as IConnectionProvider; if (cp != null) { IConfigurableApplicationContext ctx = Spring.Data.Common.DbProviderFactory.ApplicationContext as IConfigurableApplicationContext; if (ctx == null) { throw new InvalidOperationException( "Implementations of IApplicationContext must also implement IConfigurableApplicationContext"); } #if NET_1_1 DriverBase db = cp.Driver as DriverBase; #else IDriver db = cp.Driver; #endif if (db != null) { Type hibCommandType = db.CreateCommand().GetType(); string[] providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false); string hibCommandAQN = hibCommandType.AssemblyQualifiedName; foreach (string providerName in providerNames) { IObjectDefinition objectdef = ctx.ObjectFactory.GetObjectDefinition(providerName); ConstructorArgumentValues ctorArgs = objectdef.ConstructorArgumentValues; ConstructorArgumentValues.ValueHolder vh = ctorArgs.NamedArgumentValues["dbmetadata"] as ConstructorArgumentValues.ValueHolder; IObjectDefinition od = ((ObjectDefinitionHolder)vh.Value).ObjectDefinition; ConstructorArgumentValues dbmdCtorArgs = od.ConstructorArgumentValues; string commandType = dbmdCtorArgs.GetArgumentValue("commandType", typeof(string)).Value as string; if (hibCommandAQN.Equals(commandType)) { IDbProvider prov = Spring.Data.Common.DbProviderFactory.GetDbProvider(providerName); return(prov); } } } else { log.Info("Could not derive IDbProvider from SessionFactory"); } } } return(null); }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Support.AbstractObjectDefinition"/> /// class. /// </summary> /// <param name="other"> /// The object definition used to initialise the member fields of this /// instance. /// </param> /// <remarks> /// <p> /// This is an <see langword="abstract"/> class, and as such exposes no /// public constructors. /// </p> /// </remarks> protected AbstractObjectDefinition(IObjectDefinition other) { AssertUtils.ArgumentNotNull(other, "other"); OverrideFrom(other); AbstractObjectDefinition aod = other as AbstractObjectDefinition; if (aod != null) { if (aod.HasObjectType) { ObjectType = other.ObjectType; } else { ObjectTypeName = other.ObjectTypeName; } MethodOverrides = new MethodOverrides(aod.MethodOverrides); DependencyCheck = aod.DependencyCheck; } ParentName = other.ParentName; IsAbstract = other.IsAbstract; // IsSingleton = other.IsSingleton; Scope = other.Scope; Role = other.Role; IsLazyInit = other.IsLazyInit; ConstructorArgumentValues = new ConstructorArgumentValues(other.ConstructorArgumentValues); PropertyValues = new MutablePropertyValues(other.PropertyValues); EventHandlerValues = new EventValues(other.EventHandlerValues); InitMethodName = other.InitMethodName; DestroyMethodName = other.DestroyMethodName; IsAutowireCandidate = other.IsAutowireCandidate; IsPrimary = other.IsPrimary; CopyQualifiersFrom(aod); if (other.DependsOn.Count > 0) { DependsOn = other.DependsOn; } FactoryMethodName = other.FactoryMethodName; FactoryObjectName = other.FactoryObjectName; AutowireMode = other.AutowireMode; ResourceDescription = other.ResourceDescription; }
public void SetsUpMongoDbFactoryUsingAMongoConnectStringWithoutCredentials() { string xml = @"<?xml version='1.0' encoding='UTF-8' ?> <objects xmlns='http://www.springframework.net' xmlns:mongo='http://www.springframework.net/mongo'> <mongo:db-factory url='mongodb://localhost/database' /> </objects>"; var factory = new XmlObjectFactory(new StringResource(xml, Encoding.UTF8)); IObjectDefinition definition = factory.GetObjectDefinition("MongoDatabaseFactory"); ConstructorArgumentValues constructorArguments = definition.ConstructorArgumentValues; Assert.That(constructorArguments.ArgumentCount, Is.EqualTo(1)); var argument = constructorArguments.GetArgumentValue(0, typeof(MongoUrl)); Assert.That(argument, Is.Not.Null); var dbFactory = factory.GetObject <IMongoDatabaseFactory>("MongoDatabaseFactory"); var db = dbFactory.GetDatabase(); Assert.That(db.Name, Is.EqualTo("database")); }
/// <summary> /// Resolves the <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// of the supplied <paramref name="definition"/>. /// </summary> /// <param name="objectName">The name of the object that is being resolved by this factory.</param> /// <param name="definition">The rod.</param> /// <param name="wrapper">The wrapper.</param> /// <param name="cargs">The cargs.</param> /// <param name="resolvedValues">Where the resolved constructor arguments will be placed.</param> /// <returns> /// The minimum number of arguments that any constructor for the supplied /// <paramref name="definition"/> must have. /// </returns> /// <remarks> /// <p> /// 'Resolve' can be taken to mean that all of the <paramref name="definition"/>s /// constructor arguments is resolved into a concrete object that can be plugged /// into one of the <paramref name="definition"/>s constructors. Runtime object /// references to other objects in this (or a parent) factory are resolved, /// type conversion is performed, etc. /// </p> /// <p> /// These resolved values are plugged into the supplied /// <paramref name="resolvedValues"/> object, because we wouldn't want to touch /// the <paramref name="definition"/>s constructor arguments in case it (or any of /// its constructor arguments) is a prototype object definition. /// </p> /// <p> /// This method is also used for handling invocations of static factory methods. /// </p> /// </remarks> private int ResolveConstructorArguments(string objectName, RootObjectDefinition definition, ObjectWrapper wrapper, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { // ObjectDefinitionValueResolver valueResolver = new ObjectDefinitionValueResolver(objectFactory); int minNrOfArgs = cargs.ArgumentCount; if (cargs._indexedArgumentValues != null) { foreach (var entry in cargs._indexedArgumentValues) { int index = entry.Key; if (index < 0) { throw new ObjectCreationException( definition.ResourceDescription, objectName, $"Invalid constructor argument index: {index}"); } if (index > minNrOfArgs) { minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = entry.Value; string argName = "constructor argument with index " + index; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value); resolvedValues.AddIndexedArgumentValue(index, resolvedValue, StringUtils.HasText(valueHolder.Type) ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName : null); } } if (definition.ConstructorArgumentValues._genericArgumentValues != null) { const string argName = "constructor argument"; for (var i = 0; i < definition.ConstructorArgumentValues._genericArgumentValues.Count; i++) { var valueHolder = definition.ConstructorArgumentValues._genericArgumentValues[i]; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, argName, valueHolder.Value); resolvedValues.AddGenericArgumentValue( resolvedValue, StringUtils.HasText(valueHolder.Type) ? TypeResolutionUtils.ResolveType(valueHolder.Type).AssemblyQualifiedName : null); } } if (definition.ConstructorArgumentValues._namedArgumentValues != null) { foreach (var entry in definition.ConstructorArgumentValues._namedArgumentValues) { string argumentName = entry.Key; string syntheticArgumentName = "constructor argument with name " + argumentName; ConstructorArgumentValues.ValueHolder valueHolder = entry.Value; object resolvedValue = valueResolver.ResolveValueIfNecessary(objectName, definition, syntheticArgumentName, valueHolder.Value); resolvedValues.AddNamedArgumentValue(argumentName, resolvedValue); } } return(minNrOfArgs); }
/// <summary> /// Creates a new instance of the /// <see cref="Oragon.Spring.Objects.Factory.Support.RootObjectDefinition"/> class /// for a singleton, providing property values and constructor arguments. /// </summary> /// <param name="type"> /// The <see cref="System.Type"/> of the object to instantiate. /// </param> /// <param name="arguments"> /// The <see cref="Oragon.Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be applied to a new instance of the object. /// </param> /// <param name="properties"> /// The <see cref="Oragon.Spring.Objects.MutablePropertyValues"/> to be applied to /// a new instance of the object. /// </param> public RootObjectDefinition( Type type, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(arguments, properties) { ObjectType = type; }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Support.ChildWebObjectDefinition"/> class /// for a singleton, providing property values and constructor arguments. /// </summary> /// <param name="parentName">Name of the parent object definition.</param> /// <param name="typeName">The class name of the object to instantiate.</param> /// <param name="arguments"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be applied to a new instance of the object. /// </param> /// <param name="properties"> /// The <see cref="Spring.Objects.MutablePropertyValues"/> to be applied to /// a new instance of the object. /// </param> public ChildWebObjectDefinition(string parentName, string typeName, ConstructorArgumentValues arguments, MutablePropertyValues properties) : base(parentName, typeName, arguments, properties) { }
/// <summary> /// Gets the constructor instantiation info given the object definition. /// </summary> /// <param name="objectName">Name of the object.</param> /// <param name="rod">The RootObjectDefinition</param> /// <param name="chosenCtors">The explicitly chosen ctors.</param> /// <param name="explicitArgs">The explicit chose ctor args.</param> /// <returns>A ConstructorInstantiationInfo containg the specified constructor in the RootObjectDefinition or /// one based on type matching.</returns> public ConstructorInstantiationInfo GetConstructorInstantiationInfo(string objectName, RootObjectDefinition rod, ConstructorInfo[] chosenCtors, object[] explicitArgs) { ObjectWrapper wrapper = new ObjectWrapper(); ConstructorInfo constructorToUse = null; object[] argsToUse = null; if (explicitArgs != null) { argsToUse = explicitArgs; } else { //TODO performance optmization on cached ctors. } // Need to resolve the constructor. bool autowiring = (chosenCtors != null || rod.ResolvedAutowireMode == AutoWiringMode.Constructor); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs = 0; if (explicitArgs != null) { minNrOfArgs = explicitArgs.Length; } else { ConstructorArgumentValues cargs = rod.ConstructorArgumentValues; resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = ResolveConstructorArguments(objectName, rod, wrapper, cargs, resolvedValues); } // Take specified constructors, if any. ConstructorInfo[] candidates = (chosenCtors != null ? chosenCtors : AutowireUtils.GetConstructors(rod, 0)); AutowireUtils.SortConstructors(candidates); int minTypeDiffWeight = Int32.MaxValue; for (int i = 0; i < candidates.Length; i++) { ConstructorInfo candidate = candidates[i]; Type[] paramTypes = ReflectionUtils.GetParameterTypes(candidate.GetParameters()); if (constructorToUse != null && argsToUse.Length > paramTypes.Length) { // already found greedy constructor that can be satisfied, so // don't look any further, there are only less greedy constructors left... break; } if (paramTypes.Length < minNrOfArgs) { throw new ObjectCreationException(rod.ResourceDescription, objectName, string.Format(CultureInfo.InvariantCulture, "'{0}' constructor arguments specified but no matching constructor found " + "in object '{1}' (hint: specify argument indexes, names, or " + "types to avoid ambiguities).", minNrOfArgs, objectName)); } ArgumentsHolder args = null; if (resolvedValues != null) { UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; // Try to resolve arguments for current constructor //need to check for null as indicator of no ctor arg match instead of using exceptions for flow //control as in the Java implementation args = CreateArgumentArray(objectName, rod, resolvedValues, wrapper, paramTypes, candidate, autowiring, out unsatisfiedDependencyExceptionData); if (args == null) { if (i == candidates.Length - 1 && constructorToUse == null) { throw new UnsatisfiedDependencyException(rod.ResourceDescription, objectName, unsatisfiedDependencyExceptionData.ParameterIndex, unsatisfiedDependencyExceptionData.ParameterType, unsatisfiedDependencyExceptionData.ErrorMessage); } // try next constructor... continue; } } else { // Explicit arguments given -> arguments length must match exactly if (paramTypes.Length != explicitArgs.Length) { continue; } args = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = args.GetTypeDifferenceWeight(paramTypes); // Choose this constructor if it represents the closest match. if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsToUse = args.arguments; minTypeDiffWeight = typeDiffWeight; } } if (constructorToUse == null) { throw new ObjectCreationException(rod.ResourceDescription, objectName, "Could not resolve matching constructor."); } return(new ConstructorInstantiationInfo(constructorToUse, argsToUse)); }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Support.AbstractObjectDefinition"/> /// class. /// </summary> /// <remarks> /// <p> /// This is an <see langword="abstract"/> class, and as such exposes no /// public constructors. /// </p> /// </remarks> protected AbstractObjectDefinition(ConstructorArgumentValues arguments, MutablePropertyValues properties) { constructorArgumentValues = arguments ?? constructorArgumentValues ?? new ConstructorArgumentValues(); propertyValues = properties ?? propertyValues ?? new MutablePropertyValues(); }
/// <summary> /// Instantiate an object instance using a named factory method. /// </summary> /// <remarks> /// <p> /// The method may be static, if the <paramref name="definition"/> /// parameter specifies a class, rather than a /// <see cref="Spring.Objects.Factory.IFactoryObject"/> instance, or an /// instance variable on a factory object itself configured using Dependency /// Injection. /// </p> /// <p> /// Implementation requires iterating over the static or instance methods /// with the name specified in the supplied <paramref name="definition"/> /// (the method may be overloaded) and trying to match with the parameters. /// We don't have the types attached to constructor args, so trial and error /// is the only way to go here. /// </p> /// </remarks> /// <param name="name"> /// The name associated with the supplied <paramref name="definition"/>. /// </param> /// <param name="definition"> /// The definition describing the instance that is to be instantiated. /// </param> /// <param name="arguments"> /// Any arguments to the factory method that is to be invoked. /// </param> /// <returns> /// The result of the factory method invocation (the instance). /// </returns> public virtual IObjectWrapper InstantiateUsingFactoryMethod(string name, RootObjectDefinition definition, object[] arguments) { ObjectWrapper wrapper = new ObjectWrapper(); Type factoryClass = null; bool isStatic = true; ConstructorArgumentValues cargs = definition.ConstructorArgumentValues; ConstructorArgumentValues resolvedValues = new ConstructorArgumentValues(); int expectedArgCount = 0; // we don't have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the object definition... if (arguments == null || arguments.Length == 0) { expectedArgCount = cargs.ArgumentCount; ResolveConstructorArguments(name, definition, wrapper, cargs, resolvedValues); } else { // if we have constructor args, don't need to resolve them... expectedArgCount = arguments.Length; } if (StringUtils.HasText(definition.FactoryObjectName)) { // it's an instance method on the factory object's class... factoryClass = objectFactory.GetObject(definition.FactoryObjectName).GetType(); isStatic = false; } else { // it's a static factory method on the object class... factoryClass = definition.ObjectType; } GenericArgumentsHolder genericArgsInfo = new GenericArgumentsHolder(definition.FactoryMethodName); IList <MethodInfo> factoryMethodCandidates = FindMethods(genericArgsInfo.GenericMethodName, expectedArgCount, isStatic, factoryClass); bool autowiring = (definition.AutowireMode == AutoWiringMode.Constructor); // try all matching methods to see if they match the constructor arguments... for (int i = 0; i < factoryMethodCandidates.Count; i++) { MethodInfo factoryMethodCandidate = factoryMethodCandidates[i]; if (genericArgsInfo.ContainsGenericArguments) { string[] unresolvedGenericArgs = genericArgsInfo.GetGenericArguments(); if (factoryMethodCandidate.GetGenericArguments().Length != unresolvedGenericArgs.Length) { continue; } Type[] paramTypes = new Type[unresolvedGenericArgs.Length]; for (int j = 0; j < unresolvedGenericArgs.Length; j++) { paramTypes[j] = TypeResolutionUtils.ResolveType(unresolvedGenericArgs[j]); } factoryMethodCandidate = factoryMethodCandidate.MakeGenericMethod(paramTypes); } if (arguments == null || arguments.Length == 0) { Type[] paramTypes = ReflectionUtils.GetParameterTypes(factoryMethodCandidate.GetParameters()); // try to create the required arguments... UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null; ArgumentsHolder args = CreateArgumentArray(name, definition, resolvedValues, wrapper, paramTypes, factoryMethodCandidate, autowiring, out unsatisfiedDependencyExceptionData); if (args == null) { arguments = null; // if we failed to match this method, keep // trying new overloaded factory methods... continue; } else { arguments = args.arguments; } } // if we get here, we found a usable candidate factory method - check, if arguments match //arguments = (arguments.Length == 0 ? null : arguments); if (ReflectionUtils.GetMethodByArgumentValues(new MethodInfo[] { factoryMethodCandidate }, arguments) == null) { continue; } object objectInstance = instantiationStrategy.Instantiate(definition, name, objectFactory, factoryMethodCandidate, arguments); wrapper.WrappedInstance = objectInstance; #region Instrumentation if (log.IsDebugEnabled) { log.Debug(string.Format(CultureInfo.InvariantCulture, "Object '{0}' instantiated via factory method [{1}].", name, factoryMethodCandidate)); } #endregion return(wrapper); } // if we get here, we didn't match any method... throw new ObjectDefinitionStoreException( string.Format(CultureInfo.InvariantCulture, "Cannot find matching factory method '{0} on Type [{1}].", definition.FactoryMethodName, factoryClass)); }
/// <summary> /// Create an array of arguments to invoke a constructor or static factory method, /// given the resolved constructor arguments values. /// </summary> /// <remarks>When return value is null the out parameter UnsatisfiedDependencyExceptionData will contain /// information for use in throwing a UnsatisfiedDependencyException by the caller. This avoids using /// exceptions for flow control as in the original implementation.</remarks> private ArgumentsHolder CreateArgumentArray(string objectName, RootObjectDefinition rod, ConstructorArgumentValues resolvedValues, ObjectWrapper wrapper, Type[] paramTypes, MethodBase methodOrCtorInfo, bool autowiring, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData) { string methodType = (methodOrCtorInfo is ConstructorInfo) ? "constructor" : "factory method"; unsatisfiedDependencyExceptionData = null; ArgumentsHolder args = new ArgumentsHolder(paramTypes.Length); ISet usedValueHolders = new HybridSet(); IList autowiredObjectNames = new LinkedList(); bool resolveNecessary = false; ParameterInfo[] argTypes = methodOrCtorInfo.GetParameters(); for (int paramIndex = 0; paramIndex < paramTypes.Length; paramIndex++) { Type paramType = paramTypes[paramIndex]; string parameterName = argTypes[paramIndex].Name; // If we couldn't find a direct match and are not supposed to autowire, // let's try the next generic, untyped argument value as fallback: // it could match after type conversion (for example, String -> int). ConstructorArgumentValues.ValueHolder valueHolder = null; if (resolvedValues.GetNamedArgumentValue(parameterName) != null) { valueHolder = resolvedValues.GetArgumentValue(parameterName, paramType, usedValueHolders); } else { valueHolder = resolvedValues.GetArgumentValue(paramIndex, paramType, usedValueHolders); } if (valueHolder == null && !autowiring) { valueHolder = resolvedValues.GetGenericArgumentValue(null, usedValueHolders); } if (valueHolder != null) { // We found a potential match - let's give it a try. // Do not consider the same value definition multiple times! usedValueHolders.Add(valueHolder); args.rawArguments[paramIndex] = valueHolder.Value; try { object originalValue = valueHolder.Value; object convertedValue = TypeConversionUtils.ConvertValueIfNecessary(paramType, originalValue, null); args.arguments[paramIndex] = convertedValue; //? args.preparedArguments[paramIndex] = convertedValue; } catch (TypeMismatchException ex) { //To avoid using exceptions for flow control, this is not a cost in Java as stack trace is lazily created. string errorMessage = String.Format(CultureInfo.InvariantCulture, "Could not convert {0} argument value [{1}] to required type [{2}] : {3}", methodType, valueHolder.Value, paramType, ex.Message); unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage); return(null); } } else { // No explicit match found: we're either supposed to autowire or // have to fail creating an argument array for the given constructor. if (!autowiring) { string errorMessage = String.Format(CultureInfo.InvariantCulture, "Ambiguous {0} argument types - " + "Did you specify the correct object references as {0} arguments?", methodType); unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage); return(null); } try { MethodParameter param = MethodParameter.ForMethodOrConstructor(methodOrCtorInfo, paramIndex); object autowiredArgument = ResolveAutoWiredArgument(param, objectName, autowiredObjectNames); args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = new AutowiredArgumentMarker(); resolveNecessary = true; } catch (ObjectsException ex) { unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, ex.Message); return(null); } } } foreach (string autowiredObjectName in autowiredObjectNames) { if (log.IsDebugEnabled) { log.Debug("Autowiring by type from object name '" + objectName + "' via " + methodType + " to object named '" + autowiredObjectName + "'"); } } return(args); }