Singleton class and dispose (question of style really)

S

Simon

Hi.

I don't have a problem per se, I was just wondering if anyone can
offer some opinions about the best way to go about creating and
disposing of a Singleton class.

I have a class (handling DB connections) which I have defined as a
singleton, using the following pattern (VB.net code)

Private Shared mInstance As clsConnection = Nothing

Public Shared ReadOnly Property Instance() As clsConnection
Get
If mInstance Is Nothing Then
mInstance = New clsConnection
End If
Instance = mInstance
End Get
End Property

I use this in many functions in my project, and whenever I do use it,
it's usually like this;

Private Sub MySub()
Dim myConn as clsConnection
try
myConn.Instance.SomeDBops()
catch ex as exception
finally
myConn.Instance.Dispose
end try
end sub

So far so good, I'm relatively pleased that the class will be
instanciated and disposed of at the correct times.

But what if I was to call MySub from another sub that also wished to
use a/the connection object.

Private Sub AnotherSub()
Dim myConn as clsConnection
try
myConn.Instance.SomeDBops()

MySub()
catch ex as exception
finally
myConn.Instance.Dispose
end try
end sub


The singleton will be disposed of within MySub, but then when
execution reaches the finally statement in AnotherSub, an instance of
clsConnection is created just so it can be disposed of. If have lots
of similarly nested calls this happens a lot. So what do I do about
this. I could always make my connection some global or member, but I
would really like resources to be freed as soon as they are no longer
required.

So I thought maybe I could define a singleton style dispose.
Something like this;

Public Shared Sub singleDispose()
If Not mInstance Is Nothing Then
mInstance.Dispose() 'Dispose sets mInstance to Nothing
End If
End Sub

So now in my finally clauses I call myConn.singleDispose, avoiding the
case where an instance is created only to be disposed of.

Can anyone offer an opinion as to whether this is a good thing to do.
Am I adding needless overhead here? Should I care about objects being
instanciated, only to be disposed? Should I except that using members
and/or globals would be a better approach? Vague I know but at the
moment I find this approach rather pleasing, but I'm not too sure if I
should. Have I misunderstood the usage of singletons and .net object
creatation, or is this a good way to go.

TIA for any comments.
 
J

Jon Skeet [C# MVP]

Simon said:
I don't have a problem per se, I was just wondering if anyone can
offer some opinions about the best way to go about creating and
disposing of a Singleton class.

Creating, yes. Disposing - I have fewer opinions...
I have a class (handling DB connections) which I have defined as a
singleton, using the following pattern (VB.net code)

Private Shared mInstance As clsConnection = Nothing

Public Shared ReadOnly Property Instance() As clsConnection
Get
If mInstance Is Nothing Then
mInstance = New clsConnection
End If
Instance = mInstance
End Get
End Property

That isn't thread-safe.

See http://www.pobox.com/~skeet/csharp/singleton.html

The singleton will be disposed of within MySub, but then when
execution reaches the finally statement in AnotherSub, an instance of
clsConnection is created just so it can be disposed of. If have lots
of similarly nested calls this happens a lot. So what do I do about
this. I could always make my connection some global or member, but I
would really like resources to be freed as soon as they are no longer
required.

It sounds like you don't *really* want a singleton, to be honest.
So I thought maybe I could define a singleton style dispose.
Something like this;

Public Shared Sub singleDispose()
If Not mInstance Is Nothing Then
mInstance.Dispose() 'Dispose sets mInstance to Nothing
End If
End Sub

So now in my finally clauses I call myConn.singleDispose, avoiding the
case where an instance is created only to be disposed of.

Well, it's no longer really a singleton. You could end up with two
different instances at the same time - someone could "fetch" one and
keep a reference to it, then another method disposes it, then a third
method uses the property again - the first class would still have a
reference to a now-disposed object.

Singletons are designed to be long-lasting. Objects implementing
IDisposable are generally designed to be transient - the two just don't
go well together.

Perhaps you should look at a factory pattern instead?
 
S

Simon

Thanks for the reply.

That many instances issues struck me as soon as I posted that message
(Isn't it always the way). Yes, I don't think the singleton is really
what I need (or my proposed perversion of it). Thanks for the
suggestion of the factory pattern, and the clarification of Singletons
and Dispose not really being compatable, I'll keep that in mind next
time I start to go anywhere near this line of reasoning.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top