Author |
Message |
Jon Skee #1 / 24
|
Subclassing Singleton
Quote:
> Sorry if this was ambiguous. > I want to create a unique instance of each subclass. That is, > zero instances of BaseSingleton, and one instance of each subclass of > FooSingleton, BarSingleton, BazSingleton, etc: > public abstract class BaseSingleton {..} > public class FooSingleton : BaseSingleton {..} > public class BarSingleton : BaseSingleton {..} > public class BazSingleton : BaseSingleton {..}
As Chad says, it sounds like a factory would be a better idea. Is there any particular reason for introducing inheritance here at all? Should the subclasses really inherit, or is their main point of commonality their singletonity (!) ? -- Jon Skeet
If replying to the group, please do not mail me at the same time
|
Mon, 18 Apr 2005 01:12:38 GMT |
|
|
Mark A. Richma #2 / 24
|
Subclassing Singleton
My requirements are self-imposed :) Here is my idea: I have a client-server app in which I have a data access object for each class of business object. Each of these DAO's has the same SQL connection logic, protected DataSet member, etc. There is no need for more than one instance of each of these on the client. Hence, the Singleton requirement. The idea was to limit the instances to one by using a Singleton, and to refactor the redundant logic out of the DAO's by pulling it up to a base class. My thought was that this base class should be a Singleton, and subclasses of it would be responsible for business object specific logic, i.e. SQL queries. Each subclass would then inherit the connection logic, protected DataSet member, etc. from the base class, and still be limited to a single instance each. Maybe this clears it up ;) Thanks again, Mark Quote:
> How would I go about creating a Singleton class that can be subclassed? > Specifically, I want to avoid the GoF solution of a private registry of > subclasses, simply because I don't want to have to edit the base class > every time I create a subclass. The registry-based solution maintains > a hash of all known subclasses. To me, this breaks the encapsulation > of the solution. > Is there a way to do this via reflection/introspection: > public class BaseSingleton > { > ... > protected Instance() > { > // return unique instance of subclass > ??? > } > } > public class MySingleton : BaseSingleton > { > ??? > }
|
Mon, 18 Apr 2005 00:54:56 GMT |
|
|
Jon Skee #3 / 24
|
Subclassing Singleton
Quote:
> I wanted them to inherit the "singletonity" as well as the common data > access logic. See my reply-to-self.
I would worry about the "singletonity" (I know that's probably not the right word, but it's too good a one to waste) in the subclasses (it's easy enough to do) and just provide the appropriate resources/logic in the superclass. Note that that gives you the flexibility in the future to have some subclasses which *are* singletons and others which are not. How you decide to *retrieve* the singleton instances, of course, is a somewhat different matter, and one which you'll have to elaborate on the requirements for before any recommendations can sensibly be presented. -- Jon Skeet
If replying to the group, please do not mail me at the same time
|
Mon, 18 Apr 2005 01:34:38 GMT |
|
|
Jon Skee #4 / 24
|
Subclassing Singleton
Quote:
> public MySingleton > { > private static MySingleton instance; > protected MySingleton() : base() {} > public MySingleton Instance > { > get > { > if( instance == null ) > MySingleton.instance = new MySingleton(); > return MySingleton.instance; > } > } > /* yadda, yadda, yadda */ > }
Any reason for suggesting this singleton pattern instead of the more common (and simpler once you understand it, and threadsafe): public MySingleton { private static MySingleton instance = new MySingleton(); // Prevent further subclasses, which could break singletonity private MySingleton() { } public static MySingleton Instance { get { return instance; } } Quote: }
? It's still loaded lazily due to the way that static constructors are handled. If there are other static methods which should be able to be called without creating an instance, there are ways of achieving that, too, using a private nested class which contains the instance variable. -- Jon Skeet
If replying to the group, please do not mail me at the same time
|
Mon, 18 Apr 2005 01:46:54 GMT |
|
|
Jon Skee #5 / 24
|
Subclassing Singleton
Quote:
> Yeah, the way you mentioned is better. Sorry, it's been awhile since > I've had to use a singleton for anything, and I forgot about the > discussion we had in this group a couple months ago about this.
LOL - there speaks a man who presumably just hasn't had to use them much himself? It's the kind of thing that gets burned into your brain after you've written it a few times :) -- Jon Skeet
If replying to the group, please do not mail me at the same time
|
Mon, 18 Apr 2005 01:54:32 GMT |
|
|
Chad Myer #6 / 24
|
Subclassing Singleton
Quote:
> > public MySingleton > > { > > private static MySingleton instance; > > protected MySingleton() : base() {} > > public MySingleton Instance > > { > > get > > { > > if( instance == null ) > > MySingleton.instance = new MySingleton(); > > return MySingleton.instance; > > } > > } > > /* yadda, yadda, yadda */ > > } > Any reason for suggesting this singleton pattern instead of the more > common (and simpler once you understand it, and threadsafe): > public MySingleton > { > private static MySingleton instance = new MySingleton(); > // Prevent further subclasses, which could break singletonity > private MySingleton() > { > } > public static MySingleton Instance > { > get { return instance; } > } > } > ? > It's still loaded lazily due to the way that static constructors are > handled. If there are other static methods which should be able to be > called without creating an instance, there are ways of achieving that, > too, using a private nested class which contains the instance
variable. Yeah, the way you mentioned is better. Sorry, it's been awhile since I've had to use a singleton for anything, and I forgot about the discussion we had in this group a couple months ago about this. -c
|
Mon, 18 Apr 2005 01:52:09 GMT |
|
|
Chad Myer #7 / 24
|
Subclassing Singleton
Quote: > Great! Thanks. I guess what I was trying to accomplish was to "pull-up" > the instance member, Instance property, and 'get' logic into the base class. > I'm still curious if this is possible ;)
A property can only return one type of object. So, you can move Instance up to the base class, but you'll have to have it return DAOSingletonBase rather than MySingleton and the caller will have to cast up. -c
|
Mon, 18 Apr 2005 01:54:28 GMT |
|
|
Mark A. Richma #8 / 24
|
Subclassing Singleton
Great! Thanks. I guess what I was trying to accomplish was to "pull-up" the instance member, Instance property, and 'get' logic into the base class. I'm still curious if this is possible ;) - Mark
|
Mon, 18 Apr 2005 01:53:06 GMT |
|
|
Mark A. Richma #9 / 24
|
Subclassing Singleton
I wanted them to inherit the "singletonity" as well as the common data access logic. See my reply-to-self. - Mark Quote:
>> Sorry if this was ambiguous. >> I want to create a unique instance of each subclass. That is, >> zero instances of BaseSingleton, and one instance of each subclass of >> FooSingleton, BarSingleton, BazSingleton, etc: >> public abstract class BaseSingleton {..} >> public class FooSingleton : BaseSingleton {..} >> public class BarSingleton : BaseSingleton {..} >> public class BazSingleton : BaseSingleton {..} > As Chad says, it sounds like a factory would be a better idea. Is there > any particular reason for introducing inheritance here at all? Should the > subclasses really inherit, or is their main point of commonality their > singletonity (!) ?
|
Mon, 18 Apr 2005 01:24:44 GMT |
|
|
Jon Skee #10 / 24
|
Subclassing Singleton
Quote:
> Great! Thanks. I guess what I was trying to accomplish was to "pull-up" > the instance member, Instance property, and 'get' logic into the base class. > I'm still curious if this is possible ;)
Not without using reflection and/or still having a commonly named member in each of the subclasses. If you let the base class instantiate the subclasses, there's nothing to stop other classes from instantiating them too - certainly not within the same assembly. (I suppose you could do something horrible, like trying to work out the stack trace of the current thread and throwing an exception if it were inappropriate, but that's just horrible!) In order to keep them as singletons, they need to have a private constructor each, which means there needs to be *something* available within the class itself to create the instance. How would you access the instances in such a case though? Would you still want to use SubClass.Instance, but that actually end up calling BaseClass.Instance? There are no doubt other schemes which may or may not have their own swings and roundabouts... -- Jon Skeet
If replying to the group, please do not mail me at the same time
|
Mon, 18 Apr 2005 01:58:40 GMT |
|
|
Chad Myer #11 / 24
|
Subclassing Singleton
Quote: > Well, you're right - Instance should be a property which is get()-only. > However, the nature of the problem is to remove the instance lookup and > creation responsibility from the subclasses and require the base class to > return the proper subclass instance. The base class could maintain a hash > of subclasses that register themselves with a static initializer. But how > do you lookup and return the proper subclass from
BaseSingleton.Instance() Quote: > ???
It sounds like what you want is the Factory Pattern. Quote: > I could put a static initializer block in the subclasses such that they > register themselves with the base class instance, but how do you guarantee > which static initializer is called first -- the subclass could execute its > static initializer first and operate on a null base class instance.
The static initializer is called when the type is first loaded. So the first reference to a specific type will involve calling the static init, any hard-coded instance values, and finally the instance constructor. So, if you did something like: BaseSingleton.Instance(); Subclass1.Instance(); Subclass2.Instance(); ... somewhere in your initialization code (Global.asax for an ASP.NET web app, or whatever) then it would execute the static initializers in that order. However, I'm not sure if that's necessarily written in stone and I believe that you've coded yourself into a corner. Why don't you let us know what you're trying to accomplish at a higher level and we can recommend a better design perhaps. Quote: > Maybe someone with deep C# language internals knowledge can lend a hand > here. Well, this is more of a design question, not a language question. I think you're approaching this from the wrong position. -c Quote:
> >> How would I go about creating a Singleton class that can be > > subclassed? > >> Specifically, I want to avoid the GoF solution of a private registry > > of > >> subclasses, simply because I don't want to have to edit the base class > >> every time I create a subclass. The registry-based solution maintains > >> a hash of all known subclasses. To me, this breaks the encapsulation > >> of the solution. > >> Is there a way to do this via reflection/introspection: > >> public class BaseSingleton > >> { > >> ... > >> protected Instance() > >> { > >> // return unique instance of subclass > >> ??? > >> } > >> } > >> public class MySingleton : BaseSingleton > >> { > >> ??? > >> } > > Well, if Instance is a property, you have to specify a type. > > You could make it always return BaseSingleton and subclasses > > could override the property and return their own instances > > (downcasted to BaseSingleton of course) and then you could > > up-cast it back to your subclass type. > > The Instance property could return object or something else, > > but that's not much better. > > You can't change the return type of a method or property > > at run-time, so you're going to have to have some casting > > no matter what. > > -c
|
Mon, 18 Apr 2005 00:30:40 GMT |
|
|
Mark A. Richma #12 / 24
|
Subclassing Singleton
Sorry if this was ambiguous. I want to create a unique instance of each subclass. That is, zero instances of BaseSingleton, and one instance of each subclass of FooSingleton, BarSingleton, BazSingleton, etc: public abstract class BaseSingleton {..} public class FooSingleton : BaseSingleton {..} public class BarSingleton : BaseSingleton {..} public class BazSingleton : BaseSingleton {..} Thanks, Mark Quote:
>> How would I go about creating a Singleton class that can be subclassed? > First, define exactly what you mean by that. If you allow a class to be > subclasses, that subclass won't necessarily put the same restrictions on > that a sealed class can enforce. Do you want there to only be one of > *each* subclass, or can only the first subclass to try to instantiate > itself succeed? What exactly are you trying to achieve? > (I'm not trying to be funny - I genuinely don't know what you're after > here.)
|
Mon, 18 Apr 2005 00:32:19 GMT |
|
|
Nicholas Paldino [.NET/C# MVP #13 / 24
|
Subclassing Singleton
Mark, If you are using static constructors, then basically when you reference a type for a class in an assembly, it's static constructor is called (if there is one). So, if your subclass calls a static method/property, or creates an instance of a type, the static constructor for that type is called before the call goes through. However, the problem I think you will have is getting the subclass to register itself with the singleton. Before the singleton's map is created, you have to activate the type in some way in order to have its static constructor called. Hope this helps. -- - Nicholas Paldino [.NET/C# MVP]
Quote: > Well, you're right - Instance should be a property which is get()-only. > However, the nature of the problem is to remove the instance lookup and > creation responsibility from the subclasses and require the base class to > return the proper subclass instance. The base class could maintain a hash > of subclasses that register themselves with a static initializer. But how > do you lookup and return the proper subclass from BaseSingleton.Instance() > ??? > I could put a static initializer block in the subclasses such that they > register themselves with the base class instance, but how do you guarantee > which static initializer is called first -- the subclass could execute its > static initializer first and operate on a null base class instance. > Maybe someone with deep C# language internals knowledge can lend a hand > here. > I hope I am not overcomplicating my question ;) > Thanks, > Mark
> >> How would I go about creating a Singleton class that can be > > subclassed? > >> Specifically, I want to avoid the GoF solution of a private registry > > of > >> subclasses, simply because I don't want to have to edit the base class > >> every time I create a subclass. The registry-based solution maintains > >> a hash of all known subclasses. To me, this breaks the encapsulation > >> of the solution. > >> Is there a way to do this via reflection/introspection: > >> public class BaseSingleton > >> { > >> ... > >> protected Instance() > >> { > >> // return unique instance of subclass > >> ??? > >> } > >> } > >> public class MySingleton : BaseSingleton > >> { > >> ??? > >> } > > Well, if Instance is a property, you have to specify a type. > > You could make it always return BaseSingleton and subclasses > > could override the property and return their own instances > > (downcasted to BaseSingleton of course) and then you could > > up-cast it back to your subclass type. > > The Instance property could return object or something else, > > but that's not much better. > > You can't change the return type of a method or property > > at run-time, so you're going to have to have some casting > > no matter what. > > -c
|
Mon, 18 Apr 2005 00:23:14 GMT |
|
|
Chad Myer #14 / 24
|
Subclassing Singleton
Is this a fixed requirement? Why do you need subclasses? Perhaps there's a better way that doesn't involve the complexities you're going to encounter with subclassing a singleton. For example, it sounds like what you want is a factory, not necessarily subclasses. -c
Quote: > Sorry if this was ambiguous. > I want to create a unique instance of each subclass. That is, > zero instances of BaseSingleton, and one instance of each subclass of > FooSingleton, BarSingleton, BazSingleton, etc: > public abstract class BaseSingleton {..} > public class FooSingleton : BaseSingleton {..} > public class BarSingleton : BaseSingleton {..} > public class BazSingleton : BaseSingleton {..} > Thanks, > Mark
> >> How would I go about creating a Singleton class that can be subclassed? > > First, define exactly what you mean by that. If you allow a class to be > > subclasses, that subclass won't necessarily put the same restrictions on > > that a sealed class can enforce. Do you want there to only be one of > > *each* subclass, or can only the first subclass to try to instantiate > > itself succeed? What exactly are you trying to achieve? > > (I'm not trying to be funny - I genuinely don't know what you're after > > here.)
|
Mon, 18 Apr 2005 00:34:46 GMT |
|
|
Chris #15 / 24
|
Subclassing Singleton
Just don't forget to cast.... public static FooSingleton DefinedInstance { get { return (FooSingleton)instance; } Quote: }
AND public static BarSingleton DefinedInstance { get { return (BarSingleton)instance; } Quote: }
Chris R.
Quote: > Here's a conceptual workup of using a BaseSingleton. However, > you'll have to note the limitations on your code with this. Depending > on what you need, it may suffice. > //************************** > public abstract class BaseSingleton > { > protected static BaseSingleton instance; > protected BaseSingleton() > { > } > public static BaseSingleton Instance > { > get { return instance; } > } > } > //************************** > public class FooSingleton : BaseSingleton > { > static FooSingleton() > { > instance = new FooSingleton(); > } > protected FooSingleton() > { > } > public static FooSingleton DefinedInstance > { > get { return instance; } > } > } > //************************** > public class BarSingleton : BaseSingleton > { > static BarSingleton() > { > instance = new BarSingleton(); > } > protected BarSingleton() > { > } > public static BarSingleton DefinedInstance > { > get { return instance; } > } > } > //************************** > Chris R.
> > Great! Thanks. I guess what I was trying to accomplish was to > "pull-up" > > the instance member, Instance property, and 'get' logic into the base > class. > > I'm still curious if this is possible ;) > > - Mark
|
Mon, 18 Apr 2005 02:48:34 GMT |
|
|
Page 1 of 2
|
[ 24 post ] |
|
Go to page:
[1]
[2] |
|