form inheriting singleton

false74

Well-known member
Joined
Aug 4, 2010
Messages
76
Programming Experience
Beginner
here is my dilemma (or misunderstanding most likely):
I have a main form called "mainmodule" which is set up to run as a singleton.
Now what I want to do is make another class which inherits the mainmodule class.
I'm not sure if that is how it should be properly done, but in the long run all I want is multiple "submodules" that inherit the "mainmodule" so that I will not have to implement the singleton methods on each "submodule".

VB.NET:
Public Class mainmodule
    Inherits System.Windows.Forms.Form
    Public components As System.ComponentModel.IContainer

    Private Shared instance As mainmodule
    Public Shared Function Instanced() As mainmodule
        If instance Is Nothing Then
            instance = New mainmodule
        End If
        Return instance
    End Function
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
        instance = Nothing
    End Sub

    Public Sub New()

    End Sub
End Class

VB.NET:
Public Class submodule
    Inherits mainmodule

    Protected Sub New()
        MyBase.New()
        me.Text = "subform singleton"
    End Sub
End Class

VB.NET:
Windows.Forms.Application.Run(submodule.Instanced())

I assume my issue is with how the "instanced()" method is written, as it returns a new "mainmodule" form and not that of the subform.
 
What is the requirement, a global singleton for any derived type or a singleton for each derived type? I would guess the latter since the former wouldn't really make sense. (for example getting a InheritedB object when requesting the InheritedA singleton...)

I did some research and the best option I found was the suggestion from darwen in this thread to use generics: Singleton Pattern problem (inheritance) - CodeGuru Forums
VB.NET:
Public Class Singleton(Of T As Form)
    Inherits System.Windows.Forms.Form

    Private Shared _instance As T
    Public Shared Function Instance() As T
        If _instance Is Nothing Then
            Dim ctor = GetType(T).GetConstructor(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic, Nothing, Type.EmptyTypes, Nothing)
            _instance = CType(ctor.Invoke(Nothing), T)
        End If
        Return _instance
    End Function
End Class
VB.NET:
Public Class Inherited
    Inherits Singleton(Of Inherited)

    Private Sub New()
        MyBase.New()
        Me.Text = "subform singleton"
    End Sub
End Class
VB.NET:
Dim inst As Inherited = Inherited.Instance 'or Singleton(Of Inherited).Instance
 
This works! Thank you! I didn't even think this was possible to do. I modified/added onto the code to override the dispose method so the form never disposes (needed for my project). If anyone wants to see my final code here it is:

VB.NET:
Imports System.Windows.Forms
Public Class Singleton(Of T As Form)
    Inherits System.Windows.Forms.Form

    Private Shared _instance As T
    Public Shared Function Instance() As T
        Dim tp = GetType(T)
        If _instance Is Nothing Then    'if not created
            Dim ctor = tp.GetConstructor(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic, Nothing, Type.EmptyTypes, Nothing)
            _instance = CType(ctor.Invoke(Nothing), T)
        End If
        Return _instance
    End Function

    Public components As System.ComponentModel.IContainer
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()    'dispose unmannaged resources
            End If
            _instance = Nothing 'do not dispose, set to null
        End If
        MyBase.Dispose(disposing)
    End Sub

End Class

VB.NET:
Imports System.Windows.Forms
Public Class subform
    Inherits Singleton(Of subform)

    Protected Sub New()
        MyBase.New()
        Me.Text = "subform"
    End Sub
End Class
and to show the form:
VB.NET:
Windows.Forms.Application.Run(fbscoring.Instance())

Once again, thanks! This saves me so much time and code!
 
override the dispose method so the form never disposes
This is not what you're doing, to do that you would have to avoid the call to the base Dispose method (and of course not do any disposing yourself). Otherwise the code is fine for that, setting _instance to Nothing ensures a new instance is created next time you call the Instance function. You could also add "OrElse _instance.IsDisposed" to the Instance function.

You can drop the Overloads keyword, it is a pure Overrides.
IContainer is not unmanaged.
 
Hmm, I like that way better.
VB.NET:
    Public Shared Function Instance() As T
        Dim tp = GetType(T)
        If _instance Is Nothing OrElse _instance.IsDisposed Then    'if not created
            Dim ctor = tp.GetConstructor(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic, Nothing, Type.EmptyTypes, Nothing)
            _instance = CType(ctor.Invoke(Nothing), T)
        End If
        Return _instance
    End Function

IContainer is not unmanaged.
Does this mean I do not need to dispose it?
 
Does this mean I do not need to dispose it?
You do need to dispose any disposable object during disposing. I was just commenting on your labeling it as 'unmanaged'.
 
Back
Top