Académique Documents
Professionnel Documents
Culture Documents
NET C# Partie 3
SOMMAIRE
1 Application multicouches
1.1 Le problème
Une couche graphique (CG) qui servira à afficher les données provenant de la base de
données et servira aussi à envoyer des données vers la base. Cette couche communiquera avec
la base de données par l’intermédiaire d’une couche qu’on appellera couche métier.
La couche métier (CM) est la couche qui gère toutes les données issues de la base de données
comme de l’interface graphique. Elle sert de couche intermédiaire entre l’interface utilisateur
et la couche d’accès aux données.
La couche d’accès aux données (CAD) dispose de tous les mécanismes pour récupérer les
informations à partir de la base données et d’en envoyer à la base.
Enfin la couche des objets métier (COM) qui comprendra des classes correspondant aux
tables disponible dans la base de données. Cette couche sera accessible à toutes les 3 autres
couches. On pourra mettre dans cette couche la classe de connexion à la base de données.
CM COM
CAD
2 Mise en œuvre
On créera une solution qui contiendra plusieurs projets. Parmi ces projets, un
projet celui de l’interface graphique servira de point de démarrage de
l’application. A part le projet de démarrage, tous les autres projets seront des
projets de type Bibliothèque de classes. Un projet de type Bibliothèque de
classes définit un espace de nom. Les classes d’un même projet peuvent être soit
dans un seul fichier ou étendues sur plusieurs fichiers. Pour ajouter une nouvelle
classe à un projet soit dans l’espace de nom correspondant au projet on saisit la
classe par : public classe <Nom_classe>{ … }
Soit étant sur le projet on fait Menu Projet/Ajouter une classe ; ce qui engendre
un nouveau fichier de classe
Le référencement à un projet (espace de nom) s’effectue en ajoutant dans
l’entête du fichier la mention using <espace_de_nom> et en faisant Menu
Projet/Ajouter une référence on choisit le projet concerné.
Elle contiendra des classes pour chaque élément géré au niveau de la base de
données. Elle contiendra également une classe pour la connexion à la base de
données. Cette classe de connexion doit implémenter une seule instance, elle
sera définie de ce fait à l’aide du design pattern Singleton.
On trouvera ci-après quelques éléments de cette couche :
if (laConnexion.State ==
System.Data.ConnectionState.Closed)
{
laConnexion.ConnectionString =
chaineconnexion;
laConnexion.Open();
}
return laConnexion;
}
public void FermerConnexion()
{
if (laConnexion != null)
if (laConnexion.State !=
System.Data.ConnectionState.Closed)
laConnexion.Close();
}
public OleDbConnection cnx
{
get { return this.OuvrirConnexion(); }
}
}
Le design pattern Singleton est une technique qui permet d’avoir une unique
instance de la classe. Si la classe est instanciée plusieurs fois les différentes
instances sont identiques. Comme la classe Connexion est utilisée à chaque fois
que l’on voudrait accéder à la base elle sera alors instanciée plusieurs fois. Or il
ne faudrait pas que les connexions diffèrent les unes des autres.
Le code pour la classe Classe encapsulant les informations d’une ligne de la
table Classe est :
Remarquons que dans les deux classes, nous avons utilisé des propriétés pour
accéder à des champs non publics à l’aide de get et set. En particulier le
Singleton Connexion définit 2 propriétés une de type String pour la chaine de
connexion et l’autre de type OleDbConnection pour la connexion elle même
Cette couche définit pour chaque élément de la base de données une classe
permettant de gérer les données de cet élément. A savoir récupérer les données
d’une table, en insérer, modifier ou supprimer. Par exemple pour la table Classe
de la base de données, on définit la classe ClasseDAO dont le code se présente
comme suit :
String larequete;
Connexion lacon = Connexion.Instance();
OleDbConnection cnx = lacon.cnx;
Classe uneclasse = new Classe();
int num=0;
while(num<lesclasses.Count)
{
uneclasse=lesclasses[num];
if (uneclasse.lecode != "")
larequete = "update classe set code_cl='" +
uneclasse.Code_cl + "', libelle='" +
uneclasse.Libelle + "', effectif=" +
uneclasse.Effectif + " where code_cl='" +
uneclasse.lecode + "'";
else
{
larequete = " insert into classe values('" +
uneclasse.Code_cl +
"','" + uneclasse.Libelle + "'," +
uneclasse.Effectif + ")";
uneclasse.lecode = uneclasse.Code_cl;
}
OleDbCommand laCommande = new
OleDbCommand(larequete,lacon.cnx);
laCommande.ExecuteNonQuery();
}
leDataReader["Code_cl"].ToString();
laclasse.Code_cl =
leDataReader["Code_cl"] == DBNull.Value ? default(String) :
leDataReader["Code_cl"].ToString();
laclasse.Libelle =
leDataReader["Libelle"] == DBNull.Value ? default(String) :
leDataReader["Libelle"].ToString();
laclasse.Effectif =
leDataReader["Effectif"] == DBNull.Value ? default(int) :
int.Parse(leDataReader["Effectif"].ToString());
lesclasses.Add(laclasse);
}
leDataReader.Close();
return lesclasses;
}
}
Les méthodes de cette classe ont l’attribut static qui signifie qu’elles sont
identiques pour toutes les instances. La méthode GetClassesDeBD récupère
toutes les lignes de la table Classe et les mettre dans un objet liste de Classe. Les
méthodes SetUneClasseToDB, UpUneClasseToDB et DelUneClasseToDB
respectivement insèrent, modifient et suppriment une ligne dans la base de
données. La méthode SetClassesToDB met à jour toutes les données d’un objet
liste de Classe dans la base de données.
Cette couche renferme toute la logique métier, elle définit une classe pour
chaque élément à gérer dans la base. Ces classes définissent des méthodes pour
échanger des informations avec la couche d’accès aux données. Ci-après le code
pour le gestionnaire de la classe Classe.
}
public static List<Classe> ModifierClasse(Classe
uneclasse, List<Classe> lesclasses, int num)
{
lesclasses[num]=uneclasse;
ClasseDAO.UpUneClasseToDB(uneclasse);
return lesclasses;
}
public static List<Classe> SupprimerClasse(Classe
uneclasse, List<Classe> lesclasses, int num)
{
lesclasses.RemoveAt(num);
ClasseDAO.DelUneClasseToDB(uneclasse);
return lesclasses;
}
}
{
chaine = "Provider = SQLOLEDB; Data Source =" +
textBox3.Text + "; User Id=" + textBox1.Text +
"; password=" + textBox2.Text + "; Initial
Catalog=" + textBox4.Text;
try
{
//définition de la chaine de connexion
lacon.chaineconnexion = chaine;
//ouverture de la connexion
cnx =lacon.OuvrirConnexion(); //l'unique
instance est ainsi définie
MessageBox.Show("connexion réussie");
this.Close();
}
catch (Exception ex) { MessageBox.Show("connexion
non effectuée: " + ex.Message); }
}
if (num > 0)
{
num -= 1;
if (num >= 0)
{
laclasse = lesclasses[num];
afficherClasse(laclasse);
}
}
2.5 Avantages
En effet, la manière dont les données sont gérées ne dépend pas du support de
stockage du fait qu’on fait appel à une couche intermédiaire. De même changer
de support de stockage n’entraine que la modification de la couche d’accès aux
données dont n’influence pas la gestion des données
En fait dans la couche présentation, on fait appel aux méthodes des classes de la
couche métier ce qui facilite l’écriture du code.