PDA

View Full Version : MethodInvokingFactoryObject and null values


emacinty
02-12-2005, 10:43 PM
Hello.

I use the MethodInvokingFactoryObject in order to obtain a string
value which is being assigned as the property of an object.

In some circumstances, the string returned is null. This results in the
following:
Additional information: Error creating object with name 'stringHolder' defined in 'blah' : Error setting property values: PropertyAccessExceptionsException (1 errors); nested propertyAccessExceptions are:
[Spring.Objects.TypeMismatchException: Cannot convert property value of type [Missing] to required type [System.String] for property 'string',

It seems that when "null" is returned, the method invoker switches
this to an alternative "Void" value, which confuses the assignment
of the property value. However, surely assignment of null should
be fine?

The attempt above is in a simple example I stripped out of my
application, to verify that this wasn't something silly I was doing.
I've included the xml and C# code below.

Thanks for any advice,

Ewan

PS I'm using code from CVS from the end of January.

-----

2 c# classes, really trivial (& contrived):

namespace SpringTest
{
public class StringHolder
{
private string _str;

public string String
{
set
{
_str = value;
}
}
}
}

namespace SpringTest
{
public class StringReturner
{
private string _str;

public string String
{
set
{
_str = value;
}
get
{
return _str;
}
}

public string returnString()
{
return _str;
}
}
}

And the relevant bit of xml:

<object name="stringReturner" type="SpringTest.StringReturner">
<!-- property name="string">
<value>A string</value>
</property -->
</object>
<object name="stringHolder" type="SpringTest.StringHolder">
<property name="string">
<object type="Spring.Objects.Factory.Config.MethodInvokingFactor yObject">
<property name="targetMethod">
<value>returnString</value>
</property>
<property name="targetObject">
<ref object="stringReturner"/>
</property>
</object>
</property>
</object>

The invoking code just needs to try to create "stringHolder".
If the commented-out part of the "stringReturner" object definition
is reinstated, it obviously works fine.

emacinty
02-13-2005, 12:59 PM
Hi,

I'm now using a workaround, which involves:

1. Using my own invoker class inheriting from the existing one, such
that if the invocation returns null I leave the value alone instead
of switching it to the "Missing.Value" value.

2. Change MethodInvoker.Invoke to be virtual.

3. Comment out the check for whether "instance" is null in the
method AbstractObjectFactory.ResolveValueIfNecessary.

I guess change (3) may have side effects, such that errors which
might otherwise be trapped early won't be caught till later, but it
works fine for now.

Hopefully someone more knowledgeable of the Spring source than
me can advice of a more appropriate solution.

cheers

Ewan


using Spring.Objects.Factory.Config;

namespace SpringTest
{
public class NullPassingMethodInvoker : MethodInvokingFactoryObject
{
public override object Invoke()
{
object result = base.Invoke();
if (result.Equals(Spring.Util.MethodInvoker.Void))
{
return null;
}
else
{
return result;
}
}
}
}

Rick Evans
02-13-2005, 05:40 PM
Shucks... looks like you've flushed out a bug in the contract.

The docs for the MethodInvokingFactoryObject clearly state that instances of this class can be used to call methods purely for their side effects... i.e. they don't have to return a value (or at least the Java version does).

I have amended the class documentation, banged in a couple of unit tests to verify the new behaviour, and changed the class accordingly.

Still, its not the best solution is it? In effect we now have an IFactoryObject that doesn't actually manufacture anything, and that, while is useful in the scenario you describe (where the result of the method invocation could well be null), kinda muddies the whole IFactoryObject idea.

Anonymous
02-27-2005, 02:53 PM
Hi

Just in case you're still monitoring this forum issue, the MethodInvokingFactoryObject now supports named arguments in addition to the list of arguments (which was all it supported previously).

The XML that one has to bang out to specify one's named arguments is pretty verbose though... plans to clean up the XML syntax and allow it to be extended are afoot, and work should (hopefully) start on that soon (probably after the 0.6 release I should think).

Ciao
Rick