Singleton Implementation Issue

  • Thread starter Thread starter Smithers
  • Start date Start date
S

Smithers

Unless I'm misunderstanding the pattern and it's various implementations,
Singleton effectively makes the constructor unavailable to clients. The
constructor for any given class, however, is what we otherwise use [outside
of Singleton implementations] to *require* specific parameters be supplied
upon instantiation (provided of course that we've removed the default
constructor).

So my question: I want to have a Singleton implementation that requires
specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts on
this):
1. I'll go with one of the Singleton implementations that results in lazy
instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll have a
*method* named Instance() instead of a *property* of that name. The method
then defines the arguments for which clients are to supply the parameter
values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
Smithers,

If you are going to do that, then the singleton pattern doesn't really
apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it doesn't
matter if it is a property or a method), but if the method takes parameters,
and the values passed to that method could change, then what do you do the
second time the method is called with different parameters? Do you return
the same instance?

It sounds like what you really want is something along the lines of a
class factory, which returns cached instances based on the parameters passed
in.
 
Thanks Nicholas:

Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

My current motivation is as follows: At application startup I'm wanting to
create one instance of a class ("the singleton"). Many settings needed by
the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than reading
the configuration settings directly from withing the singleton. One reason
that I don't want to read the configuration settings directly from within
the singleton is that I want to reuse the singleton in a Windows Forms app
(which uses App.config) and then in an ASP.NET Web version of the
application (which uses Web.config).

Thanks for your feedback!





Nicholas Paldino said:
Smithers,

If you are going to do that, then the singleton pattern doesn't really
apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it doesn't
matter if it is a property or a method), but if the method takes
parameters, and the values passed to that method could change, then what
do you do the second time the method is called with different parameters?
Do you return the same instance?

It sounds like what you really want is something along the lines of a
class factory, which returns cached instances based on the parameters
passed in.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Smithers said:
Unless I'm misunderstanding the pattern and it's various implementations,
Singleton effectively makes the constructor unavailable to clients. The
constructor for any given class, however, is what we otherwise use
[outside of Singleton implementations] to *require* specific parameters
be supplied upon instantiation (provided of course that we've removed the
default constructor).

So my question: I want to have a Singleton implementation that requires
specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts on
this):
1. I'll go with one of the Singleton implementations that results in lazy
instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll have a
*method* named Instance() instead of a *property* of that name. The
method then defines the arguments for which clients are to supply the
parameter values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
If you want to be able to have multiple instances of the object that
vary by some parameters, but are the same if the parameters are the
same, then use a static retrieval method with the appropriate
parameters. Store instances of the class in a Dictionary where the
input parameter(s are the key and instances are values. If multiple
parameters then use a custom class for those parameters with
appropriate hashcode/equals implementations. Then when the method is
called, look up an existing instance in the dictionary and return that
if found. If not create a new instance put it in the dictionary, and
return it.

This is not a Singleton any more 'cause there are multiple instances.
It's called a Flyweight.

HTH,

Sam
 
Wanting to create a singleton with a particular state upon
initialization doesn't mean it shouldn't be a singleton. It's taking
parameters in your Instance method which indicates that it shouldn't be a
singleton. If your instance method looks like this (this is a
simplification):

public static MyClass Instance(int i)
{
// Return an instance of MyClass based on i.
}

Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned. This
negates the possibility of it being a singleton at that point (and makes it
more like a class factory).

Is there a reason that you want to pass a
System.Configuration.Configuration instance to it, rather than having the
private constructor get it?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Smithers said:
Thanks Nicholas:

Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

My current motivation is as follows: At application startup I'm wanting to
create one instance of a class ("the singleton"). Many settings needed by
the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than reading
the configuration settings directly from withing the singleton. One reason
that I don't want to read the configuration settings directly from within
the singleton is that I want to reuse the singleton in a Windows Forms app
(which uses App.config) and then in an ASP.NET Web version of the
application (which uses Web.config).

Thanks for your feedback!





Nicholas Paldino said:
Smithers,

If you are going to do that, then the singleton pattern doesn't really
apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it doesn't
matter if it is a property or a method), but if the method takes
parameters, and the values passed to that method could change, then what
do you do the second time the method is called with different parameters?
Do you return the same instance?

