PDA

View Full Version : Singleton or not singleton


samokk
07-08-2005, 03:48 AM
Hi,

I'm wondering about something :

let's say I have an object A, with fields b, c and d.

b is set to object B, c to object C, etc..

Let's say A, B, C and D are deployed as prototype.

The first time I appContext.getBean("A"), I get a new instance of all objects.
But the second time I do it, I will obviously have a new instance for A, but what about the b, c and d properties ?

Regards,
Sami Dalouche

Rick Evans
07-08-2005, 06:31 AM
Hiya Sami

Objects b, c, and d will also be new (since they are prototypes). This is the expected behaviour.

Ciao
Rick

spmva
07-08-2005, 03:56 PM
On the subject of singletons, I was playing around with something that generated a problem that I couldn't think of a way out of.

If you had object A and B both as prototypes, where A had field b and B had field a, and b set to object B and a set to object A, you end up with a cyclical relationship that sends you to a stack overflow when you try to get the object.

Is the only solution here to change the design of A and B to eliminate that issue?

samokk
07-08-2005, 04:25 PM
Hiya Sami

Objects b, c, and d will also be new (since they are prototypes). This is the expected behaviour.

Ciao
Rick

OK, thanks, I just wanted to make sure about this :)

Now, another question...

I have a set of DAOs. All my DAOs implement an interface, and I have a set of UserCommands (Command Pattern). Each UserCommand may have to access the DAOs. I'd like them to use IoC some way, but here's what I could think of :

- Use a Factory class, that is aware of the container, and retrieves an instance of all DAOs classes through spring's API.
- Use a Factory class that is not aware of the container, with static fields set by IoC.

The first option seems ugly, since there is no IoC
The second option doesn't seem doable with Spring, does it ?

Thanks

Rick Evans
07-08-2005, 04:32 PM
Hiya

For sure, thats a chicken and egg problem.

<object id="a" type="foo.A, Foo">
<property name="b" ref="b"/>
</object>
<object id="b" type="foo.B, Foo">
<property name="a" ref="a"/>
</object>

