Question à propos des DTO's
Hello à tous,
J'ai récemment découvert une série de 3 articles via ce message.
N'ayant jamais eu de cours d'archi, je me forme sur le tas et cette série d'article tombe à pic !
Notemment, dans la partie où il traite des DTOParser et notamment des ordinaux afin d'accéder aux éléments des datareaders via leur index plutôt que leur nom (car c'est plus performant).
Pour un DTO simple, pas de souci. Mais comment fait-on pour un DTO qui contient d'autres DTO's ?
Prenons par exemple une classe Tel (pour téléphone) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Public Class Tel
Public Property Id As Integer
Public Property Type As TypeTel
Public Property Pays As Pays
Public Property Num As String
Public Sub New(ByVal id As Integer, ByVal type As TypeTel, ByVal pays As Pays, ByVal num As String)
Me.Id = id
Me.Type = type
Me.Pays = pays
Me.Num = num
End Sub
End Class |
Où TypeTel indique de quel type de téléphone il s'agit (fixe, portable, fax, etc.) et Pays indique le pays histoire d'avoir l'indicatif téléphonique du-dit pays.
Donc en suivant l'article, je commence vaillamment à créer une classe ParserTel comme suit :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Public Class Parser_Tel
Private ord_id As Integer
Private ord_num As Integer
Public Function PopulateDTO(reader As System.Data.SqlClient.SqlDataReader) As Tel
End Function
Public Sub PopulateOrd(reader As System.Data.SqlClient.SqlDataReader)
End Sub
End Class |
Mais je bloque pour Pays et TypeTel. Toutes les données nécessaires à la création de ces deux instances se trouvent dans la datareader (pour ne pas devoir refaire un accès db pou récupérer le pays et le type sur base de leur Id).
Faut-il faire appel au parser du DTO Pays dans la fonction PopulateDTO ??
J'espère avoir été clair :aie:
Comment faire une fabrique générique de classe ?
Bonjour,
Ayant vu ce fil, j'ai voulu utiliser le principe.
J'aurai voulu rendre ceci plus générique, mais je butte sur un problème.
J'ai une classe abstraite pour les DTO (bib DTO)
Code:
1 2 3 4
| Public MustInherit Class DTOParser
Public MustOverride Function PopulateDTO(ByVal reader As DbDataReader) As clsDTOBase
Public MustOverride Sub PopulateOrdinals(ByVal reader As DbDataReader)
End Class |
Je cré des classes qui hérite de DTOParser (comme dans les liens sur les DTO)
Code:
1 2 3
| MustInherit Class DTOParser_Person
Inherits DTOParser
'... |
J'ai des classes pour utiliser un DTO typé
Code:
1 2 3 4
| Public Function GetPersonId(ByVal PersonId As String) As PersonDTO
DALApp.AjouteParam("PersonId", DbType.String, PersonId)
Return DALApp.GetSingleDTO(Of PersonDTO)("select * from personnes where PersonId = ?")
End Function |
Cette méthode GetSingleDto fait partie de ma DAL (bib DAL) et c'est ici que je souhaite utiliser une fabrique de DTO générique
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Public Function GetSingleDTO(Of T As clsDTOBase)(ByVal Requete As String) As T 'where T as clsdtobase
Dim UnDTO As T = Nothing
Dim Reader As DbDataReader
Try
Using Reader
If ExecuterReader(Requete, Reader) = 0 Then
If Reader.HasRows Then
Reader.Read()
Dim parser As DTOParser
parser = DTOParserFactory.GetParser(GetType(T))
'parser = CType(DTOParserFactory.CreInstanceDTO("PersonDTO"), DTOParser)
'parser = DTOFabriqueAnalyseur.GetAnalyseur(GetType(T))
parser.PopulateOrdinals(Reader)
UnDTO = DirectCast(parser.PopulateDTO(Reader), T)
End If |
Dans les exemples des liens les noms sont en dur. Cela ne me convient pas puisque ma méthode sera placé dans la bib DTO et ne connais donc pas les noms des classes qui seront crées dans l'appli qui l'utilisera.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Public NotInheritable Class DTOParserFactory
Public Shared Function GetParser(ByVal DTOType As System.Type) As DTOParser
Select Case DTOType.Name
Case "PersonDTO"
Return New DTOParser_Person()
Exit Select
Case "PostDTO"
'Return New DTOParser_Post()
Exit Select
'...
End Select
Throw New Exception("Unknown Type")
End Function |
D'ou ma question comment faire une fabrique générique de classe ? fabrique qui prendrait un type T (classe quelconque) et qui renverrai une instance de cette classe typé (ex : PersonDTO)
Je n'ai rien trouvé de concret sur le net malgrès différentes recherche. J'ai essayé
Code:
1 2 3 4 5 6 7 8 9 10
| Public NotInheritable Class DTOFabriqueAnalyseur(Of T As {Class, New})
Private Sub New()
End Sub
Public Shared Function GetAnalyseur(Of _T As {Class, New})() As DTOParser
Dim dto_parser As Type = GetType(_T)
Dim typeArgs As Type() = {GetType(DTOParser)}
Dim ClasseDyn As Type = dto_parser.MakeGenericType(typeArgs)
Return Activator.CreateInstance(ClasseDyn)
End Function
End Class |
Mais j'ai des problème de convertion de type.
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| Public NotInheritable Class DTOParserFactory
Public Shared Function CreInstanceDTO(ByVal typeName As String) As Object
For Each assembly As Reflection.Assembly In AppDomain.CurrentDomain.GetAssemblies()
For Each type As Type In assembly.GetTypes()
If (typeName = type.Name) OrElse (typeName = type.FullName) Then
Return Activator.CreateInstance(type)
End If
Next
Next
Return Nothing
End Function
End Class |
mais le debbogger se perd. [Edit] sur la ligne If (typeName = type.Name) OrElse (typeName = type.FullName) Then [/Edit]
Je cherche depuis un moment, mais je ne trouve pas. Si vous avez une idée ou une solution, je suis à l'écoute.
A+, Hervé.