It sounds like what you really want is something along the lines of a
class factory, which returns cached instances based on the parameters
passed in.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Smithers said:
Unless I'm misunderstanding the pattern and it's various
implementations, Singleton effectively makes the constructor unavailable
to clients. The constructor for any given class, however, is what we
otherwise use [outside of Singleton implementations] to *require*
specific parameters be supplied upon instantiation (provided of course
that we've removed the default constructor).

So my question: I want to have a Singleton implementation that requires
specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts on
this):
1. I'll go with one of the Singleton implementations that results in
lazy instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll have
a *method* named Instance() instead of a *property* of that name. The
method then defines the arguments for which clients are to supply the
parameter values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
hi,
Actually, for the "App.Config" and "Web.Config" problem,
System.Configuration.ConfigurationManager addresses this very exact problem.
You can use this class in both situations and it works fine. Just make sure
to give both app settings the same key (once in Web.Config and once in
App.Config)

I hope it helps

ThunderMusic

Smithers said:
Thanks Nicholas:

Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

My current motivation is as follows: At application startup I'm wanting to
create one instance of a class ("the singleton"). Many settings needed by
the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than reading
the configuration settings directly from withing the singleton. One reason
that I don't want to read the configuration settings directly from within
the singleton is that I want to reuse the singleton in a Windows Forms app
(which uses App.config) and then in an ASP.NET Web version of the
application (which uses Web.config).

Thanks for your feedback!





Nicholas Paldino said:
Smithers,

If you are going to do that, then the singleton pattern doesn't really
apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it doesn't
matter if it is a property or a method), but if the method takes
parameters, and the values passed to that method could change, then what
do you do the second time the method is called with different parameters?
Do you return the same instance?

It sounds like what you really want is something along the lines of a
class factory, which returns cached instances based on the parameters
passed in.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Smithers said:
Unless I'm misunderstanding the pattern and it's various
implementations, Singleton effectively makes the constructor unavailable
to clients. The constructor for any given class, however, is what we
otherwise use [outside of Singleton implementations] to *require*
specific parameters be supplied upon instantiation (provided of course
that we've removed the default constructor).

So my question: I want to have a Singleton implementation that requires
specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts on
this):
1. I'll go with one of the Singleton implementations that results in
lazy instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll have
a *method* named Instance() instead of a *property* of that name. The
method then defines the arguments for which clients are to supply the
parameter values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
Smithers said:
Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

Because it implies that you could call the same initialization with
different parameters, resulting in a different instance. Having two
different instances is the opposite of a singleton. :)
My current motivation is as follows: At application startup I'm wanting to
create one instance of a class ("the singleton"). Many settings needed by
the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than reading
the configuration settings directly from withing the singleton.

I think your motivation is valid, however I don't think that that
modifying the usual singleton design by including parameters in the
getter for the singleton instance makes sense. Doing so would imply
that you could get a different singleton depending on how you call the
getter, which isn't correct (see above).

IMHO, it would be better to define some sort of initialization method
for the class, and then a separate getter (property would be fine). If
you attempt to get the singleton before the initialization is done, you
should throw an exception.

The initialization can either immediately create the singleton instance
or simply store the parameters somewhere for use when the singleton is
actually created lazily. You could even store the parameters in a
dynamically allocated object so that the data could be thrown away once
the singleton had actually be instantiated (or alternatively, you may
find it useful to keep the parameters handy, in case you need to refer
to them later, if for some reason they aren't represented exactly in the
singleton instance itself).

Pete
 
RE:
<< Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned>>

Okay - so it's just an implication (altough an important one). So anyone
looking at my code later (including myself) might see the client code and
incorrectly assume we have a factory going on rather than a Singleton. Is
that basically "the problem" that I'd be creating (not to minimize it)?

RE:
<< Is there a reason that you want to pass a
System.Configuration.Configuration instance to it, rather than having the
private constructor get it? >>
Yes - I was just thinking that I might eliminate the duplication of code
that reads App/Web.config (duplicated between the singleton and the client
[of the singleton] application)... the few lines that is anyway.

Thanks again.




Nicholas Paldino said:
Wanting to create a singleton with a particular state upon
initialization doesn't mean it shouldn't be a singleton. It's taking
parameters in your Instance method which indicates that it shouldn't be a
singleton. If your instance method looks like this (this is a
simplification):

public static MyClass Instance(int i)
{
// Return an instance of MyClass based on i.
}

Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned. This
negates the possibility of it being a singleton at that point (and makes
it more like a class factory).

Is there a reason that you want to pass a
System.Configuration.Configuration instance to it, rather than having the
private constructor get it?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Smithers said:
Thanks Nicholas:

Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

My current motivation is as follows: At application startup I'm wanting
to create one instance of a class ("the singleton"). Many settings needed
by the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than
reading the configuration settings directly from withing the singleton.
One reason that I don't want to read the configuration settings directly
from within the singleton is that I want to reuse the singleton in a
Windows Forms app (which uses App.config) and then in an ASP.NET Web
version of the application (which uses Web.config).

Thanks for your feedback!





Nicholas Paldino said:
Smithers,

If you are going to do that, then the singleton pattern doesn't
really apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it doesn't
matter if it is a property or a method), but if the method takes
parameters, and the values passed to that method could change, then what
do you do the second time the method is called with different
parameters? Do you return the same instance?

It sounds like what you really want is something along the lines of a
class factory, which returns cached instances based on the parameters
passed in.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Unless I'm misunderstanding the pattern and it's various
implementations, Singleton effectively makes the constructor
unavailable to clients. The constructor for any given class, however,
is what we otherwise use [outside of Singleton implementations] to
*require* specific parameters be supplied upon instantiation (provided
of course that we've removed the default constructor).

So my question: I want to have a Singleton implementation that requires
specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts on
this):
1. I'll go with one of the Singleton implementations that results in
lazy instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll have
a *method* named Instance() instead of a *property* of that name. The
method then defines the arguments for which clients are to supply the
parameter values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
Smithers,

That's pretty much "the problem". It's nothing major, it's just not a
singleton at that point. That doesn't mean that it can't be done, but it
would be somewhat misleading the way you want to do it.

If you are doing this to separate out the hassles of using a web.config
file and app.config file, I believe another poster in this thread stated
that the classes in the System.Configuration namespace now handle that
event. If that is the case, then you wouldn't need a parameterized method
anymore.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Smithers said:
RE:
<< Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned>>

Okay - so it's just an implication (altough an important one). So anyone
looking at my code later (including myself) might see the client code and
incorrectly assume we have a factory going on rather than a Singleton. Is
that basically "the problem" that I'd be creating (not to minimize it)?

RE:
<< Is there a reason that you want to pass a
System.Configuration.Configuration instance to it, rather than having the
private constructor get it? >>
Yes - I was just thinking that I might eliminate the duplication of code
that reads App/Web.config (duplicated between the singleton and the client
[of the singleton] application)... the few lines that is anyway.

Thanks again.




Nicholas Paldino said:
Wanting to create a singleton with a particular state upon
initialization doesn't mean it shouldn't be a singleton. It's taking
parameters in your Instance method which indicates that it shouldn't be a
singleton. If your instance method looks like this (this is a
simplification):

public static MyClass Instance(int i)
{
// Return an instance of MyClass based on i.
}

Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned. This
negates the possibility of it being a singleton at that point (and makes
it more like a class factory).

Is there a reason that you want to pass a
System.Configuration.Configuration instance to it, rather than having the
private constructor get it?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Smithers said:
Thanks Nicholas:

Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

