public void CanApplyConstructorArgsToAbstractType()
        {
            IResource resource = new ReadOnlyXmlTestResource("ctor-args.xml", GetType());
            XmlObjectFactory xof = new XmlObjectFactory(resource);
            TestObject rod = (TestObject)xof.GetObject("rod");
            Assert.AreEqual(1, rod.Age);

            RootObjectDefinition def = (RootObjectDefinition) xof.GetObjectDefinition("rod");
            ConstructorResolver resolver = new ConstructorResolver(xof, xof, new SimpleInstantiationStrategy(), 
                                                    new ObjectDefinitionValueResolver(xof));
            
            ConstructorInstantiationInfo ci = resolver.GetConstructorInstantiationInfo("rod", def, null, null);

            AbstractObjectDefinition objDef = (AbstractObjectDefinition)xof.GetObjectDefinition("foo");
            objDef.IsAbstract = false;

            TestObject foo = (TestObject) xof.GetObject("foo");


            Assert.AreEqual(2, foo.Age);
        }
        /// <summary>
        /// "autowire constructor" (with constructor arguments by type) behaviour.
        /// </summary>
        /// <param name="name">The name of the object to autowire by type.</param>
        /// <param name="definition">The object definition to update through autowiring.</param>
        /// <param name="ctors">The chosen candidate constructors.</param>
        /// <param name="explicitArgs">The argument values passed in programmatically via the GetObject method,
        /// or <code>null</code> if none (-> use constructor argument values from object definition)</param>
        /// <returns>
        /// An <see cref="Spring.Objects.IObjectWrapper"/> for the new instance.
        /// </returns>
        /// <remarks>
        /// <para>
        /// Also applied if explicit constructor argument values are specified,
        /// matching all remaining arguments with objects from the object factory.
        /// </para>
        /// <para>
        /// This corresponds to constructor injection: in this mode, a Spring.NET
        /// object factory is able to host components that expect constructor-based
        /// dependency resolution.
        /// </para>
        /// </remarks>
        protected IObjectWrapper AutowireConstructor(string name, RootObjectDefinition definition, ConstructorInfo[] ctors, object[] explicitArgs)
        {
            ConstructorResolver constructorResolver =
                new ConstructorResolver(this, this, InstantiationStrategy, CreateValueResolver());
            return constructorResolver.AutowireConstructor(name, definition, ctors, explicitArgs);

        }
 /// <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>
 protected virtual IObjectWrapper InstantiateUsingFactoryMethod(string name, RootObjectDefinition definition, object[] arguments)
 {
     ConstructorResolver constructorResolver =
             new ConstructorResolver(this, this, InstantiationStrategy, CreateValueResolver());
     return constructorResolver.InstantiateUsingFactoryMethod(name, definition, arguments);
 }
Пример #4
0
            /// <summary>
            /// Applies attributes to the proxy class.
            /// </summary>
            /// <param name="typeBuilder">The type builder to use.</param>
            /// <param name="targetType">The proxied class.</param>
            /// <see cref="IProxyTypeBuilder.ProxyTargetAttributes"/>
            /// <see cref="IProxyTypeBuilder.TypeAttributes"/>
            protected override void ApplyTypeAttributes(TypeBuilder typeBuilder, Type targetType)
            {
                foreach (object attr in GetTypeAttributes(targetType))
                {
                    if (attr is CustomAttributeBuilder)
                    {
                        typeBuilder.SetCustomAttribute((CustomAttributeBuilder)attr);
                    }
#if NET_2_0
                    else if (attr is CustomAttributeData)
                    {
                        typeBuilder.SetCustomAttribute(
                            ReflectionUtils.CreateCustomAttribute((CustomAttributeData)attr));
                    }
#endif
                    else if (attr is Attribute)
                    {
                        typeBuilder.SetCustomAttribute(
                            ReflectionUtils.CreateCustomAttribute((Attribute)attr));
                    }
                    else if (attr is IObjectDefinition)
                    {
                        RootObjectDefinition objectDefinition = (RootObjectDefinition) attr;

                        //TODO check that object definition is for an Attribute type.

                        //Change object definition so it can be instantiated and make prototype scope.
                        objectDefinition.IsAbstract = false;
                        objectDefinition.IsSingleton = false;
                        string objectName = ObjectDefinitionReaderUtils.GenerateObjectName(objectDefinition, objectFactory);
                        objectFactory.RegisterObjectDefinition(objectName, objectDefinition);
                        

                        //find constructor and constructor arg values to create this attribute.                       
                        ConstructorResolver constructorResolver = new ConstructorResolver(objectFactory, objectFactory,
                                                                               new SimpleInstantiationStrategy(),
                                                                               new ObjectDefinitionValueResolver(objectFactory));

                        
                        ConstructorInstantiationInfo ci = constructorResolver.GetConstructorInstantiationInfo(objectName,
                                                                                                              objectDefinition,
                                                                                                              null, null);

                        if (objectDefinition.PropertyValues.PropertyValues.Length == 0)
                        {
                            CustomAttributeBuilder cab = new CustomAttributeBuilder(ci.ConstructorInfo,
                                                                                    ci.ArgInstances);
                            typeBuilder.SetCustomAttribute(cab);
                        }
                        else
                        {
                            object attributeInstance = objectFactory.GetObject(objectName);
                            IObjectWrapper wrappedAttributeInstance = new ObjectWrapper(attributeInstance);
                            PropertyInfo[] namedProperties = wrappedAttributeInstance.GetPropertyInfos();
                            object[] propertyValues = new object[namedProperties.Length];
                            for (int i = 0; i < namedProperties.Length; i++)
                            {
                                propertyValues[i] =
                                    wrappedAttributeInstance.GetPropertyValue(namedProperties[i].Name);
                            }
                            CustomAttributeBuilder cab = new CustomAttributeBuilder(ci.ConstructorInfo, ci.ArgInstances, 
                                                                                    namedProperties, propertyValues);
                            typeBuilder.SetCustomAttribute(cab);
                        }


                    }
                    
                }
            }