diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
index 60ed720f..f16a716a 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
@@ -142,13 +142,18 @@ namespace Spring.Objects.Factory.Support
/// specified object.
///
/// Name of the object.
- /// The merged object definition to determine the type for.
+ /// The merged object definition to determine the type for. May be null
///
/// The type of the object, or null if not predictable
///
protected override Type PredictObjectType(string objectName, RootObjectDefinition mod)
{
Type objectType;
+ if (mod == null)
+ {
+ return null;
+ }
+
if (StringUtils.HasText(mod.FactoryMethodName))
{
objectType = GetTypeForFactoryMethod(objectName, mod);
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
index 0eeda5de..b7912c4b 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
@@ -740,11 +740,11 @@ namespace Spring.Objects.Factory.Support
/// To be overridden in subclasses, applying more sophisticated type detection.
///
/// Name of the object.
- /// The merged object definition to determine the type for.
+ /// The merged object definition to determine the type for. May be null
/// The type of the object, or null if not predictable
protected virtual Type PredictObjectType(string objectName, RootObjectDefinition mod)
{
- if (StringUtils.HasText(mod.FactoryObjectName))
+ if (mod == null || StringUtils.HasText(mod.FactoryObjectName))
{
return null;
}
diff --git a/src/Spring/Spring.Services/Remoting/SaoExporter.cs b/src/Spring/Spring.Services/Remoting/SaoExporter.cs
index 18a74089..4ec33d7f 100644
--- a/src/Spring/Spring.Services/Remoting/SaoExporter.cs
+++ b/src/Spring/Spring.Services/Remoting/SaoExporter.cs
@@ -249,10 +249,26 @@ namespace Spring.Remoting
}
IProxyTypeBuilder builder = new SaoRemoteObjectProxyTypeBuilder( this );
- builder.TargetType = this.objectFactory.GetType( targetName );
- if (interfaces != null && interfaces.Length > 0)
+ Type targetType = this.objectFactory.GetType( targetName );
+ if (targetType == null)
{
- builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray( interfaces );
+ // perform full object retrieval if type cannot be predicted - this will
+ // also cause any object creation exceptions to be thrown
+ targetType = this.objectFactory.GetObject(targetName).GetType();
+ }
+
+ if (targetType.IsInterface)
+ {
+ builder.Interfaces = new Type[] { targetType };
+ builder.TargetType = typeof(object);
+ }
+ else
+ {
+ if (interfaces != null && interfaces.Length > 0)
+ {
+ builder.Interfaces = TypeResolutionUtils.ResolveInterfaceArray(interfaces);
+ }
+ builder.TargetType = targetType;
}
Type proxyType = builder.BuildProxyType();
diff --git a/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs b/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs
index 2cac107c..a7fb4d96 100644
--- a/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs
+++ b/test/Spring/Spring.Services.Tests/Remoting/SaoExporterTests.cs
@@ -22,33 +22,52 @@
using System;
using NUnit.Framework;
+using Rhino.Mocks;
+using Spring.Aop.Framework;
+using Spring.Core.IO;
using Spring.Objects;
+using Spring.Objects.Factory;
using Spring.Objects.Factory.Support;
+using Spring.Objects.Factory.Xml;
#endregion
namespace Spring.Remoting
{
- ///
- /// Unit tests for the SaoExporter class.
- ///
- /// Bruno Baia
- /// Mark Pollack
- [TestFixture]
- public class SaoExporterTests : BaseRemotingTestFixture
- {
+ ///
+ /// Unit tests for the SaoExporter class.
+ ///
+ /// Bruno Baia
+ /// Mark Pollack
+ [TestFixture]
+ public class SaoExporterTests : BaseRemotingTestFixture
+ {
[Test]
- [ExpectedException(typeof(ArgumentException))]
- public void BailsWhenNotConfigured ()
- {
- SaoExporter exp = new SaoExporter();
- exp.AfterPropertiesSet();
- }
+ [ExpectedException(typeof(ArgumentException))]
+ public void BailsWhenNotConfigured()
+ {
+ SaoExporter exp = new SaoExporter();
+ exp.AfterPropertiesSet();
+ }
+
+ [Test]
+ [ExpectedException(typeof(NoSuchObjectDefinitionException))]
+ public void BailsIfTargetNotFound()
+ {
+ using (DefaultListableObjectFactory of = new DefaultListableObjectFactory())
+ {
+ SaoExporter saoExporter = new SaoExporter();
+ saoExporter.ObjectFactory = of;
+ saoExporter.TargetName = "DOESNOTEXIST";
+ saoExporter.ServiceName = "RemotedSaoSingletonCounter";
+ saoExporter.AfterPropertiesSet();
+ }
+ }
[Test]
public void ExportSingleton()
{
- using(DefaultListableObjectFactory of = new DefaultListableObjectFactory())
+ using (DefaultListableObjectFactory of = new DefaultListableObjectFactory())
{
of.RegisterSingleton("simpleCounter", new SimpleCounter());
SaoExporter saoExporter = new SaoExporter();
@@ -58,7 +77,7 @@ namespace Spring.Remoting
saoExporter.AfterPropertiesSet();
of.RegisterSingleton("simpleCounterExporter", saoExporter); // also tests SaoExporter.Dispose()!
- ISimpleCounter client = (ISimpleCounter) Activator.GetObject(typeof(ISimpleCounter), "tcp://localhost:8005/RemotedSaoSingletonCounter" );
+ ISimpleCounter client = (ISimpleCounter)Activator.GetObject(typeof(ISimpleCounter), "tcp://localhost:8005/RemotedSaoSingletonCounter");
client.Count();
client.Count();
@@ -69,7 +88,7 @@ namespace Spring.Remoting
[Test]
public void ExportSingleCall()
{
- using(DefaultListableObjectFactory of = new DefaultListableObjectFactory())
+ using (DefaultListableObjectFactory of = new DefaultListableObjectFactory())
{
of.RegisterObjectDefinition("simpleCounter", new RootObjectDefinition(typeof(SimpleCounter), false));
SaoExporter saoExporter = new SaoExporter();
@@ -79,11 +98,62 @@ namespace Spring.Remoting
saoExporter.AfterPropertiesSet();
of.RegisterSingleton("simpleCounterExporter", saoExporter); // also tests SaoExporter.Dispose()!
- ISimpleCounter client = (ISimpleCounter) Activator.GetObject(typeof(ISimpleCounter), "tcp://localhost:8005/RemotedSaoSingleCallCounter" );
+ ISimpleCounter client = (ISimpleCounter)Activator.GetObject(typeof(ISimpleCounter), "tcp://localhost:8005/RemotedSaoSingleCallCounter");
client.Count();
client.Count();
Assert.AreEqual(0, client.Counter);
}
}
- }
+
+ ///
+ /// Checks that exp an IFactoryObject.ObjectType returns an interface type,
+ ///
+ [Test(Description = "http://jira.springframework.org/browse/SPRNET-1251")]
+ public void CanExportFromInterfaceTargetType()
+ {
+ using (DefaultListableObjectFactory of = new DefaultListableObjectFactory())
+ {
+ MockRepository mocks = new MockRepository();
+ IFactoryObject simpleCounterFactory = (IFactoryObject) mocks.DynamicMock(typeof (IFactoryObject));
+ Expect.Call(simpleCounterFactory.ObjectType).Return(typeof (ISimpleCounter));
+ Expect.Call(simpleCounterFactory.IsSingleton).Return(true);
+ Expect.Call(simpleCounterFactory.GetObject()).Return(new SimpleCounter());
+
+ mocks.ReplayAll();
+
+ of.RegisterSingleton("simpleCounter", simpleCounterFactory);
+ SaoExporter saoExporter = new SaoExporter();
+ saoExporter.ObjectFactory = of;
+ saoExporter.TargetName = "simpleCounter";
+ saoExporter.ServiceName = "RemotedSaoCallCounter";
+ saoExporter.AfterPropertiesSet();
+
+// XmlObjectDefinitionReader reader = new XmlObjectDefinitionReader(of);
+// reader.LoadObjectDefinitions(new StringResource(
+// @"
+//
+//
+//
+//
+//
+//
+//
+//
+//"));
+// SaoExporter saoExporter = (SaoExporter) of.GetObject("ISimpleCounterExporter");
+// Assert.IsNotNull(saoExporter);
+
+ ISimpleCounter client = (ISimpleCounter)Activator.GetObject(typeof(ISimpleCounter), "tcp://localhost:8005/RemotedSaoCallCounter");
+ client.Count();
+ client.Count();
+
+ Assert.AreEqual(2, client.Counter);
+
+ mocks.VerifyAll();
+ }
+ }
+ }
}