Il pattern Singleton garantisce che una classe abbia una sola istanza e fornisce un punto di accesso globale ad essa. In VB.NET si usa spesso un costruttore privato e una proprietà statica per memorizzare l'unica istanza:
Public Class Singleton Private Shared _instance As Singleton Private Sub New() ' Costruttore privato End Sub Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property End Class
Sicurezza nei thread:
In un ambiente multi-thread è possibile che vengano creati due istanze in caso di accesso simultaneo. Soluzione: utilizzare un blocco o la costruzione Lazy(Of T):
' Implementazione pigra e sicura per i thread Public Class Singleton Private Shared ReadOnly _instance As New Lazy(Of Singleton)(Function() New Singleton()) Private Sub New() End Sub Public Shared ReadOnly Property Instance() As Singleton Get Return _instance.Value End Get End Property End Class
Differenza:
Qual è il rischio di avere un codice così per implementare il Singleton?
Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property
Risposta: In un ambiente multi-thread può accadere che due thread vedano contemporaneamente che _instance è Nothing e entrambi creino un oggetto. Pertanto, questo approccio non è completamente sicuro per i thread. Si raccomanda di utilizzare Lazy(Of T) o SyncLock per il blocco.
Storia
Sistema ERP: Un logger Singleton avviato da servizi veniva talvolta creato due volte, perdendo i log. Motivo: mancanza di sincronizzazione nella proprietà, sebbene l'applicazione fosse multi-thread.
Storia
Applicazione Windows Forms: Nel progetto si è portata la gestione del database in Singleton, ma non è stata implementata l'inizializzazione pigra. All'avvio dell'applicazione si verificava una pesante connessione, rallentando il caricamento dell'interfaccia utente per tutti.
Storia
Plugin di una piattaforma giornalistica: Si è cercato di utilizzare una variabile statica in un modulo per il Singleton, non protetta da accesso multi-thread, il risultato è stata la creazione di più istanze del gestore delle email durante i picchi di carico, causando email duplicate.