Ok mais quel est l'intérêt de mettre cela dans une librairie à part ???
Ok mais quel est l'intérêt de mettre cela dans une librairie à part ???
Kropernic
Pour des développements en couche, on sépare ainsi très nettement les couches.
Tu as
- la bibliothèque d'éléments DTO commun à toutes tes appli
- la bibliothèque d'éléments DAL commun à toutes tes appli
La simplification des développements des autres applications. Tu n'as pas à réintroduire le code, tu références simplement les DLL. (comme celles de Visual Studio : System.Text, System.IO, System.Data, System.Linq, ...)
Simplification de la maintenance. Tu ajoutes de nouvelles fonctionnalitées (ou corrige des bugs) toutes tes applis en bénéficie.
Ensuite au niveau du code cela simplifie l'écriture.
Ex:
Dans l'appli
Pour l'accés à la couche données
Note : Le seul point génant pour l'instant est la difference entre "access" et les autres SGBD ce qui m'obligera a changer mes requetes dans l'appli si je bascule d'access vers un autre. (je vais essayer de voir cà)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Public Class clsDALAppli Protected Shared DALApp As clsDataAccessLayer Public Sub New() DALApp = New clsDataAccessLayer(IdBDD) 'le fichier de config contient toutes les info pour la BDD et l'environnement (access, sqlserver, ...) End Sub
Lecture d'info pour une personne (même la construction de la requête paramètrée est dans la couche DAL)
Bien sur il reste à construire les DTO perso à l'appli
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Public Class PersonDB Inherits clsDALAppli Public Function GetPersonId(ByVal PersonId As String) As PersonDTO DALApp.AjouteParam("PersonId", DbType.String, PersonId) Return DALApp.GetSingleDTO((New DTOParser_Person).GetType.AssemblyQualifiedName, "select * from personnes where PersonId = ?") End Function Public Function GetPersonByEmail(ByVal email As String) As PersonDTO DALApp.AjouteParam("email", DbType.String, email) Return DALApp.GetSingleDTO((New DTOParser_Person).GetType.AssemblyQualifiedName, "select * from personnes where email = ?") End Function
Un DTO personne
Le parser du DTO personne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Public Class PersonDTO Inherits clsdtobase Private mPersonId As Integer Public Property PersonId() As Integer Get Return mPersonId End Get Set(ByVal value As Integer) mPersonId = value End Set End Property '...
A voir si l'on ne pourrait pas faire un générateur pour ce genre de chose simple.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Class DTOParser_Person Inherits DTOParser Private Ord_PersonId As Integer '... Public Overrides Sub PopulateOrdinals(ByVal reader As DbDataReader) Ord_PersonId = reader.GetOrdinal("PersonId") '... Public Overrides Function PopulateDTO(ByVal reader As DbDataReader) As clsDTOBase Dim UnePersonne As PersonDTO = New PersonDTO Try If Not reader.IsDBNull(Ord_PersonId) Then UnePersonne.PersonId = reader.GetInt32(Ord_PersonId) '...
Ensuite utilisation pour l'interface (la grosse part du code sera ici)
Relativement simple à utiliser ensuite il me semble.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dim PersDb As PersonDB = New PersonDB Dim p As PersonDTO = PersDb.GetPersonByEmail("Email") MessageBox.Show(p.PersonId) ' juste pour exemple. Alimenter champs, liste, dataset, ...
Espérant avoir répondu à ta question.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Je ne pense pas que ce que tu cherches à faire soit possible. Il faut à un moment faire un "mapping", du type DTO vers le type DTOParser.
Donc à défaut de réflexion, il faut faire un switch, comme montré dans la partie 3 du tuto, et retourner la nouvelle instance correspondant.
Less Is More
Pensez à utiliser les boutons , et les balises code
Desole pour l'absence d'accents, clavier US oblige
Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.
Effectivement, c'est ce qu'il me semblait.
Et c'est surement pour cà que je ne trouve rien sur internet.
Ce n'est pas tout à fait là que ce situe le problème.
Car le PopulateDTO(ByVal reader As DbDataReader) As clsDTOBase du DTOParser renvoie bien un DTOBase dont hérite DTOPerson. (c'est un peu compliqué, j'en conviens)
Mais c'est bien ce type de problème que je rencontre pour une l'utilisation d'une classe générique en paramètre.
le cast du type DTOParser (classe de definition abstraite pour être connu dans la DAL) vers le type DTOParser_Person (classe réelle utilisée dans l'appli) n'est pas accepté en exécution.
Mais bon, je vais tout de même essayer de creuser encore un peu.
En tout cas merci d'avoir suivi et pour tes conseils.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Lol, j'ai bien compris que c'était pour le développement couche.
Mais ajouter encore une couche juste pour l'usine (et le dtobase?), je ne vois pas trop l'intérêt.
Pour ma part (mais j'admets d'être encore un noob en POO et encore plus en archi), la factory va très bien avec les DTO puisqu'elle n'est quand même pas utilisable sans eux.
Kropernic
Ce n'est pas une couche supplémentaire.
Le DTO est l'élément transversal léger qui permet de passer les infos entre les couches (U.I., Métier, DAL).
C'est ce qui est expliqué dans les tutos des liens.
Si on peut le rendre générique c'est très intéressant. (pour les raisons expliquées auparavent)
C'est pour cela que j'essaye de la placer dans la bib DTO, sinon cela à peu d'intérêt.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Rappel du problème :
Il me semble que j'approche de la solution, et même que j'ai trouvé.
Dans la bibliothèque DataTransfertObject
Une classe abstraite qui définie les méthodes utilisables dans les classes héritées. (équivalent à DTOParser)
La fabrique de classe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Public MustInherit Class ClassDynAbstraite Public MustOverride Function PopulateDTO() As clsDTOBase Public MustOverride Sub PopulateOrdinals() End Class
Dans l'appli (j'ai simplifié : sans la DAL)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Public NotInheritable Class DTOParserFactory Public Shared Function FabriqueClasse(Of T As {New})() As T Return New T End Function End Class
Une classe qui hérite de la classe abstraite (Equivalent à DTOParser_Person)
Appel
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 Imports DataTransfertObject Public Class ClassDyn Inherits ClassDynAbstraite Private mExiste As String = "Existe bel et bien." ' pour test. Public ReadOnly Property Existe() As String Get Return mExiste End Get End Property Sub New() End Sub Public Overrides Function PopulateDTO() As clsDTOBase Dim persDTO As PersonDTO = New PersonDTO persDTO.IsNew = True Return persDTO End Function Public Overrides Sub PopulateOrdinals() End Sub End Class
On a bien Existe bel et bien. - Une nouvelle personne : True
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Private Sub btnClassDyn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClassDyn.Click Dim InstanceClassDyn As ClassDyn = DTOParserFactory.FabriqueClasse(Of ClassDyn)() MessageBox.Show(InstanceClassDyn.Existe & " - Une nouvelle personne : " & (InstanceClassDyn.PopulateDTO.IsNew).ToString) End Sub
Ma fabrique placé dans la bibliothèque cré bien une nouvelle instance d'une classe qu'elle ne connait pas (d'ailleur, il n'y a pas de lien avec la classe abstraite) C'était là mon erreur, (mon post 24), d'essayer d'avoir un lien entre la classe abstraite et la classe réelle pour connaître la structure.
Et là, pas de réflexion. pour les perf.
C'était donc tout simple, juste en utilisant une classe générique en paramètre.
Bien, il me reste à adapter en passant à travers la DAL.
Merci à ceux qui ont suivi et surtout à DotNetMatt pour ces conseils
[Edit]
Note : l'exemple ci-dessus n'a aucun interrêt en lui même, il sert juste à résoudre un problème plus complexe. (créer un objet que la DAL ne connais pas, mais qui, en redescendant à travers elle sera alimenté avec les données de la BDD) [/Edit]
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Bonjour,
Je me permets de rouvrir cette discussion car j'ai une question sur l'utilisation des DTO's dans la couche BAL (car je pense que j'utilise cette architecture de travers).
Dans ma couche BAL, que dois-je faire exactement ?
Actuellement, ma couche BAL se "contente" de transférer les DTO's qu'elle reçoit de la couche GUI vers la couche DAL et inversément. Mais du coup, les classes de la couche DTO contiennent aussi des méthodes utilitaires alors qu'elles devraient contenir que des propriétés et un constructeur.
Si on reprend la classe PersonDTO de l'article, en quoi consisterait la classe PersonBAL si on devait la coder ?
Kropernic
Dans une archi en 3 couches, la couche métier (Business / BAL) sert à faire l'interface entre la DAL et l'UI, dans les deux sens. Donc :
- PersonDAL expose des méthodes qui permettent à l'application de communiquer avec la DB.
- PersonBAL consomme les méthodes de la DAL et expose les propriétés de l'objet Person ainsi que des méthodes permettant à l'UI d'interagir avec la DB via la DAL.
- Enfin on a l'UI qui consomme les propriétés exposées par la BAL (principe du binding), et communique avec la BAL via les méthodes qu'elle expose. DAns le sens inverse, quand l'UI renvoie des données, la BAL transfère les infos vers la DAL, qui à son tour manipule la DB.
Donc PersonDAL exposerait ses propriétés (Nom, Prénom, Email, bref tout ce qui caractérise une Personne dans ton application) + des méthodes publiques (Save, Update, Delete).
Eventuellement il peut y avoir d'autres méthodes privées (par exemple) qui feraient appel à une classe tierce pour valider par exemple un numéro de sécurité sociale, ou une adresse email. Ces méthodes privées peuvent être utilisées par les méthodes publiques (Save/Update/Delete).
Bien sûr rien ne t'empêche dans la BAL de définir la méthode de vérification du numéro de sécurité sociale en tant que public si tu en as besoin dans l'UI Mais bon c'est le principe d'encapsulation.
[EDIT] Regarde cet article, les schémas sont plutôt parlants : Three Layer Architecture in C# .NET
Less Is More
Pensez à utiliser les boutons , et les balises code
Desole pour l'absence d'accents, clavier US oblige
Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.
Rien à ajouter par rapport à ce qu'à dit DotNetMatt si ce n'est qu'au lieu de BAL (Business Access Layer) il faudrait mieux mettre BLL (Business Logic Layer).
Comme le dit DotNetMatt, tu auras donc 3 couches :
- UI (User Interface) : interface graphique.
- BLL (Business Logic Layer) : la couche de logique métier.
- DAL (Data Access Layer) : la couche d'accès aux données.
Je te conseille les 2 tutos suivants :
Introduction au développement en couches
Quelle est la différence entre un DTO et un POCO ?
Hum, je ne suis pas tout à fait d'accord avec DotNetMatt.
PersonDAL expose seulement des méthodes publiques (Save : Insert, Update, Delete; Select divers) Les données sont passés par les DTO (en paramètres d'entrés ou en retour de fonctions) qui eux ne contiennent que les propriétés de Person et le constructeur.
Transversal : (Disposé en travers : qui coupe en travers) pour nous dans le sens "qui circule à travers" les couches.
D'ailleur regarde - High Performance Data Access Layer Architecture Part 2
que tu donnes dans ton post de demande (post 1) par le lien message
Il n'y a aucune propriété de Person (Nom, Prénom, ...) dans la DALPerson (nommé PersonDB).
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Prenons l'exemple Person (avec l'âge en plus)
Contrôler les données avant sauvegarde.
. Imaginons que tu développes la couche métier pour la donner à d'autres développeurs. Ceux-ci ne contrôlerons peut-être pas l'âge.
Appliquer les calculs métiers, des règles de gestions.
. Calculer des moyennes d'âge par rapport à une liste DTO pour l'affichage, etc
Toujours avec l'âge en plus (cela me permet de facilement donner des exemples)
Contrôle des données.
. ex : date de naissance valide par rapport au jour actuel et à la durée de vie
Transfert simple d'un DTO
Transfert simple d'une liste DTO
Renvoie de données calculées .
. des fonctions qui reçoivent un DTO ou une liste DTO et renvoient : l'âge, la moyenne d'âge, le nombre de personnes dans une tranche d'âge, le nombre de personnes concernées pour un élément x ou y, etc...
Fonction métier
. préparation à l'envoie de mail. [Edit]je ne sais pas si l'exemple est bien bon[/Edit] avant appel au service de mail.
Etc ...
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Je me rends compte que ma question n'était pas claire mais à force d'y réfléchir, je commence à mieux cerner où se trouve mon problème de compréhension.
Voici donc une question plus cibler. La couche GUI travaille-t-elle avec des objets DTO qui sont triturés par la couche BLL (j'ai tenu compte de la marque et je dis donc maintenant BLL au lieu de BAL) et mis en DB par la couche DAL ou bien travaille-t-elle sur des objets de la couche BLL (qui hériteraient par exemple des DTO's) ?
En exemple avec un formulaire de recherche pour des clients. J'indique que je veux ceux habitant Paris et je clique sur le bouton de recherche. GUI fait donc appel à BLL au moyen de la fonction GetCustomers en passant le paramètre qui va bien. Qu'est-ce que BLL renvoi ? Une liste de DTO ou un liste de BAL ?
Si c'est une liste de DTO, si je pige bien, si maintenant de cette liste je veux extraire les clients dont le nom commence par la lettre "M", je fais appelle à une méthode de BAL en passant ma liste et j'en récupère une nouvelle ?
Kropernic
Attention BAL revient
Pour la deuxième et troisième question, dans ce cas, personnellement je dirai une liste DTO puis une nouvelle Liste DTO (mais je garderai l'ancienne comme référence si l'utilisateur change de lettre) une nouvelle puisque tu ne transforme pas les données.
Mais d'une façon plus générale, en cas de manip de transformation des données (dont découleront de nouvelles propriétés) tu seras obligé d'utiliser des "objets de la couche BLL (qui hériteraient par exemple des DTO's)" ou qui auront une propriété DTO (je préfére cela mais c'est personnel), enfin il me semble.
Mais je ne suis pas expert dans ce domaine
Bon, je dois partir au boulot, je reprendrais le fil ce soir
[Edit]
D'une manière générale
Si c'est juste une simple fonctionalité ne modifiant pas la structure du DTO renvoi d'un DTO ou d'une liste DTO (ou le résultat de la fonctionalité; calcul, ...) vers l'UI
Si des propriétés supplémentaires sont nécessaires renvoie un nouvel objet DTO-BLL (contenant le DTO + les nouvelles propriétés) sous forme simple ou liste vers l'UI.
Mais l'objet BLL manipulateur (couche BLL) peut garder le DTO d'origine sous forme de propriété afin de pouvoir renvoyer les données vers l'UI si celle-ci veut un sous-ensemble différent. Un peu comme on ferait avec un dataset. Avec une durée de vie limité au besoin de l'UI pour visualiser ces données.
Dans ce cas l'objet BLL (couche métier) va devenir un POCO puisqu'il aura le DTO d'origine et des nouvelles propriétés + des méthodes de manipulations qui renveront un nouveau genre de DTO BLL (retour du DTO + les nouvelles propriétés, voire même un autre ensemble de propriétés ne ressemblant pas au DTO) (je ne sais pas si tu suis) Ce cas se présente lorsque la couche métier effectue beaucoup de manipulation des données.
Après pour des appli simple, on n'est pas obligé daller aussi loin. Et tout dépend aussi de l'appli en terme de manipulation métier. Si c'est juste des contrôles et des calculs on reste dans le cas simple.
Si tu veux garder la phylosophie des tutos l'objet renvoyé vers l'UI doit être un objet léger (juste les propriétés)
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Less Is More
Pensez à utiliser les boutons , et les balises code
Desole pour l'absence d'accents, clavier US oblige
Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.
Pour répondre très précisément à tes questions
Voir la partie Edit de mon post précédant.
Une liste de DTO
Pour la question suivante, cela ne doit pas se situer dans la BLL, puisqu'il s'agit plutôt de fonctionalités d'affichages. (il me semble)
Mais bon faisons comme si s'était une fonctionalié métier pour expliquer.
Le retour sera une liste de DTO.
Maintenant dans ta BLL, tu vas manipuler une liste DTO
2 solutions
Tu passes l'ancienne liste et tu en récupères une nouvelle (mais après tu ne pourras plus faire de manip vis à vis des clients (choix de ceux qui commence par "R") puisque tu auras restreint ta liste.) Cela peut suffire fonctionnellement.
tu as intérêt à faire un objet POCO (une propriété liste DTO + les méthodes qui manipule La liste DTO)
A la demande "recherche client de Paris" tu charges les client de Paris (en passant par la DAL qui te renvoi une liste DTO) dans la propriété liste DTO de ton POCO, et tu renvois la liste DTO à l'UI.
A la demande "extraire les clients dont le nom commence par la lettre "M"" tu utilises une méthode de ton objet POCO qui va extraire de la propriété liste DTO une nouvelle liste DTO qui sera renvoyé vers l'UI.
(ainsi si l'utilisateur change et recherche des noms qui commence par "R" tu repart de la propriété liste DTO complète des clients de Paris).
Après effectivement si la demande suivante est "Les clients commençant par "MA"" tu reparcours la liste compléte. (à voir si tu veux pousser la fonctionalité plus loin en gardant une liste intermédiaire, mais cela risque de devenir compliqué) Sachant que le parcour d'une liste (même de 500 ou 1000 éléments) en mémoire pour filtrer sera imperceptible pour l'utilisateur final, il me semble qu'il faut rester simple (c'est juste pour pousser le raisonnement jusqu'au bout)
Ainsi entre tes diverses couches circule un objet (liste) DTO léger.
Ceci te permet de développer tes couches de façons trés indépendante les unes des autres.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Je m'en doutais, mais je préférais rectifier
Même dans le tuto (Quelle est la différence entre un DTO et un POCO ? ) cité par h2s84 il utilise BAL
lorsque vous souhaitez déplacer les données de votre DAL (NDT : couche d'accès aux données) à votre BAL ou entre les je-ne-sais-quelles couches de votre architecture n-tiers.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Ok donc dans les objets de la couche BLL on une propriété DTO dans laquelle je fourre l'objet du même nom.
Ca parait bizarre à manipuler mais je vais tester pour voir ce que ça donne.
Kropernic
C'est effectivement le but des DTO (Data Transfert Object). Les DTO c'est pour faire transiter des données être un pont entre deux parties et doit contenir des informations minimalistes dont on a besoin quand on travaille par exemple avec des services telles que WCF. Bref un DTO ne doit pas contenir la complexité de ton modèle ou domaine.
Traductions d'articles :
La mémoire en .NET - Qu'est-ce qui va où ?
Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager