public void ChokesOnCircularReferenceToPlaceHolder() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof(TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "${foo}"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "ba${foo}r"; properties.Add("foo", expectedName); IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory)); Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] { "foo" }); Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def); mocks.ReplayAll(); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.Properties = properties; try { cfg.PostProcessObjectFactory(mock); Assert.Fail("Should have raised an ObjectDefinitionStoreException by this point."); } catch (ObjectDefinitionStoreException) { } mocks.VerifyAll(); }
public void ChokesOnCircularReferenceToPlaceHolder() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof(TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "${foo}"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "ba${foo}r"; properties.Add("foo", expectedName); IConfigurableListableObjectFactory mock = A.Fake <IConfigurableListableObjectFactory>(); A.CallTo(() => mock.GetObjectDefinitionNames(false)).Returns(new string[] { "foo" }); A.CallTo(() => mock.GetObjectDefinition(null, false)).WithAnyArguments().Returns(def); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.Properties = properties; try { cfg.PostProcessObjectFactory(mock); Assert.Fail("Should have raised an ObjectDefinitionStoreException by this point."); } catch (ObjectDefinitionStoreException) { } }
public void ChokesOnCircularReferenceToPlaceHolder() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof (TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "${foo}"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "ba${foo}r"; properties.Add("foo", expectedName); IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory)); Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"}); Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def); mocks.ReplayAll(); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.Properties = properties; try { cfg.PostProcessObjectFactory(mock); Assert.Fail("Should have raised an ObjectDefinitionStoreException by this point."); } catch (ObjectDefinitionStoreException) { } mocks.VerifyAll(); }
/// <summary> /// Copy all given argument values into this object. /// </summary> /// <param name="other"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be used to populate this instance. /// </param> public void AddAll(ConstructorArgumentValues other) { if (other != null) { if (other._genericArgumentValues != null && other._genericArgumentValues.Count > 0) { GetAndInitializeGenericArgumentValuesIfNeeded().AddRange(other._genericArgumentValues); } if (other._indexedArgumentValues != null && other._indexedArgumentValues.Count > 0) { foreach (var entry in other._indexedArgumentValues) { ValueHolder vh = entry.Value; if (vh != null) { AddOrMergeIndexedArgumentValues(entry.Key, vh.Copy()); } } } if (other._namedArgumentValues != null && other._namedArgumentValues.Count > 0) { foreach (var entry in other._namedArgumentValues) { AddOrMergeNamedArgumentValues(entry.Key, entry.Value); //NamedArgumentValues.Add(entry.Key, entry.Value); } } } }
public void UsingCustomMarkers() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof(TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "#hope.floats#"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "Rick"; properties.Add("hope.floats", expectedName); IConfigurableListableObjectFactory mock = A.Fake <IConfigurableListableObjectFactory>(); A.CallTo(() => mock.GetObjectDefinitionNames(false)).Returns(new string[] { "foo" }); A.CallTo(() => mock.GetObjectDefinition(null, false)).WithAnyArguments().Returns(def); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.PlaceholderPrefix = cfg.PlaceholderSuffix = "#"; cfg.Properties = properties; cfg.PostProcessObjectFactory(mock); A.CallTo(() => mock.AddEmbeddedValueResolver(null)).WithAnyArguments().MustHaveHappened(); Assert.AreEqual(expectedName, def.ConstructorArgumentValues.GetNamedArgumentValue("name").Value, "Named argument placeholder value was not replaced."); }
public void ReplacesNamedCtorArgument() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof(TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "${hope.floats}"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "Rick"; properties.Add("hope.floats", expectedName); IConfigurableListableObjectFactory mock = mocks.StrictMock <IConfigurableListableObjectFactory>(); Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] { "foo" }); Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def); Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments(); mocks.ReplayAll(); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.Properties = properties; cfg.PostProcessObjectFactory(mock); mocks.VerifyAll(); Assert.AreEqual(expectedName, def.ConstructorArgumentValues.GetNamedArgumentValue("name").Value, "Named argument placeholder value was not replaced."); }
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); }
public void UsingCustomMarkers() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof(TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "#hope.floats#"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "Rick"; properties.Add("hope.floats", expectedName); IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory)); Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] { "foo" }); Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def); mocks.ReplayAll(); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.PlaceholderPrefix = cfg.PlaceholderSuffix = "#"; cfg.Properties = properties; cfg.PostProcessObjectFactory(mock); mocks.VerifyAll(); Assert.AreEqual(expectedName, def.ConstructorArgumentValues.GetNamedArgumentValue("name").Value, "Named argument placeholder value was not replaced."); }
public void ValueHolderToStringsNicely() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(1, typeof(int).FullName); ConstructorArgumentValues.ValueHolder vh = values.GetGenericArgumentValue(typeof(int)); Assert.AreEqual("'1' [System.Int32]", vh.ToString()); }
/// <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; }
public void AddGenericArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(DBNull.Value); Assert.IsFalse(values.Empty, "Added one value, but the collection is sayin' it's empty."); Assert.AreEqual(1, values.ArgumentCount, "Added one value, but the collection ain't sayin' that it's got a single element in it."); Assert.AreEqual(1, values.GenericArgumentValues.Count, "Added one generic value, but the collection of indexed values ain't sayin' that it's got a single element in it."); }
public void Instantiation() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNotNull(values.GenericArgumentValues, "The 'GenericArgumentValues' property was not initialised."); Assert.IsNotNull(values.IndexedArgumentValues, "The 'IndexedArgumentValues' property was not initialised."); Assert.IsNotNull(values.NamedArgumentValues, "The 'NamedArgumentValues' property was not initialised."); Assert.AreEqual(0, values.ArgumentCount, "There were some arguments in a newly initialised instance."); Assert.IsTrue(values.Empty, "A newly initialised instance was not initially empty."); }
public void GetGeneric_Untyped_ArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); const string expectedValue = "Rick"; values.AddGenericArgumentValue(expectedValue); ConstructorArgumentValues.ValueHolder name = values.GetGenericArgumentValue(null, null); Assert.IsNotNull(name, "Must get non-null valueholder back if no required type is specified."); Assert.AreEqual(expectedValue, name.Value); }
public void AddNamedArgument() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue("foo", "sball"); Assert.AreEqual(1, values.NamedArgumentValues.Count, "Added one named argument but it doesn't seem to have been added to the named arguments collection."); Assert.AreEqual(1, values.ArgumentCount, "Added one named argument but it doesn't seem to be reflected in the overall argument count."); ConstructorArgumentValues.ValueHolder arg = values.GetNamedArgumentValue("foo"); Assert.IsNotNull(arg, "The named argument previously added could not be pulled from the ctor arg collection."); Assert.AreEqual("sball", arg.Value, "The value of the named argument passed in is not the same as the one that was pulled out."); }
private ConstructorArgumentValues getConstructorArgumentValues(TypeRegistration registrationEntry) { ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues(); int index = 0; foreach (ParameterValue constructorParameter in registrationEntry.ConstructorParameters) { constructorArgs.AddIndexedArgumentValue(index++,getInjectionParameterValue(constructorParameter)); } return constructorArgs; }
public void GetGeneric_Untyped_ArgumentValueWithOnlyStronglyTypedValuesInTheCtorValueList() { ConstructorArgumentValues values = new ConstructorArgumentValues(); const string expectedValue = "Rick"; values.AddGenericArgumentValue(expectedValue, typeof(string).FullName); ConstructorArgumentValues.ValueHolder name = values.GetGenericArgumentValue(null, null); Assert.IsNull(name, "Must get null valueholder back if no required type is specified but only " + "strongly typed values are present in the ctor values list."); }
public void AddRangeOfIndexedArgumentValues() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddIndexedArgumentValue(1, DBNull.Value); values.AddIndexedArgumentValue(2, "Foo"); values.AddIndexedArgumentValue(3, 3); new ConstructorArgumentValues(values); Assert.IsFalse(values.Empty, "Added three indexed values(as a range), but the collection is sayin' it's empty."); Assert.AreEqual(3, values.ArgumentCount, "Added three indexed values(as a range), but the collection ain't sayin' that it's got 3 elements in it."); Assert.AreEqual(3, values.IndexedArgumentValues.Count, "Added three indexed values(as a range), but the collection of indexed values ain't sayin' that it's got 3 elements in it."); }
public void GetGenericArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNull(values.GetGenericArgumentValue(typeof(object)), "Mmm... managed to get a non null instance back from an empty instance."); values.AddGenericArgumentValue(DBNull.Value, typeof(DBNull).FullName); Assert.IsNull(values.GetGenericArgumentValue(typeof(string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type."); ConstructorArgumentValues.ValueHolder value = values.GetGenericArgumentValue(typeof(DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type, but got null when retrieving it using said Type."); Assert.AreSame(DBNull.Value, value.Value, "The value stored at the specified index was not the exact same instance as was added."); }
public void NamedArgumentsAreCaseInsensitive() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue("foo", "sball"); Assert.AreEqual(1, values.NamedArgumentValues.Count, "Added one named argument but it doesn't seem to have been added to the named arguments collection."); Assert.AreEqual(1, values.ArgumentCount, "Added one named argument but it doesn't seem to be reflected in the overall argument count."); Assert.IsTrue(values.ContainsNamedArgument("FOo"), "Mmm, the ContainsNamedArgument() method eveidently IS case sensitive (which is wrong)."); ConstructorArgumentValues.ValueHolder arg = values.GetNamedArgumentValue("fOo"); Assert.IsNotNull(arg, "The named argument previously added could not be pulled from the ctor arg collection."); Assert.AreEqual("sball", arg.Value, "The value of the named argument passed in is not the same as the one that was pulled out."); }
public void AddAllFromOther() { ConstructorArgumentValues other = new ConstructorArgumentValues(); other.AddIndexedArgumentValue(1, DBNull.Value); other.AddIndexedArgumentValue(2, "Foo"); other.AddIndexedArgumentValue(3, 3); ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddAll(other); Assert.AreEqual(other.ArgumentCount, values.ArgumentCount, "Must have been the same since one was filled up with the values in the other."); }
/// <summary> /// Traverse the given ObjectDefinition object and the MutablePropertyValues /// and ConstructorArgumentValues contained in them. /// </summary> /// <param name="definition">The object definition to traverse.</param> public virtual void VisitObjectDefinition(IObjectDefinition definition) { VisitObjectTypeName(definition); VisitPropertyValues(definition); ConstructorArgumentValues cas = definition.ConstructorArgumentValues; if (cas != null) { VisitIndexedArgumentValues(cas.IndexedArgumentValues); VisitNamedArgumentValues(cas.NamedArgumentValues); VisitGenericArgumentValues(cas.GenericArgumentValues); } }
public void GetIndexedArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNull(values.GetIndexedArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an empty instance."); values.AddIndexedArgumentValue(16, DBNull.Value, typeof(DBNull).FullName); Assert.IsNull(values.GetIndexedArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an instance that should have now't at the specified index."); ConstructorArgumentValues.ValueHolder value = values.GetIndexedArgumentValue(16, typeof(DBNull)); Assert.IsNotNull(value, "Stored a value at a specified index, but got null when retrieving it."); Assert.AreSame(DBNull.Value, value.Value, "The value stored at the specified index was not the exact same instance as was added."); ConstructorArgumentValues.ValueHolder wrongValue = values.GetIndexedArgumentValue(16, typeof(string)); Assert.IsNull(wrongValue, "Stored a value at a specified index, and got it (or rather something) back when retrieving it with the wrong Type specified."); }
public void GetArgumentValue() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.IsNull(values.GetArgumentValue(0, typeof(object)), "Mmm... managed to get a non null instance back from an empty instance."); values.AddGenericArgumentValue(DBNull.Value, typeof(DBNull).FullName); values.AddNamedArgumentValue("foo", DBNull.Value); values.AddIndexedArgumentValue(16, DBNull.Value, typeof(DBNull).FullName); Assert.IsNull(values.GetArgumentValue(100, typeof(string)), "Mmm... managed to get a non null instance back from an instance that should have now't with the specified Type."); ConstructorArgumentValues.ValueHolder value = values.GetArgumentValue(-3, typeof(DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type at a specified index, but got null when retrieving it using the wrong index but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); value = values.GetArgumentValue("foo", typeof(DBNull)); Assert.IsNotNull(value, "Stored a value of a specified Type under a name, but got null when retrieving it using the wrong name but the correct Type."); Assert.AreSame(DBNull.Value, value.Value, "The retrieved value was not the exact same instance as was added."); }
public void GetGenericArgumentValueIgnoresAlreadyUsedValues() { ISet used = new ListSet(); ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(1); values.AddGenericArgumentValue(2); values.AddGenericArgumentValue(3); Type intType = typeof (int); ConstructorArgumentValues.ValueHolder one = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(1, one.Value); used.Add(one); ConstructorArgumentValues.ValueHolder two = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(2, two.Value); used.Add(two); ConstructorArgumentValues.ValueHolder three = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(3, three.Value); used.Add(three); ConstructorArgumentValues.ValueHolder four = values.GetGenericArgumentValue(intType, used); Assert.IsNull(four); }
/// <summary> /// Copy all given argument values into this object. /// </summary> /// <param name="other"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be used to populate this instance. /// </param> public void AddAll(ConstructorArgumentValues other) { if (other != null) { foreach (object o in other.GenericArgumentValues) { GenericArgumentValues.Add(o); } foreach (DictionaryEntry entry in other.IndexedArgumentValues) { ValueHolder vh = entry.Value as ValueHolder; if (vh != null) { AddOrMergeIndexedArgumentValues((int)entry.Key, vh.Copy()); } } foreach (DictionaryEntry entry in other.NamedArgumentValues) { NamedArgumentValues.Add(entry.Key, entry.Value); } } }
/// <summary> /// Copy all given argument values into this object. /// </summary> /// <param name="other"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be used to populate this instance. /// </param> public void AddAll(ConstructorArgumentValues other) { if (other != null) { foreach (ValueHolder o in other.GenericArgumentValues) { GenericArgumentValues.Add(o); } foreach (KeyValuePair <int, ValueHolder> entry in other.IndexedArgumentValues) { ValueHolder vh = entry.Value; if (vh != null) { AddOrMergeIndexedArgumentValues(entry.Key, vh.Copy()); } } foreach (KeyValuePair <string, object> entry in other.NamedArgumentValues) { AddOrMergeNamedArgumentValues(entry.Key, entry.Value); //NamedArgumentValues.Add(entry.Key, entry.Value); } } }
public void GetGenericArgumentValueIgnoresAlreadyUsedValues() { ISet used = new ListSet(); ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddGenericArgumentValue(1); values.AddGenericArgumentValue(2); values.AddGenericArgumentValue(3); Type intType = typeof(int); ConstructorArgumentValues.ValueHolder one = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(1, one.Value); used.Add(one); ConstructorArgumentValues.ValueHolder two = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(2, two.Value); used.Add(two); ConstructorArgumentValues.ValueHolder three = values.GetGenericArgumentValue(intType, used); Assert.AreEqual(3, three.Value); used.Add(three); ConstructorArgumentValues.ValueHolder four = values.GetGenericArgumentValue(intType, used); Assert.IsNull(four); }
public void AddNamedArgumentWithWhitespaceStringName() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue(Environment.NewLine + " ", 1); }
public void AddNamedArgumentWithEmptyStringName() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue(string.Empty, 1); }
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); }
public void UsingCustomMarkers() { RootObjectDefinition def = new RootObjectDefinition(); def.ObjectType = typeof (TestObject); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddNamedArgumentValue("name", "#hope.floats#"); def.ConstructorArgumentValues = args; NameValueCollection properties = new NameValueCollection(); const string expectedName = "Rick"; properties.Add("hope.floats", expectedName); IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory)); Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"}); Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def); mocks.ReplayAll(); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.PlaceholderPrefix = cfg.PlaceholderSuffix = "#"; cfg.Properties = properties; cfg.PostProcessObjectFactory(mock); mocks.VerifyAll(); Assert.AreEqual(expectedName, def.ConstructorArgumentValues.GetNamedArgumentValue("name").Value, "Named argument placeholder value was not replaced."); }
public void CreateObjectWithMixOfNamedAndIndexedCtorArguments() { string expectedName = "Bingo"; int expectedAge = 1023; ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue("age", expectedAge); values.AddIndexedArgumentValue(0, expectedName); RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues()); DefaultListableObjectFactory fac = new DefaultListableObjectFactory(); fac.RegisterObjectDefinition("foo", def); ITestObject foo = fac["foo"] as ITestObject; Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory."); Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg."); Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg."); }
public void AddAllDoesntChokeOnNullArgument() { ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddAll(null); }
/// <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; }
/// <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> /// 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> /// 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> /// Parse a constructor-arg element. /// </summary> /// <param name="name"> /// The name of the object (definition) associated with the ctor arg. /// </param> /// <param name="arguments"> /// The list of constructor args associated with the object (definition). /// </param> /// <param name="element"> /// The name of the element containing the ctor arg definition. /// </param> /// <param name="parserContext"> /// The namespace-aware parser. /// </param> protected virtual void ParseConstructorArgElement( string name, ConstructorArgumentValues arguments, XmlElement element, ParserContext parserContext) { object val = ParsePropertyValue(element, name, parserContext); string indexAttr = GetAttributeValue(element, ObjectDefinitionConstants.IndexAttribute); string typeAttr = GetAttributeValue(element, ObjectDefinitionConstants.TypeAttribute); string nameAttr = GetAttributeValue(element, ObjectDefinitionConstants.ArgumentNameAttribute); // only one of the 'index' or 'name' attributes can be present if (StringUtils.HasText(indexAttr) && StringUtils.HasText(nameAttr)) { throw new ObjectDefinitionStoreException( parserContext.ReaderContext.Resource, name, "Only one of the 'index' or 'name' attributes can be present per constructor argument."); } if (StringUtils.HasText(indexAttr)) { try { int index = int.Parse(indexAttr, CultureInfo.CurrentCulture); if (index < 0) { throw new ObjectDefinitionStoreException( parserContext.ReaderContext.Resource, name, "'index' cannot be lower than 0"); } if (StringUtils.HasText(typeAttr)) { arguments.AddIndexedArgumentValue(index, val, typeAttr); } else { arguments.AddIndexedArgumentValue(index, val); } } catch (FormatException) { throw new ObjectDefinitionStoreException( parserContext.ReaderContext.Resource, name, "Attribute 'index' of tag 'constructor-arg' must be an integer value."); } } else if (StringUtils.HasText(nameAttr)) { if (StringUtils.HasText(typeAttr)) { if (log.IsWarnEnabled) { log.Warn("The 'type' attribute is redundant when the 'name' attribute has been used on a constructor argument element."); } } arguments.AddNamedArgumentValue(nameAttr, val); } else { if (StringUtils.HasText(typeAttr)) { arguments.AddGenericArgumentValue(val, typeAttr); } else { arguments.AddGenericArgumentValue(val); } } }
/// <summary> /// Parse constructor argument subelements of the given object element. /// </summary> protected ConstructorArgumentValues ParseConstructorArgSubElements( string name, XmlElement element, ParserContext parserContext) { ConstructorArgumentValues arguments = new ConstructorArgumentValues(); foreach (XmlNode node in this.SelectNodes(element, ObjectDefinitionConstants.ConstructorArgElement)) { ParseConstructorArgElement(name, arguments, (XmlElement)node, parserContext); } return arguments; }
public void AddNamedArgumentWithEmptyStringName() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.Throws <ArgumentNullException>(() => values.AddNamedArgumentValue(string.Empty, 1)); }
public void DoubleBooleanAutowire() { RootObjectDefinition def = new RootObjectDefinition(typeof(DoubleBooleanConstructorObject)); ConstructorArgumentValues args = new ConstructorArgumentValues(); args.AddGenericArgumentValue(true, "bool"); def.ConstructorArgumentValues = args; def.AutowireMode = AutoWiringMode.Constructor; def.IsSingleton = true; DefaultListableObjectFactory fac = new DefaultListableObjectFactory(); fac.RegisterObjectDefinition("foo", def); fac.GetObject("foo"); }
public void AddNamedArgumentWithWhitespaceStringName() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.Throws <ArgumentNullException>(() => values.AddNamedArgumentValue(Environment.NewLine + " ", 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; }
public void CreateObjectWithMixOfNamedAndIndexedAndAutowiredCtorArguments() { string expectedCompany = "Griffin's Foosball Arcade"; MutablePropertyValues autoProps = new MutablePropertyValues(); autoProps.Add(new PropertyValue("Company", expectedCompany)); RootObjectDefinition autowired = new RootObjectDefinition(typeof(NestedTestObject), autoProps); string expectedName = "Bingo"; int expectedAge = 1023; ConstructorArgumentValues values = new ConstructorArgumentValues(); values.AddNamedArgumentValue("age", expectedAge); values.AddIndexedArgumentValue(0, expectedName); RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues()); def.AutowireMode = AutoWiringMode.Constructor; DefaultListableObjectFactory fac = new DefaultListableObjectFactory(); fac.RegisterObjectDefinition("foo", def); fac.RegisterObjectDefinition("doctor", autowired); ITestObject foo = fac["foo"] as ITestObject; Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory."); Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg."); Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg."); Assert.AreEqual(expectedCompany, foo.Doctor.Company, "Dependency 'doctor.Company' was not resolved using autowiring."); }
/// <summary> /// Copy all given argument values into this object. /// </summary> /// <param name="other"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be used to populate this instance. /// </param> public void AddAll(ConstructorArgumentValues other) { if (other != null) { foreach (object o in other.GenericArgumentValues) { GenericArgumentValues.Add(o); } foreach (DictionaryEntry entry in other.IndexedArgumentValues) { ValueHolder vh = entry.Value as ValueHolder; if (vh != null) { AddOrMergeIndexedArgumentValues( (int) entry.Key, vh.Copy()); } } foreach (DictionaryEntry entry in other.NamedArgumentValues) { AddOrMergeNamedArgumentValues(entry.Key, entry.Value); //NamedArgumentValues.Add(entry.Key, entry.Value); } } }
public void CreateObjectWithCtorArgsOverrided() { using (DefaultListableObjectFactory lof = new DefaultListableObjectFactory()) { ConstructorArgumentValues arguments = new ConstructorArgumentValues(); arguments.AddNamedArgumentValue("age", 27); arguments.AddNamedArgumentValue("name", "Bruno"); RootObjectDefinition singleton = new RootObjectDefinition(typeof(TestObject), arguments, new MutablePropertyValues()); singleton.IsSingleton = true; lof.RegisterObjectDefinition("singleton", singleton); TestObject to = lof.CreateObject("singleton", typeof(TestObject), new object[] { "Mark", 35 }) as TestObject; Assert.IsNotNull(to); Assert.AreEqual(35, to.Age); Assert.AreEqual("Mark", to.Name); TestObject to2 = lof.CreateObject("singleton", null, null) as TestObject; Assert.IsNotNull(to2); Assert.AreEqual(27, to2.Age); Assert.AreEqual("Bruno", to2.Name); } }
/// <summary> /// Configures the constructor argument ValueHolder. /// </summary> /// <param name="valueHolder">The vconstructor alue holder.</param> protected void ConfigureConstructorArgument(ConstructorArgumentValues.ValueHolder valueHolder) { object newVal = ResolveValue(valueHolder.Value); if (!ObjectUtils.NullSafeEquals(newVal, valueHolder.Value)) { valueHolder.Value = newVal; } }
/// <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) {}
public void CreateObjectWithMixOfIndexedAndTwoNamedSameTypeCtorArguments() { // this object will be passed in as a named constructor argument string expectedCompany = "Griffin's Foosball Arcade"; MutablePropertyValues autoProps = new MutablePropertyValues(); autoProps.Add(new PropertyValue("Company", expectedCompany)); RootObjectDefinition autowired = new RootObjectDefinition(typeof(NestedTestObject), autoProps); // this object will be passed in as a named constructor argument string expectedLawyersCompany = "Pollack, Pounce, & Pulverise"; MutablePropertyValues lawyerProps = new MutablePropertyValues(); lawyerProps.Add(new PropertyValue("Company", expectedLawyersCompany)); RootObjectDefinition lawyer = new RootObjectDefinition(typeof(NestedTestObject), lawyerProps); // this simple string object will be passed in as an indexed constructor argument string expectedName = "Bingo"; // this simple integer object will be passed in as a named constructor argument int expectedAge = 1023; ConstructorArgumentValues values = new ConstructorArgumentValues(); // lets mix the order up a little... values.AddNamedArgumentValue("age", expectedAge); values.AddIndexedArgumentValue(0, expectedName); values.AddNamedArgumentValue("doctor", new RuntimeObjectReference("a_doctor")); values.AddNamedArgumentValue("lawyer", new RuntimeObjectReference("a_lawyer")); RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), values, new MutablePropertyValues()); DefaultListableObjectFactory fac = new DefaultListableObjectFactory(); // the object we're attempting to resolve... fac.RegisterObjectDefinition("foo", def); // the object that will be looked up and passed as a named parameter to a ctor call... fac.RegisterObjectDefinition("a_doctor", autowired); // another object that will be looked up and passed as a named parameter to a ctor call... fac.RegisterObjectDefinition("a_lawyer", lawyer); ITestObject foo = fac["foo"] as ITestObject; Assert.IsNotNull(foo, "Couldn't pull manually registered instance out of the factory."); Assert.AreEqual(expectedName, foo.Name, "Dependency 'name' was not resolved an indexed ctor arg."); Assert.AreEqual(expectedAge, foo.Age, "Dependency 'age' was not resolved using a named ctor arg."); Assert.AreEqual(expectedCompany, foo.Doctor.Company, "Dependency 'doctor.Company' was not resolved using autowiring."); Assert.AreEqual(expectedLawyersCompany, foo.Lawyer.Company, "Dependency 'lawyer.Company' was not resolved using another named ctor arg."); }
public void SunnyDay() { StaticApplicationContext ac = new StaticApplicationContext(); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.Add("age", "${age}"); RootObjectDefinition def = new RootObjectDefinition("${fqn}", new ConstructorArgumentValues(), pvs); ac.RegisterObjectDefinition("tb3", def); pvs = new MutablePropertyValues(); pvs.Add("age", "${age}"); pvs.Add("name", "name${var}${"); pvs.Add("spouse", new RuntimeObjectReference("${ref}")); ac.RegisterSingleton("tb1", typeof (TestObject), pvs); ConstructorArgumentValues cas = new ConstructorArgumentValues(); cas.AddIndexedArgumentValue(1, "${age}"); cas.AddGenericArgumentValue("${var}name${age}"); pvs = new MutablePropertyValues(); ArrayList friends = new ManagedList(); friends.Add("na${age}me"); friends.Add(new RuntimeObjectReference("${ref}")); pvs.Add("friends", friends); ISet someSet = new ManagedSet(); someSet.Add("na${age}me"); someSet.Add(new RuntimeObjectReference("${ref}")); pvs.Add("someSet", someSet); IDictionary someDictionary = new ManagedDictionary(); someDictionary["key1"] = new RuntimeObjectReference("${ref}"); someDictionary["key2"] = "${age}name"; MutablePropertyValues innerPvs = new MutablePropertyValues(); someDictionary["key3"] = new RootObjectDefinition(typeof (TestObject), innerPvs); someDictionary["key4"] = new ChildObjectDefinition("tb1", innerPvs); pvs.Add("someMap", someDictionary); RootObjectDefinition definition = new RootObjectDefinition(typeof (TestObject), cas, pvs); ac.DefaultListableObjectFactory.RegisterObjectDefinition("tb2", definition); pvs = new MutablePropertyValues(); pvs.Add("Properties", "<spring-config><add key=\"age\" value=\"98\"/><add key=\"var\" value=\"${m}var\"/><add key=\"ref\" value=\"tb2\"/><add key=\"m\" value=\"my\"/><add key=\"fqn\" value=\"Spring.Objects.TestObject, Spring.Core.Tests\"/></spring-config>"); ac.RegisterSingleton("configurer", typeof (PropertyPlaceholderConfigurer), pvs); ac.Refresh(); TestObject tb1 = (TestObject) ac.GetObject("tb1"); TestObject tb2 = (TestObject) ac.GetObject("tb2"); TestObject tb3 = (TestObject) ac.GetObject("tb3"); Assert.AreEqual(98, tb1.Age); Assert.AreEqual(98, tb2.Age); Assert.AreEqual(98, tb3.Age); Assert.AreEqual("namemyvar${", tb1.Name); Assert.AreEqual("myvarname98", tb2.Name); Assert.AreEqual(tb2, tb1.Spouse); Assert.AreEqual(2, tb2.Friends.Count); IEnumerator ie = tb2.Friends.GetEnumerator(); ie.MoveNext(); Assert.AreEqual("na98me", ie.Current); ie.MoveNext(); Assert.AreEqual(tb2, ie.Current); Assert.AreEqual(2, tb2.SomeSet.Count); Assert.IsTrue(tb2.SomeSet.Contains("na98me")); Assert.IsTrue(tb2.SomeSet.Contains(tb2)); Assert.AreEqual(4, tb2.SomeMap.Count); Assert.AreEqual(tb2, tb2.SomeMap["key1"]); Assert.AreEqual("98name", tb2.SomeMap["key2"]); TestObject inner1 = (TestObject) tb2.SomeMap["key3"]; TestObject inner2 = (TestObject) tb2.SomeMap["key4"]; Assert.AreEqual(0, inner1.Age); Assert.AreEqual(null, inner1.Name); Assert.AreEqual(98, inner2.Age); Assert.AreEqual("namemyvar${", inner2.Name); }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// class. /// </summary> /// <param name="other"> /// The <see cref="Spring.Objects.Factory.Config.ConstructorArgumentValues"/> /// to be used to populate this instance. /// </param> public ConstructorArgumentValues(ConstructorArgumentValues other) { AddAll(other); }
public void SunnyDay() { StaticApplicationContext ac = new StaticApplicationContext(); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.Add("age", "${age}"); RootObjectDefinition def = new RootObjectDefinition("${fqn}", new ConstructorArgumentValues(), pvs); ac.RegisterObjectDefinition("tb3", def); pvs = new MutablePropertyValues(); pvs.Add("age", "${age}"); pvs.Add("name", "name${var}${"); pvs.Add("spouse", new RuntimeObjectReference("${ref}")); ac.RegisterSingleton("tb1", typeof(TestObject), pvs); ConstructorArgumentValues cas = new ConstructorArgumentValues(); cas.AddIndexedArgumentValue(1, "${age}"); cas.AddGenericArgumentValue("${var}name${age}"); pvs = new MutablePropertyValues(); ArrayList friends = new ManagedList(); friends.Add("na${age}me"); friends.Add(new RuntimeObjectReference("${ref}")); pvs.Add("friends", friends); ISet someSet = new ManagedSet(); someSet.Add("na${age}me"); someSet.Add(new RuntimeObjectReference("${ref}")); pvs.Add("someSet", someSet); IDictionary someDictionary = new ManagedDictionary(); someDictionary["key1"] = new RuntimeObjectReference("${ref}"); someDictionary["key2"] = "${age}name"; MutablePropertyValues innerPvs = new MutablePropertyValues(); someDictionary["key3"] = new RootObjectDefinition(typeof(TestObject), innerPvs); someDictionary["key4"] = new ChildObjectDefinition("tb1", innerPvs); pvs.Add("someMap", someDictionary); RootObjectDefinition definition = new RootObjectDefinition(typeof(TestObject), cas, pvs); ac.DefaultListableObjectFactory.RegisterObjectDefinition("tb2", definition); pvs = new MutablePropertyValues(); pvs.Add("Properties", "<spring-config><add key=\"age\" value=\"98\"/><add key=\"var\" value=\"${m}var\"/><add key=\"ref\" value=\"tb2\"/><add key=\"m\" value=\"my\"/><add key=\"fqn\" value=\"Spring.Objects.TestObject, Spring.Core.Tests\"/></spring-config>"); ac.RegisterSingleton("configurer", typeof(PropertyPlaceholderConfigurer), pvs); ac.Refresh(); TestObject tb1 = (TestObject)ac.GetObject("tb1"); TestObject tb2 = (TestObject)ac.GetObject("tb2"); TestObject tb3 = (TestObject)ac.GetObject("tb3"); Assert.AreEqual(98, tb1.Age); Assert.AreEqual(98, tb2.Age); Assert.AreEqual(98, tb3.Age); Assert.AreEqual("namemyvar${", tb1.Name); Assert.AreEqual("myvarname98", tb2.Name); Assert.AreEqual(tb2, tb1.Spouse); Assert.AreEqual(2, tb2.Friends.Count); IEnumerator ie = tb2.Friends.GetEnumerator(); ie.MoveNext(); Assert.AreEqual("na98me", ie.Current); ie.MoveNext(); Assert.AreEqual(tb2, ie.Current); Assert.AreEqual(2, tb2.SomeSet.Count); Assert.IsTrue(tb2.SomeSet.Contains("na98me")); Assert.IsTrue(tb2.SomeSet.Contains(tb2)); Assert.AreEqual(4, tb2.SomeMap.Count); Assert.AreEqual(tb2, tb2.SomeMap["key1"]); Assert.AreEqual("98name", tb2.SomeMap["key2"]); TestObject inner1 = (TestObject)tb2.SomeMap["key3"]; TestObject inner2 = (TestObject)tb2.SomeMap["key4"]; Assert.AreEqual(0, inner1.Age); Assert.AreEqual(null, inner1.Name); Assert.AreEqual(98, inner2.Age); Assert.AreEqual("namemyvar${", inner2.Name); }
public void AddNamedArgumentWithNullName() { ConstructorArgumentValues values = new ConstructorArgumentValues(); Assert.Throws <ArgumentNullException>(() => values.AddNamedArgumentValue(null, 1)); }
/// <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 (KeyValuePair<int, ConstructorArgumentValues.ValueHolder> 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 = 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 (KeyValuePair<string, object> namedArgumentEntry in definition.ConstructorArgumentValues.NamedArgumentValues) { string argumentName = 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> /// 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"); this.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; DependsOn = new string[other.DependsOn.Length]; IsAutowireCandidate = other.IsAutowireCandidate; Array.Copy(other.DependsOn, DependsOn, other.DependsOn.Length); FactoryMethodName = other.FactoryMethodName; FactoryObjectName = other.FactoryObjectName; AutowireMode = other.AutowireMode; ResourceDescription = other.ResourceDescription; }
/// <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; }