My current motivation is as follows: At application startup I'm wanting
to create one instance of a class ("the singleton"). Many settings
needed by the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than
reading the configuration settings directly from withing the singleton.
One reason that I don't want to read the configuration settings directly
from within the singleton is that I want to reuse the singleton in a
Windows Forms app (which uses App.config) and then in an ASP.NET Web
version of the application (which uses Web.config).

Thanks for your feedback!





in message Smithers,

If you are going to do that, then the singleton pattern doesn't
really apply. The whole point is that you have one instance here.

Now, having a property that returns that instance is fine (it
doesn't matter if it is a property or a method), but if the method
takes parameters, and the values passed to that method could change,
then what do you do the second time the method is called with different
parameters? Do you return the same instance?

It sounds like what you really want is something along the lines of
a class factory, which returns cached instances based on the parameters
passed in.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Unless I'm misunderstanding the pattern and it's various
implementations, Singleton effectively makes the constructor
unavailable to clients. The constructor for any given class, however,
is what we otherwise use [outside of Singleton implementations] to
*require* specific parameters be supplied upon instantiation (provided
of course that we've removed the default constructor).

So my question: I want to have a Singleton implementation that
requires specific parameters to be supplied upon instantiation.

My initial shot at a reasonable answer (please provide your thoughts
on this):
1. I'll go with one of the Singleton implementations that results in
lazy instantiation.
2. Then, in order to *require* the parameters to be supplied, I'll
have a *method* named Instance() instead of a *property* of that name.
The method then defines the arguments for which clients are to supply
the parameter values upon accessing the Singleton.

Thoughts? Considerations? Perspective?

Thanks.
 
Smithers said:
RE:
<< Then there is an implication that for different values of i, you are
going to have different instances of MyClass which can be returned>>

Okay - so it's just an implication (altough an important one). So anyone
looking at my code later (including myself) might see the client code and
incorrectly assume we have a factory going on rather than a Singleton. Is
that basically "the problem" that I'd be creating (not to minimize it)?

That's my take on it, anyway. That is, the big issue here is what the
code _appears_ to do versus what it actually does. I presume that if
your singleton getter takes parameters, and if the singleton has
actually been initialized, then the getter is just going to ignore the
parameters. I'd say that's not a very good design. The parameters
imply that you can pass information in and get different results
depending on the parameters, but in this case that would not actually be
true.

Pete
 
Thanks Peter:

RE:
<< IMHO, it would be better to define some sort of initialization method for
the class, and then a separate getter (property would be fine). >>

That's exactly what I did the first time around, but it seemed to be a bit
of a hack to me. So I went for the method [returning the Instance] thing
(per my OP here) - but that didn't seem quite right either... thus going to
the group to see what you all think.

So I'm apparently left with one option that you pointed out, or having a
"GetInstance(myParm)" method that returns the instance but also makes it
look like a factory. Hummm.

I do understant your point about the *implication* of having parameters
(implying it's not really a Singleton).

FWIW: In my case what I'm storing in the App/Web.config are a few paths to
be monitored by a few FileSystemWatchers that run within the singleton. The
fact that the values are coming from App/Web.config kind of sort of
indicates that these parameters won't be changing frequently.

-Thanks again.


Peter Duniho said:
Smithers said:
Why does [wanting to create a Singleton with a particular state upon
initialization] indicate in any way that the class should not be a
singleton?

Because it implies that you could call the same initialization with
different parameters, resulting in a different instance. Having two
different instances is the opposite of a singleton. :)
My current motivation is as follows: At application startup I'm wanting
to create one instance of a class ("the singleton"). Many settings needed
by the singleton are stored in App.config. I am wanting to pass a
[System.Configuration.Configuration] to the singleton, rather than
reading the configuration settings directly from withing the singleton.

I think your motivation is valid, however I don't think that that
modifying the usual singleton design by including parameters in the getter
for the singleton instance makes sense. Doing so would imply that you
could get a different singleton depending on how you call the getter,
which isn't correct (see above).

IMHO, it would be better to define some sort of initialization method for
the class, and then a separate getter (property would be fine). If you
attempt to get the singleton before the initialization is done, you should
throw an exception.

The initialization can either immediately create the singleton instance or
simply store the parameters somewhere for use when the singleton is
actually created lazily. You could even store the parameters in a
dynamically allocated object so that the data could be thrown away once
the singleton had actually be instantiated (or alternatively, you may find
it useful to keep the parameters handy, in case you need to refer to them
later, if for some reason they aren't represented exactly in the singleton
instance itself).

Pete
 
Re
<< That is, the big issue here is what the code _appears_ to do versus what
it actually does >>

Yep- That's a huge problem IMHO. I generally shoot for maintainability over
(fewer) lines of code if those lines are harder to understand or even
outright misleading as would be the case here. So I'll revert to my original
implementation which was what you suggested earlier.

Thanks for discussion.
 
Smithers said:
Thanks Peter:

RE:
<< IMHO, it would be better to define some sort of initialization method for
the class, and then a separate getter (property would be fine). >>

That's exactly what I did the first time around, but it seemed to be a bit
of a hack to me. So I went for the method [returning the Instance] thing
(per my OP here) - but that didn't seem quite right either... thus going to
the group to see what you all think.

I agree that the "initialize, then obtain reference" paradigm is not one
that I prefer. It just seems nicer to have the initialization and
retrieval of an instance happen all at the same time.

However, I also think it's more important than the code clearly indicate
what it's doing than to comply with some internal sense of aesthetics.
At the end of the day, while I prefer than my code be elegant, it is
more important that it be clear and maintainable. I don't usually have
to choose between elegant and maintainable, but the latter should always
win if your goal is to have correct, bug-free code (IMHO, that should
always be the goal :) ).

[...]
FWIW: In my case what I'm storing in the App/Web.config are a few paths to
be monitored by a few FileSystemWatchers that run within the singleton. The
fact that the values are coming from App/Web.config kind of sort of
indicates that these parameters won't be changing frequently.

I would be curious to know if the suggestion from the person posting as
"ThunderMusic" was of any use. It does seem that with the design he
suggested, that would address the App/Web.config issue. It doesn't
obviate the more general discussion, but would it not deal with the
specific issue that raised that discussion?

Pete
 
RE:

<< I would be curious to know if the suggestion from the person posting as
"ThunderMusic" was of any use. It does seem that with the design he
suggested, that would address the App/Web.config issue. It doesn't
obviate the more general discussion, but would it not deal with the
specific issue that raised that discussion?
That insight is valid and could easily be seen as providing satisfactory
resolution to my particular scenario. But more than that I was considering
the "separation of concerns" design principle in light of tight/loose
coupling implications for how I'm going about this particular design
decision.

So my more pressing issue here is that of learning good/proper object
design. What I'm doing is refactoring a 1.1 utility that has been working
just fine in production for a couple of years. Beyond takign advantage of
the new 2.0 constructs (e.g., generics, plus the whole new
System.Configuration namespace), this refactoring effort is being undertaken
so that I can gain some practical experience with designing for all of the
"abilities" (extensibility, maintainability, reliability, etc). So I have
the luxury of "wallowing in academia" on this project and grappling with a
bunch of design tradeoffs. There's nothing like a real proejct to make us
think about stuff from a different perspective - like this whole Singleton
question. I've been doing Singleton for a while now and never thought of
passing in some values - where those values ideally are present upon
initialization of the Singleton (and we *really* also do NOT have a
factory).

So per this duscussion we once again see that patterns are very much about
communication and expectations about code and even readability of code - and
not nearly so much about actual implementation (i.e., "a pattern isn't a
library"). We can technically implement a pattern - but could go very much
against the spirit and intent of patterns in generall if we come up with a
nutso implementation.

Cheers.
 
Back
Top