Stò facendo varie prove sulla serializzazione ed ho incontrato delle domande che ritengo interessanti.
Stò costruendo delle classi per gestire in modo flessibile i settaggi (opzioni di configurazione) di una mia applicazione. Questa applicazione necessita di molte opzioni (sono alla base della logica della mia applicazione).
Per gestire queste informazioni ho creato una classe che implementa il pattern Singleton e serializzo/deserializzo questa classe per creare un file XML contenente le configurazioni.
Logicamente mi pare una soluzione ma stò incontrando alcuni problemi a livello logico che mi piacerebbe condividere e risolvere con voi.
I dati dei settaggi sono logicamente organizzabili per in gruppi ben definiti: ad esempio, l'applicazione si dovrà connettere a 2 database diversi e quindi avrò i dati di Server, User, Password e NomeDB per ognuna delle 2 connessioni.
Per fare questo posso fare:
<XmlRoot(ElementName:="Configurazione")> _
Public Class MieConfig
'Oggetto per il controllo del singleton
Private Shared _Values As MieConfig
Private Const _FileConfig As String = "Config.xml"
Shared Sub New()
'Utile a rendere singleton la classe
Load()
End Sub
Public Shared ReadOnly Property Value() As Config
Get
'Controlla che non esista un'istanza della classe (Singleton)
If (_Values Is Nothing) Then
'istanzia la classe solo se non già istanziata
_Values = New MieConfig
End If
'Ritorna la classe istanziata
Return _Values
End Get
End Property
Friend Shared Sub Load()
If IO.File.Exists(_FileConfig) Then
'Deserializza il file XML
Using fs As New IO.FileStream(_FileConfig, IO.FileMode.Open)
Dim xser As New Xml.Serialization.XmlSerializer(GetType(MieConfig))
_Values = DirectCast(xser.Deserialize(fs), MieConfig)
End Using
End If
End Sub
Public Shared Sub Save()
'Serializza il file XML
Using fs As New IO.FileStream(_FileConfig, IO.FileMode.Create)
Dim xser As New Xml.Serialization.XmlSerializer(GetType(MieConfig))
xser.Serialize(fs, _Values)
End Using
End Sub
#Region "Proprietà"
Private _Server1 As String
<XmlElement(ElementName:="Server1")> _
Public Property Server1() As String
Get
Return _Server1
End Get
Set(ByVal value As String)
_Server1 = value
End Set
End Property
Private _Server2 As String
<XmlElement(ElementName:="Server2")> _
Public Property Server2() As String
Get
Return _Server2
End Get
Set(ByVal value As String)
_Server2 = value
End Set
End Property
Private _User1 As String
<XmlElement(ElementName:="User1")> _
Public Property User1() As String
Get
Return _User1
End Get
Set(ByVal value As String)
_User1 = value
End Set
End Property
Private _User2 As String
<XmlElement(ElementName:="User2")> _
Public Property User2() As String
Get
Return _User2
End Get
Set(ByVal value As String)
_User2 = value
End Set
End Property
'... e così via
#End Region
End Class
Ho provato, attraverso le classi ad organizzare meglio i dati e ci sono riuscito in questo modo:
<XmlRoot(ElementName:="Configurazione")> _
Public Class MieConfig
'Oggetto per il controllo del singleton
Private Shared _Values As MieConfig
Private Const _FileConfig As String = "Config.xml"
Shared Sub New()
'Utile a rendere singleton la classe
Load()
End Sub
Public Shared ReadOnly Property Value() As MieConfig
Get
'Controlla che non esista un'istanza della classe (Singleton)
If (_Values Is Nothing) Then
'istanzia la classe solo se non già istanziata
_Values = New MieConfig
End If
'Ritorna la classe istanziata
Return _Values
End Get
End Property
Friend Shared Sub Load()
If IO.File.Exists(_FileConfig) Then
'Deserializza il file XML
Using fs As New IO.FileStream(_FileConfig, IO.FileMode.Open)
Dim xser As New Xml.Serialization.XmlSerializer(GetType(MieConfig))
_Values = DirectCast(xser.Deserialize(fs), MieConfig)
End Using
End If
End Sub
Public Shared Sub Save()
'Serializza il file XML
Using fs As New IO.FileStream(_FileConfig, IO.FileMode.Create)
Dim xser As New Xml.Serialization.XmlSerializer(GetType(MieConfig))
xser.Serialize(fs, _Values)
End Using
End Sub
#Region "Proprietà"
Private _Database1 As New Database1Class
<XmlElement(ElementName:="Database1")> _
Public Property Database1() As Database1Class
Get
Return _Database1
End Get
Set(ByVal value As Database1Class)
_Database1 = value
End Set
End Property
Private _Database1 As New Database2Class
<XmlElement(ElementName:="Database2")> _
Public Property Database2() As Database2Class
Get
Return _Database2
End Get
Set(ByVal value As Database2Class)
_Database2 = value
End Set
End Property
#End Region
End Class
Public Class Database1Class
#Region "Proprietà"
Private _Server As String = ""
<XmlElement(ElementName:="Server")> _
Public Property Server() As String
Get
Return _Server
End Get
Set(ByVal value As String)
_Server = value
End Set
End Property
Private _User As String = ""
<XmlElement(ElementName:="User")> _
Public Property User() As String
Get
Return _User
End Get
Set(ByVal value As String)
_User = value
End Set
End Property
'... e cos' via
#End Region
End Class
Public Class Database2Class
#Region "Proprietà"
Private _Server As String = ""
<XmlElement(ElementName:="Server")> _
Public Property Server() As String
Get
Return _Server
End Get
Set(ByVal value As String)
_Server = value
End Set
End Property
Private _User As String = ""
<XmlElement(ElementName:="User")> _
Public Property User() As String
Get
Return _User
End Get
Set(ByVal value As String)
_User = value
End Set
End Property
'... e così via
#End Region
End Class
Fin qui tutto OKe funziona, però mi ritrovo ad un bivio perchè vorrei sistemare alcune cose che non mi piacciono.
In primo luogo vorrei che le classi Database1 e Database2 fossero visibili solo dalla classe MieConfig perchè sono a suo esclusivo uso e consumo. Non riesco a farlo perchè se cambio il modificatore di accesso non posso definire le property nella classe MieConfig come Public e quindi non verrebbero serializzate da XMLSerialize.
Ho pensato di gestire le classi Database1 e Database2 come pubbliche aggiungendo altre proprietà, funzioni e metodi che mi permettano di gestire i DB in modo più mirato. Facendo ciò però incontrerei un problema successivo nel momento in cui volessi serializzare le singole classi: per serializzare la classe MieConfig mi servono alcune proprietà delle classi Database1 e Database2 ma serializzando la classe Database1 (ad esempio) vorrei poter serializzare altre proprietà pubbliche eventualmente con Attributi diversi...
Come posso risolvere questi "problemi"? Che consigli/dritte potete darmi? Cose ne pensate?
Grazie a tutti quelli che hanno avuto la pazienza di leggere e cercare di capire le mie elucubrazioni mentali 
Ciao!!!
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole