views:

270

answers:

3

I have a following object:

public class TestObject
{
    public String Something { get; set; }
}

and a following objects file:

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"&gt;

  <object id="TestObject" type="SpringTest.TestObject" autowire="byName"/>
</objects>

What I would like to do is to register singleton and get the TestObject. I am doing this like so:

IConfigurableApplicationContext context = new XmlApplicationContext("objects.xml");
context.ObjectFactory.RegisterSingleton("Something", "something to test");
object obj = context.GetObject("TestObject");

But the objects property Something is always null. I think that this should work or am I doing something wrong?

Many thanks!

A: 

Why aren't you using scope="singleton" if you want a singleton or am I missing something?

Taylor Leese
What to you mean by that? To add scope="singleton" to object definition like this:<object id="TestObject" type="SpringTest.TestObject" autowire="byName" scope="singleton"/>This is not possible (scope can only be application, session or request). If you meant singleton="true" that this doesn't need to be specified because this is the default behaviour AFAIK. The thing is that i want to assign one identifier to all the services which are created from factory.
rrejc
scope="singleton" is valid. Check the Spring documentation: http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes
Taylor Leese
Sorry if I didn't tell this explicitly, but I am using spring.net (where this, as said, is not a valid value).
rrejc
In java, all bean are created as singleton by default ... is it the case in spring.net ?
Antoine Claval
A: 

I think your Something property is not getting set because singletons are instantiated when the application context is instantiated. When you call RegisterSingleton, the TestObject has already been created. The bean wiring is only done when a bean is created.

You might be able to work around this problem by making the singleton instantiate lazily. That way it isn't instantiated until the first time it's requested. Hopefully, that's after you've registered the other singletons it needs.

I don't know exactly what you're trying to accomplish, but if I wanted to change the wiring between some singleton beans at run time without making the beans aware of it, I would introduce some wrapper objects. Each wrapper would implement an interface and then just delegate all methods to its current target bean. To change the wiring, you just change the wrapper's target.

Update: as yawn suggested, Spring.NET has hot-swappable target sources that let you swap out the implementation of a bean at run time. Here's some sample code from the documentation that shows how to swap the bean implementation:

HotSwappableTargetSource swapper = 
    (HotSwappableTargetSource) objectFactory.GetObject("swapper");
object oldTarget = swapper.swap(newTarget);

The XML definitions in the documentation look like this:

<object id="initialTarget" type="MyCompany.OldTarget, MyCompany">
</object>

<object id="swapper" 
    type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop">
    <constructor-arg><ref local="initialTarget"/></constructor-arg>
</object>

<object id="swappable" 
    type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
    <property name="targetSource">
        <ref local="swapper"/>
    </property>
</object>
Don Kirkby
Hmm you are right, lazy instantiation helped of course. Let me desribe what I want to do: I have multiple contexts for different customers. When I pull the object from a context I want to add a customer "id" (simple nhibernate object) to pulled object (service) and any other services which are referenced from the pulled object.
rrejc
Sorry, I still don't really understand what you're trying to do. Try to be specific about which objects are singletons and what references you need between objects.You might find method injection helpful, it's designed to smooth over the boundaries between objects of different scopes. Here's the documentation:http://www.springframework.net/docs/1.3.0-RC1/reference/html/objects.html#objects-method-injection
Don Kirkby
+1  A: 

I'm not sure what the problem statement is exactly (never used Spring for .NET). But if you want what Don Kirkby suggest you should lookup TargetSources in the reference documentation (assuming that the .NET implementation has them, too).

yawn
Thanks, I hadn't run across target sources before. I don't know if that helps the original poster, but I appreciate the info.
Don Kirkby