This is just not going to fly... you will get an ObjectCurrentlyInCreationException (http://www.springframework.net/doc/api/html/Spring.Objects.Factory.ObjectCurrentlyInCreationEx ception.html) when the container detects that it is trying to resolve a reference to an object that it is already in the process of resolving.

Workarounds... don't use or code obtuse classes. Only kidding... well, kindof :?. You could introduce a property into one of the classes, so that one of them could be constructed and then inserted into the ctor of the other and then have its dependency on the other resolved via setter injection.

<object id="a" type="Spring.Examples.MovieFinder.A, MovieFinder">
<property name="b" ref="b"/>
</object>
<object id="b" type="Spring.Examples.MovieFinder.B, MovieFinder">
<constructor-arg name="a" ref="a"/>
</object>

Such that the output of the following snippet would be true...

IApplicationContext ctx
= ConfigurationSettings.GetConfig("spring/context") as IApplicationContext;
A a = (A) ctx["a"];
Console.Out.WriteLine(object.ReferenceEquals(a, a.B.A));

This issue doesn't just apply to prototypes though... it will present itself in the case of singletons too. So I guess the answer is... don't do that :?

Ciao
Rick

Rick Evans
07-08-2005, 04:52 PM
Hiya Sami

That last reply of mine was in response to spmva (from Tyson's Corner).

In response to your post regarding DAOs and UserCommands that used said DAOs, well... why can't you simply inject the relevant DAOs straight into the relevant UserCommands?

To wit (I'm coding this straight into this tiny wee textbox, so please do gloss over any syntactic typos)...

public interface Dao
{
IList selectForList(object query);
}

public class StockDao : Dao
{
public IList SelectForList(object query)
{
// ...
}
}

public interface UserCommand
{
void Execute();
}


public class StockListingUserCommand : UserCommand
{
public void Execute()
{
IList stock = _dao.SelectForList (...);
// do something with the stock...
}

public Dao Dao
{
set { _dao = value; }
}

private Dao _dao;
}

For sure, I don't know your exact business scenario, or your classes, but doing it like so means that you have zero dependencies on Spring.NETs container or API, and none of your code has to be aware of the container.

In response to your two suggestions...

Use a Factory class, that is aware of the container, and retrieves an instance of all DAOs classes through spring's API.

Yes, you technically could do that, but that is one of the issues that dependency injection is specifically aimed at resolving. You shouldn't need to do that... ever (even a lot of the corner cases around this issue have been closed off by Spring.NET).

Use a Factory class that is not aware of the container, with static fields set by IoC.

Yes, you could also do this (it is doable with Spring.NET). But the reasons against doing so are the same as the ones I outlined in the preceding paragraph. IoC (and specifically Dependency Injection) obviates any need to do so.

Sorry for the short post... if you want to go over this in any more detail, or you'd like to see some concrete snippets of the XML configuration that one would use to achieve this, feel free to hit the 'Post Reply' button.

Ciao
Rick

samokk
07-08-2005, 07:00 PM
Hi,

Thanks a lot for your answer.

Concerning the UserCommands and the DAO injection...
What I have is a set of ASP.Net pages. Each time something is clicked, it triggers a UserCommand, like, let's say, AddItemToShoppingCardCommand.

So, I can't really have Spring create all the commands, with the correct DAOs injected.. (Or at least, I don't really see how..) Well, something doable would be to have spring deploy each command as a prototype, then explicitely request each command to the applicationContext, but it's still the same problem...

Any better idea ?

Concerning Dependency injection of static fields.. Nice thing Spring.Net does it ! I thought it didn't :)

Thanks again !
Sami

Hiya Sami

That last reply of mine was in response to spmva (from Tyson's Corner).

In response to your post regarding DAOs and UserCommands that used said DAOs, well... why can't you simply inject the relevant DAOs straight into the relevant UserCommands?

To wit (I'm coding this straight into this tiny wee textbox, so please do gloss over any syntactic typos)...

public interface Dao
{
IList selectForList(object query);
}

public class StockDao : Dao
{
public IList SelectForList(object query)
{
// ...
}
}

public interface UserCommand
{
void Execute();
}


public class StockListingUserCommand : UserCommand
{
public void Execute()
{
IList stock = _dao.SelectForList (...);
// do something with the stock...
}

public Dao Dao
{
set { _dao = value; }
}

private Dao _dao;
}

For sure, I don't know your exact business scenario, or your classes, but doing it like so means that you have zero dependencies on Spring.NETs container or API, and none of your code has to be aware of the container.

In response to your two suggestions...

Use a Factory class, that is aware of the container, and retrieves an instance of all DAOs classes through spring's API.

Yes, you technically could do that, but that is one of the issues that dependency injection is specifically aimed at resolving. You shouldn't need to do that... ever (even a lot of the corner cases around this issue have been closed off by Spring.NET).

Use a Factory class that is not aware of the container, with static fields set by IoC.

Yes, you could also do this (it is doable with Spring.NET). But the reasons against doing so are the same as the ones I outlined in the preceding paragraph. IoC (and specifically Dependency Injection) obviates any need to do so.

Sorry for the short post... if you want to go over this in any more detail, or you'd like to see some concrete snippets of the XML configuration that one would use to achieve this, feel free to hit the 'Post Reply' button.

Ciao
Rick

Mark Pollack
07-09-2005, 06:06 PM
Hi Sami,

You can use dependency injection on your asp.net pages, take a look at the wiki (http://opensource.atlassian.com/confluence/spring/display/NET/Dependency+Injection+for+ASP.Net+pages) for some documentation. You can ignore the discussion of master pages in that sample. The asp.net page can then have the dao object set via spring. Does this help?

Cheers,
Mark

samokk
07-10-2005, 08:25 PM
Hi Sami,

You can use dependency injection on your asp.net pages, take a look at the wiki (http://opensource.atlassian.com/confluence/spring/display/NET/Dependency+Injection+for+ASP.Net+pages) for some documentation. You can ignore the discussion of master pages in that sample. The asp.net page can then have the dao object set via spring. Does this help?

Cheers,
Mark

Hmm, this looks nice to me :) I think I'm going to be able to use this.. Thank you very much !!!!