Questions.doc

Transcription

Questions.doc
Spécialiste Visual Basic
Formation et développement
[email protected]
Réponses à vos questions
Plusieurs des questions que je reçois par courrier électronique de mes étudiants après la
formation peuvent en intéresser d’autres. J’ai donc amassé une petite collection de ces questions
et de mes réponses, en espérant qu’elles pourront vous être utiles.
Veuillez excuser les fautes d’orthographes et la syntaxe, je vous présente les questions et les
réponses telles quelles, n’ayant pas le temps de faire les corrections.
De nouvelles questions s’ajoutent de temps à autre. Vous pouvez consulter la copie la plus
récente en tout temps en format pdf, sur notre site Web, à
http://www3.sympatico.ca/jbfi/questions.pdf
ADO.NET
Passer des guillemets et apostrophes dans un objet Command ....................................................5
Récupérer la valeur par défaut d’un champ dans la base de données .........................................23
Classes
Références circulaires ...................................................................................................................24
Collections
Utiliser une clé plutôt que l’indice ..................................................................................................14
ComboBox
DoubleClick ne fonctionne pas ........................................................................................................4
Emplir un ComboBox avec un DataReader ..................................................................................21
Contrôles
Référencer un contrôle d’un formulaire à l’autre ..............................................................................6
DataReader
Emplir un ComboBox avec un DataReader ..................................................................................21
Événements
DoubleClick – ComboBox ................................................................................................................4
1
Formulaires
Formulaires MDI .............................................................................................................................19
Référencer un contrôle d’un formulaire à l’autre ..............................................................................6
MDAC
Problèmes avec les différentes versions et mises à jour ..............................................................13
SQL Server et MDAC ....................................................................................................................12
MDI
Formulaires MDI .............................................................................................................................19
SQL Server
Comment se préparer à passer à SQL Server à partir d’Access ....................................................3
Installation minimum sur le client ...................................................................................................12
SQL Server et MDAC ....................................................................................................................12
VB.NET vs VB6
Conversion de VB6 à VB.NET........................................................................................................16
Les applications VB.NET demandent plus de mémoire ................................................................16
VB vs C#
VB ou C#? Lequel est le meilleur? ..................................................................................................7
2
Quelles sont, en gros, les choses importantes à considérer si on monte une application
avec une BD Access 2000 et qu'ensuite on veuille éventuellement la mettre sur SQL
Serveur ? (d'ici un ou 2 ans... )
Passer les tables de Access à SQL Server ne cause généralement pas de problèmes. Ce sont
les requêtes et le code qui ne passent pas bien.
Pour les requêtes, il y a une couple de choses à éviter :
- Référencer des contrôles dans les formulaires. C'est généralement fait dans les critères, pour
filter le résultat sur une sélection ou une valeur saisie par l'utilisateur dans un formulaire. SQL
Server ne voyant pas les formulaires, il ne peut les référencer. Il faut faire des requêtes dont les
critères sont des paramètres, et passer ces paramètres dans du code.
- Dans les requêtes avec paramètres, il est important de ne pas se contenter de spécifier les
paramètres à passer en les mettant simplement entre crochets [paramètre], ce qui est suffisant
en Access. Il faut en plus spécifier les paramètres dans les propriétés de la requête.
- Éviter de référencer des procédures, particulièrement des procédures qu'on a écrites soi-même.
SQL Server est capable de reconnaître certaines procédures qui sont standard en SQL, mais pas
celles qui sont spécifiques à Access (par exemple le DLookup) ou qu'on a écrites nous-mêmes.
Si le stagiaire ne connaît pas assez bien SQL Server pour savoir quelles sont les procédures
reconnues par Transact-SQL, il est mieux de ne pas du tout utiliser des procédures dans les
champs calculés ou dans les critères.
Pour le code :
- Si on ajoute du code dans les formulaire et les rapports, ou si on crée des modules, il faut
utiliser la librairie ADO au lieu de DAO. Le code ADO fonctionnera à peu près tel quel sur SQL
Server, mais le code DAO est spécifique à Access.
Tous les trucs énumérés sont des chose qu'on fait couramment en Access, mais qui ne passent
pas dans SQL Server. Ce sont celles qui m'ont personnellement causé des problèmes. Il y a
peut-être aussi de mauvaises techniques (Access étant conçu au départ pour monsieur-tout-lemonde, il est assez permissif) à éviter, mais comme toutes les expériences de conversion que j'ai
eues étaient sur des bases de données que j'avais moi-même conçues, je ne pourrais les
identifier (naturellement, je n'utilise jamais de mauvaises techniques :-)).
Ne pas oublier qu'Access 2000 vient avec un truc qui s'appelle le MSDE qui est une version
réduite de SQL Server, mais qui est limité, dans la pratique, à 5 utilisateurs simultanés (en
théorie, c'est une vingtaine, mais en pratique, ça commence à ralentir considérablement après 5).
Si ça vous convient, ça fait des bases de données qui vont passer directement à SQL Server
quand vous serez prêt. Ça implique cependant que le stagiaire est déjà à l'aise avec la
conception des tables, schémas, vues et procédures de SQL Server.
3
L’événement DoubleClick ne semble pas fonctionner dans les ComboBox.
Effectivement, ça a été confirmé par Microsoft :
It is because the ComboBox control doesn't support DoubleClick event. The
ComboBox control has a textbox inside it, which "eat" the DoubleClick event
to perform the default predefined behavior - selecting word. Though the
event can be seen and handled in the IDE, it will not fire at runtime.
La solution est de simuler le DoubleClick en utilisant un Timer :
Timer1.Interval = SystemInformation.DoubleClickTime 'Dans l’événement Load
'du formulaire
Private Sub Timer1 (ByVal sender As Object, ByVal e As System.EventArgs)
Handles Timer1.Tick
tmrTimer.Enabled = False
'Mettre ici le code que vous auriez mis sur le Click, au besoin
'Ça va être exécuté avec un petit délai, mais ce n’est pas grave
' dans la plupart des situations
End Sub
'Modification de l’événement Click, qui agit à la place du DoubleClick
Private Sub Combo1_Click (ByVal sender As Object, ByVal e As
System.EventArgs) Handles Combo1.Click
If Timer1.Enabled Then
'Mettre ici le code que vous auriez mis dans le DoubleClick
Else
Timer1.Start()
End If
End Sub
4
On fait des "SqlCommand" dans une application et on a eu des erreurs à cause que les
gens entraient des caractères spéciaux dans une "String" qu'on passait en paramètre
(exemple: ' ou " ). Est-ce qu'il y a un moyen facile de valider une "String" pour capter les
caractères spéciaux et les encoder/décoder au besoin ou bien, je dois me construire un
objet qui ferait ce travail ?
Le problème des apostrophes et guillemets est assez classique.
En VB, un double guillemet ("") à l'intérieur d'une String est vu comme un simple guillemet :
"WHERE Province = ""QC"""
sera vu comme
WHERE Province="QC"
dans la base de données.
La plupart des bases de données (SQL Server et Access et quelques autres) acceptent aussi
bien un guillemet qu'un apostrophe comme délimiteur de String dans une commande SQL, de
sorte que si on envoie
""Prud'homme""
qui donnera
"Prud'homme"
au lieu de
'Prud'homme'
Ça règle le problème.
La méthode Replace des Strings peut être utilisée pour faire les changements appropriés avant
d'appeler la commande.
Microsoft a un article sur ça, spécifique à ADO.NET à
http://support.microsoft.com/default.aspx?scid=kb;en-us;311023.
5
En VB 6.0, j'ai un formulaire frmMain qui ouvre un formulaire frmChild.
Dans frmChild, je suis capable d'aller lire la valeur d'une propriété d'un contrôle de
frmMain en faisant par exemple xyz = frmMain.txtID.text
En VB.NET, ça ne fonctionne plus. Comment faire ? Est-ce que je suis obligé d'initialiser
une variable global pour échanger des données entre deux formulaires ou y a t'il une
syntaxe particulière pour faire la même
chose qu'avant ?
VB.NET est plus pointu. Il ne crée par automatiquement une propriété permettant d'accéder à
chacun des contrôles , parce que ça ouvre la porte à un certain nombre de bogues,
particulièrement du fait que c'est en lecture-écriture. Un formulaire peut donc en faire "casser" un
autre en VB6.
C'est donc à toi de créer dans frmMain une propriété pour chacune des valeurs que tu veux
manipuler. Ça permet entre autres de déterminer le niveau d'accès pour chacune de ces valeurs.
Dans le cas que tu me soumets, ça ressemblerait à ceci :
Public ReadOnly Property Toto() As String
Get
Return txtID.Text
End Get
End Property
Tu pourrais alors faire ceci pour récupérer la valeur :
xyz = frmMain.Toto
6
J’hésite entre VB et C#. Lequel des deux langages est le meilleur. Il semble avoir sur le
marché présentement une demande pour le C#.
Si je pouvais seulement avoir 10 cents à chaque fois qu’on m’a posé cette question, je pourrais
prendre ma retraite toute de suite.
Il n’y a pas d’avantage à utiliser un plutôt que l’autre.
Le fait que les classes internes de .NET aient été en majorité écrites en C# laisse à penser que le
C# est meilleur. C’est faux. Microsoft à privilégié C# pour deux raisons.
La première est que le type de programmeur qui travaille sur des compilateurs ou sur des
environnements aussi complexe que Visual Studio, incluant un système de 6500 classes où tout
le monde hérite de tout le monde, a un background C++et va donc travailler plus facilement avec
un syntaxe s’apparentant au C.
La deuxième, c’est que C# étant nouveau, ils voulaient le raffiner et le déboguer. Comme il n’était
pas prêt, ils ne pouvaient pas le tester sur de nouvelles applications. En développant le C# en
parallèle avec l’outil dans lequel il est utilisé, ils pouvaient en même temps tester les concepts et
s’assurer que le langage serait adéquat au moment de sa sortie. La syntaxe de VB étant déjà
relativement développée, il y avait donc moins à faire.
Ça a déjà été dit chez Microsoft : ça aurait aussi bien pu avoir été fait en VB.
C’est penser en « mode Windows » et ne pas connaître ou comprendre .NET que de croire que
parce que les dll sont en C#, C# en fera un meilleur usage.
C’est uniquement une question de style et de goût. Mais pour répondre aux différentes
interrogations, voici une petite discussion sur 3 aspects du sujet : une comparaison des deux
langages, la perception que peut donner une lecture rapide du marché, et le futur des deux
langages.
Différences entre les langages
Il n'y a fondamentalement pas de différence entre travailler en C# ou en Visual Basic dans .NET.
Que vous travailliez dans un langage ou l'autre (ou même en COBOL, Fortran et Pascal, qui sont
disponibles de compagnies indépendantes de Microsoft), le résultat d'une compilation .NET
devrait en théorie donner le même résultat.
Vous utilisez le même outils pour créer les formulaires, vous connecter à une base de données
ou générer une application d'installation, peut importe le langage.
Une variable Integer VB ou une variable int C#, ça finit compilé en Int32 .NET. C'est une classe
qui fait partie de l'environnement .NET, et bien que le terme pour l'utiliser en VB soit différent de
celui de C#, le résultat est exactement le même. C'est vrai pour les String, les dates, ou n'importe
laquelle des 6500 (et plus dans la version 2003) classes fournies avec .NET. Vous pouvez
généralement interchanger le code entre les langages avec presque pas de modifications. Voici
un exemple, dans les deux langages, d'une routine qui exécute une procédure stockée dans une
base de données. C’est le code en rouge qui fait le travail, le reste, c’est uniquement des
déclarations de variables et une trappe d’erreur :
7
Visual Basic :
Dim con As New OleDbConnection _
("file name=..\..\Frizotte.udl")
Dim com As OleDbCommand
Dim dta As New OleDbDataAdapter()
Dim dts As New DataSet()
Dim par As New OleDbParameter()
par.ParameterName = "@Pays"
par.DbType = DbType.String
par.Value = cboPays.Text
com = New OleDbCommand()
com.Connection = con
com.CommandText = "spClientsPays"
com.CommandType = CommandType.StoredProcedure
com.Parameters.Add(par)
dta.SelectCommand = com
Try
dta.Fill(dts)
Catch erreur As OleDbException
Debug.WriteLine(erreur)
End Try
dtgClients.DataSource = dts.Tables(0)
C#:
OleDbConnection con=new OleDbConnection
("file name=..\\..\\Frizotte.udl");
OleDbCommand com;
OleDbDataAdapter dta=new OleDbDataAdapter();
DataSet dts=new DataSet();
OleDbParameter par=new OleDbParameter();
par.ParameterName = "@Pays";
par.DbType = DbType.String;
par.Value = cboPays.Text;
com=new OleDbCommand();
com.Connection = con;
com.CommandText = "spClientsPays";
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(par);
dta.SelectCommand = com;
try
{
dta.Fill(dts);
}
catch (OleDbException erreur)
{
Debug.WriteLine(erreur);
}
dtgClients.DataSource = dts.Tables[0];
}
8
Si vous comparez les deux, vous constaterez qu'à part les déclarations de variables, l'utilisation
des ; et des accolades {}, et des indices d'arrays définis par () en VB et [] en C#, le code est
exactement le même. Il devrait aussi donner le même résultat à la compilation.
Il n'y a aucun avantage particulier à utiliser un langage plutôt que l'autre. Les compilateurs sont
différents, de sorte qu'il est possible que certaines routines soient plus efficaces en VB et d'autres
plus efficaces en C#, mais en théorie, ils devraient générer le même code.
Certaines options de l'environnement de développement ne fonctionnent que pour C#. Ainsi, en
VB, vous devez recompiler complètement l'application dès que vous faites un petit changement.
C# offre une option permettant de ne recompiler que les lignes modifiées depuis la dernière
compilation. Ça accélère le développement de grosses applications en C#.
Par contre, les événements sont beaucoup plus faciles à créer dans VB, qui génère
automatiquement les procédures événementielles, alors qu'en C#, il faut les écrire à la main. Ça
accélère le développement en VB.
Vous utilisez donc les mêmes outils et les même concepts pour développer en VB et C#. Le code
compilé devrait être à peu près identique, donc pas de différence de performance. Vous pourriez
même avoir une application « bilingue », ayant un .EXE VB et un .DLL C# ou l'inverse. Le choix
du langage n'est pas important.
Ce qui fait la différence, c'est uniquement une question de goût personnel, habituellement basé
sur l'expérience du programmeur. Les vieux programmeurs VB préfèrent Visual Basic .NET (ils
sont habitués aux Dim et peuvent toujours utiliser leurs vieilles fonctions VB); les programmeurs
qui ont une expérience plus forte en C ou en Java vont habituellement préférer le C#, qui est un
mélange des deux syntaxes.
Analyse du marché
Si l’on se fie aux annonces de journaux, il semble y avoir une demande plus grande pour le C#
que pour le Visual Basic. Il est difficile de savoir si c’est vraiment le cas, mais il nous semble que
non. On parle plus du C#, mais il faut comprendre pourquoi.
Dans un premier temps, le C# attire surtout les entreprises qui programment déjà en C ou en
Java et qui veulent passer à .NET. Ces entreprises ont déjà compris l’intérêt de travailler dans un
environnement objet, et voient l’intérêt de .NET.
Dans les boîtes où l’on faisait du VB6, on ne sait pas vraiment ce qu’est un objet (les petites
classes de VB6 n’étaient pas de vrais objets), et l’on ne voit pas vraiment pourquoi on investirait
dans quelque chose de nouveau alors que ce qu’on a fonctionne. « Pourquoi se compliquer la vie
avec le polymorphisme et l’héritage, on n’en a jamais senti le besoin »… donc on n’en saisi pas
l’utilité. On ne comprend pas l’intérêt de passer à .NET. Je sens très bien ce phénomène sur le
terrain : il y a actuellement (septembre 2003), deux à trois fois plus de demande pour des cours
de VB6 que pour des cours de VB.NET.
Les entreprises C et Java font le saut, mais pas les entreprises VB. Comme le C# attire
d’avantage les programmeurs C++ et Java, la demande aurait à priori tendance à être un peu
plus forte pour le C# à ce stade-ci, sans compter que certains programmeurs VB décident, tant
qu’à apprendre quelque chose de nouveau, de passer à C#, alors que l’inverse n’existe à-peuprès pas.
Pourtant, si l’on se fie uniquement aux inscriptions à nos cours, on constate à-peu-près 2
inscriptions en VB.NET pour 1 en C#.
9
Les journaux donnent l’impression du contraire?
C# est nouveau. Les programmeurs C# sont donc plus rares que les programmeurs VB, et donc,
plus en demande dans les petites annonces. Il est facile pour une entreprise de trouver à l’interne
quelqu’un qui connaît VB et qui n’a qu’à se mettre à jour pour passer à VB.NET. Ce n’est pas le
cas pour le C#. Il y a donc plus d’offres d’emplois en C#, parce qu’on doit sortir à l’extérieur.
Si l’on se promène depuis quelques années dans l’univers .NET, autant chez Microsoft que dans
les sites Web et les revues spécialisées, on constate qu’au lancement de Visual Studio .NET au
début de 2002, il y avait plus d’articles C# que d’articles VB, dans une proportion d’environ 2 pour
1. Cette tendance semble s’inverser. Dans le numéro de juin du Visual Studio Magazine, il y a 1
seul article C#, 3 articles VB et 1 article mixte. Il y a exactement les mêmes proportions en août.
En Juillet, c’était égal à 2 / 2 / 2.
Ma perception est peut-être biaisée parce que j’ai plus tendance à rencontrer des programmeurs
VB, mais il me semble qu’à l’exception des offres d’emplois, il y se fait plus de VB que de C#.
Le futur des deux langages
Lequel est le plus intéressant à long terme? Lequel va être privilégié par Microsoft?
Microsoft a investi autant dans l’un que dans l’autre, et promet autant de travail dans l’un que
dans l’autre. De leur part, on dit donc que les deux choix sont aussi valables.
Par contre, les observateurs du milieu ont tendance à croire que les langages vont
éventuellement se distancier. Il y a eu plusieurs articles et discussions à ce sujet ces derniers
mois.
À quoi sert un langage de programmation sans système d’opération pour faire fonctionner
l’application? Microsoft a dans un premier temps concentré ses énergies à concevoir un
environnement solide (le framework), pas à raffiner des langages.
Il y a cependant beaucoup de « grogne » du côté de Visual Basic, et un grand nombre de
programmeurs VB6 ne font pas le saut parce que : « ce n’est plus aussi simple qu’avant »1. Les
programmeurs C trouvent qu’ils perdent du contrôle en C#, et en même temps que le C en
« managed code » est inutile.
Il n’y a pas de langage RAD (Rapid Application Development) dans le monde .NET. Ça fait
penser à Windows à ses débuts. Il a fallu attendre la venue de VB pour pouvoir penser faire des
applications en quelques jours au lieu de quelques mois. Bien des gens pensent que ça devrait
encore être le rôle de VB, et croient que, bien que ce ne soit pas officiel, ce soit aussi l’idée de
Microsoft. On le sent même déjà un peu, par exemple, pour la déclaration des procédures
événementielles déjà mentionnée en comparant les deux langages. VB fait plus de choses
automatiquement.
On a donc tendance à croire qu’avec le temps, Microsoft sera porté à ajouter à C# des
fonctionnalités le rapprochant du C parce que les programmeurs C# demanderont des
fonctionnalités auxquelles ils étaient habitués en C, et porté à donner aux programmeurs VB le
1
Il n’y a pas à se le cacher, c’est plus complexe de programmer en VB.NET qu’en VB6. Un grand
nombre d’individus se sont improvisés programmeur « professionnel » avec juste un peu
d’expérience dans les versions antérieures de VB. Ce ne sera pas le cas avec VB.NET, ne seraitce que parce qu’ils n’auront pas la patience d’apprendre à s’en servir correctement. X=Y passe
toujours la compilation en VB6, pas toujours en VB.NET.
10
choix d’utiliser plus d’outils permettant de simplifier et d’accélérer leur travail, comme ils étaient
habitués à le faire « dans le temps ».
En conclusion
La transition de VB6 à VB.NET est plus aisée que de VB6 à C#, alors d’après moi, si VB6 faisait
l’affaire pour vous, VB.NET la fera, seulement mieux et avec un outil plus solide, qui vous oblige
à vous discipliner et à concevoir des applications plus faciles à maintenir, quoique un peu plus
complexes à développer.
Si VB n’était pas suffisant, vous faisiez probablement du C et aurez probablement encore à en
faire. C# est donc alors plus adéquat. Même chose si vous êtes plus à l’aise avec la syntaxe de C
ou Java, parce que la transition sera plus facile.
11
Minimalement qu'est-ce qu'il me faut installer sur un poste de travail pour utiliser une
application ADO.NET qui accède à SQL Server?
Ton application et le framework, naturellement, mais aussi :
- Les dll d'accès aux bases de données, un truc que Microsoft appelle MDAC (Microsoft Data
ACcess) et que tes utilisateurs ont peut-être déjà, même s'ils n'utilisaient que des bases de
données Access dans le passé, mais qui vaudrait peut-être la peine d'être mis à jour. Tu peux
trouver la version la plus récente à
http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28001860.
- Le client SQL. Ça peut s'installes CD de SQL Server, mais il y a plusieurs approche, incluant le
MSDE dont on parle dans le manuel de cours. Je te suggère de consulter la documentation SQL
Server sur l'installation du client. Un ancien étudiant m’a affirmé que l’installation de MDAC était
suffisante, mais ce serait à vérifier. En ce qui me concerne, j’ai toujours installé le client SQL.
Lorsqu'on installe un client SQL Server, automatiquement MDAC s'installe, dois-je
supposer que c'est la bonne version de MDAC? J'imagine que oui.
Tu n'as pas nécessairement la bonne version du MDAC, ça dépend de ta version de SQL Server.
Ils ne sont pas faciles à suivre. D'après les spécifications, ça prend minimum MDAC 2.6 pour
ADO.NET et SQL Server 2000, mais le 2.7 avec le Service Pack 1 est suggéré pour profiter de
toutes les possibilités.
Si je ne me trompe pas, l’installation du client SQL Server va te donner le MDAC 2.6, il y aurait
donc avantage à installer le MDAC 2.7 séparément
Si tu installes le client SQL Server 7, je crois que c’est le MDAC 2.5 qui s’installe, et ce n’est pas
suffisant pour ADO.NET.
On se demandait aussi si ADO.NET passe réellement par MDAC lorsqu'on utilise des
SqlConnection pour SQL Server? En d'autres termes, MDAC semble être plus au niveau de
OLEDB et ODBC.
Tu as raison, ça joue surtout au niveau d'OLEDB et ODBC. ADO.NET a besoin de certaines
composantes de MDAC. On ne passe pas par ODBC et OLEDB, mais il utilise certains éléments
de MDAC. Je pense par exemple à la validation et à la création des connexions. Les
ConnectionStrings ont exactement les mêmes syntaxes en ADO.NET qu'en ADO. Je ne serais
donc pas surpris que ce soit une des composantes du MDAC qui établisse la connexion.
12
Est-ce que les différentes mise à jour de MDAC ont un impact sur ADO.NET lorsque utilisé
avec SQL Server? Par exemple, est-ce qu'on pourrait avoir un type d'erreur chez un client
qui exécute notre application avec une version de MDAC différente de celle qu'on
s'attend?
Oui, il est possible que tu aies des erreurs si ton client n'a pas la même version du
MDAC.Normalement, la version du MDAC nécessaire fait partie des spécifications de
l'application, et l’on essaie de motiver nos clients à faire des mises à jour régulières. À ce qu’on
m’a dit, le MDAC se met à jour automatiquement au travers de Windows Update à partir de
Windows XP.
On lit des article sur MDAC qui nous font un peu peur en terme de déploiement: Terminal
Server, SQL Server 7.0 en cluster non supporté par MDAC, les version MDAC venant avec
le OS sur XP et pas avec les autres os... Beaucoup de problème en vue...
MDAC, ce n'est pas une application en soi, c'est une série de dll, une centralisation de tous les dll
d'accès aux données. Plutôt que de créer des problèmes, il corrige un problème qui était courant
à l'époque.
Dans le temps, il fallait mettre à jour ODBC, puis OLEDB, puis Access, puis SQL, etc. Ce sont
tous des outils qui travaillent ensemble, mais qu'on mettait à jour séparément. On se retrouvait
donc souvent avec des incompatibilités entre les versions. Microsoft a décidé de simplifier notre
tâche en mettant tout dans MDAC. Ainsi, si une nouvelle version de SQL Server sort, il y a
habituellement une nouvelle version du MDAC qui s'occupe à ce que tout ce beau monde puisse
travailler avec la nouvelle version.
MDAC venant avec le OS sur XP, c'est la nouvelle tendance. C'est comme le framework qui vient
avec le OS sur Windows Server 2003. Ça aussi, ça correspond à un besoin qui s'est présenté
dans le passé. Par exemple, on devait toujours installer le runtime de VB avec nos applications.
C'était un peu absurde, parce que presque tous les ordinateurs se retrouvaient éventuellement
avec ce runtime, mais avec des versions différentes, dépendant des applications qui s'y étaient
installer. En distribuant le runtime avec le système d'opération, ça nous évite d'avoir à l'installer,
et ça devient le rôle de Windows Update de s'assurer que la dernière mise à jour est toujours
installée. Ça simplifie la vie de l'usager, et celle des concepteurs d'applications.
Si tu lis des articles sur n'importe quoi, en informatique, tu vas avoir peur. Les systèmes sont
rendus très complexes, y'en a pas deux qui a la même configuration d'appareils et de logiciels.
C'est certain qu'il va y avoir des problèmes de temps en temps. J'ai déjà vu une liste de bogues
VB6 qui faisait pas loin de 30 pages à raison d'une vingtaine de bogues par page. Ça fait peur.
Pourtant, des millions de programmeurs travaillaient allégrement et avec un certain "plaisir" en
VB6. Si on fouillait, on se rendait compte que la plupart de ces bogues étaient reliés à des
configurations très particulières (lire rares), et qu'il y avait presque toujours une façon de les
contourner.
13
En VB6, nous pouvions associer une clé (Key) à la function Add d'une collection, ce qui, je
ne croit pas, être le cas aux 6 types de Collections en .NET. Est-ce qu'il y a une façon de
faire en .Net pour simuler cette clé.
Je sais qu'on peut utiliser l'objet Collection dans .Net mais je crois qu'il n'est pas natif,
est-ce exacte?
L'utilisation d'une clé facilite le travail mais diminue la performance. Chaque fois que tu
références un objet par sa clé, VB doit consulter une table virtuelle pour savoir quel indice (les
collections fonctionnent avant tout par indice, pas par clé) contient l'objet référencé par la clé. On
conseillait donc autant que possible de ne pas utiliser les clés, sauf dans les cas où la
performance n'était pas essentielle ou quand il y avait beaucoup de création/destruction d'objets
et que le travail nécessaire à "suivre" un objet par son indice devenait trop difficile.
En VB6, à moins de travailler à partir de rien pour créer nos propres classes collections, il n'y
avait qu'un seul mécanisme pour créer des collections, et Microsoft a donc décidé d'y ajouter le
truc de la clé qui est très commode dans certaines circonstances, comme tu le sais probablement
déjà.
En VB.NET, comme on a plusieurs classes collections, ils y sont allés avant tout pour la
performance. L'utilisation des clés n'est essentielle que dans certaines situations, alors, comme
tu l'as constaté, la plupart des collections n'offrent pas cette technique.
Avant d'utiliser une clé, pose-toi la question suivante : est-ce que je fais ça uniquement par
"paresse", parce que c'est plus facile, ou parce qu'il est très difficile de faire autrement? Si tu as
des grosses collections, la performance en prend un coup quand tu recherches un élément par
sa clé.
Si tu ne peux pas t'en passer (y'a des cas où essayer de suivre les objets pas leur indice est plus
pénalisant que d'utiliser la clé), tu as deux choix :
--------------------1. La bonne vieille collection de VB6, qui est toujours disponible, mais qui fait partie du
namespace Microsoft.VisualBasic. Ce n'est donc pas une collection de .NET. Je n'ai pas
vraiment fouillé, mais j'ai l'impression que le compilateur VB génère quelque chose qui utilise les
collections .NET en ajoutant du code pour gérer les clés.
Dim z As New Collection
ou, pour être plus précis
Dim z As New Microsoft.VisualBasic.Collection
t'offre les mêmes mécanismes qu'à l'époque, incluant une clé optionnelle. Le code écrit avec ce
type de collection n'est cependant pas portable dans les autres langages, ce qui peut être un
handicap dans certaines entreprises.
--------------------2. Si tu veux être .NET pur, avec du code portable, les classes SortedList et HashTable sont des
collections qui utilisent une clé. Je n'ai travaillé avec aucunes d'entre elles (mes collections sont
presque toutes créées en héritant de CollectionBase, comme on apprend à le faire dans le cours
objet, et dans ce cas, c'est toi qui crée la méthode Add, tu la fais comme tu veux), alors ce que je
te dis n'est pas par expérience, mais seulement une analyse personnelle de la documentation.
Donc, à prendre avec un grain de sel.
En théorie, elle sont plus performantes que celle de VB parce qu'elle sont optimisée pour
travailler avec une clé. En pratique, faudrait faire des tests. En théorie, la HashTable est plus
performante, mais la SortedList, comme son nom l'indique, est triée sur la clé. Encore là, faudrait
faire des tests, et ça peut dépendre du type d'utilisation qu'on en fait.
14
Leur handicap, c'est quelles fonctionnent uniquement avec une clé, il n'y a pas d'indice :
Dim z As New Collections.SortedList
ou
Dim z As New Collections.Hashtable
Pour un programmeur VB6, ça ne saute pas aux yeux. Les paramètres à ajouter au Add sont key
As Object, value As Object. La clé peut être n'importe quel objet, incluant une String, qui est un
objet comme tout le monde le sait. Son utilisation est donc semblable à celle de VB, sauf que les
paramètres ne sont pas dans le même ordre, la clé passant en premier :
z.Add ("Toto",<Objet à ajouter dans la collection>)
' Toto est la clé
x = z.Item("Toto")
Il n'y a, à ma connaissance, pas de collection .NET qui offre à la fois un indice et une clé. Seule
la Microsoft.VisualBasic.Collection VB permet les deux.
15
J'ai commencé à jouer avec vb.net et la première chose que j'ai fait c'est de traduire une
app vb6 à vb.net (je sais que ce n'est pas très conseillé) mais je fut très surpris de voir
"engraisser" mon application de tel manière. Mon application ne contient qu'un Timer, 2
Labels, ainsi qu'un contrôle text et un textarea, ce qu'elle fait et bien tu choisis une
application dans le textarea (path, hardcoder) et puis tu entres dans le contrôle text l'heure
à laquelle tu veux que la dites application (ou process) se termine et vb la ferme et se
ferme aussi.
La conversion s'est faite presque sans anicroche sauf quelques petits détails (entre autre
delegate pour des api de windows, qui m'ont un peu fait suer). Mais la surprise fut surtout
au niveau de l'utilisation mémoire des 2 applications. VB6 = 2 Mo +- , vb.net = 12 Mo +-,
pire encore lorsque je change mon textarea pour un FSO afin de rendre l'application plus
complète alors c'est presque 17 Mo que l'applciation utilise. Est-ce normal ou c'est le fait
de la convertir qui fait ça, sinon les app Vb.net sont très gourmandes en mémoire non?
Ton rapport de 6 à 1 m'a a première vue surpris, mais si on y pense bien, c'est probablement
normal. Je suis allé vérifier, et c'est à peu près ce que j'ai aussi pour la seule application que j'ai
personnellement converti. Je suis cependant surpris par le 5 Mo supplémentaire pour le FSO. J'ai
fait un test pour voir, et chez moi, utiliser le FSO avec un petit fichier d'une seule ligne n'ajoute
qu'un seul Mo. La différence vient peut-être du fait que tu as un gros fichier chargé dans l'espace
mémoire de l'application.
Mais sans considérer l'Interop FSO, qui n'est supposé être qu'une mesure temporaire, pourquoi
une si grande différence?
Si tu jettes un coup d'oeil aux modules qui roulent en même temps qu'une application .NET
(Debug -> Windows -> Modules à partir d'une application en mode Break), tu constateras que le
run-time de .NET (la première entrée : mscorlib) fait environ de 10 Mo, contre 1.3 Mo pour le runtime de VB6. .NET utilise par défaut des classes qui assurent la sécurité et qui valident
continuellement les opérations. Les variables de type primitif demandent beaucoup plus de
mémoire, venant avec une série de propriété et méthodes (les méthodes sont cependant
partagées entre toutes les variables de même type). Le rapport de grosseur entre les deux runtime est donc normal.
Pour une application Windows il faut rajouter environ 2 Mo pour System.Windows.Forms.dll, sans
compter System.Drawing.dll qui est requis par Forms. En VB6, tout ça était dans le run-time de
VB.
Si tu ajoutes par-dessus tout ça le fait que tu as une application convertie qui utilise mal les
ressources de .NET et qui a besoin de dll supplémentaires pour assurer la compatibilité et
fonctionner, ça commence à "faire du monde à la messe".
Il y a donc nécessairement une augmentation de l'utilisation des ressources.
Par contre, faut voir si les chiffres que tu as sont bien représentatifs de la réalité.
Je suppose que tu t'es fié au Gestionnaire de tâches (Task Manager) de Windows. C'est un outil
qui a toujours été assez approximatif, et c'est particulièrement le cas pour une application .NET. Il
faut donc interpréter l'information qu'il nous donne.
Dans un premier temps, il faut se souvenir qu'une application .NET roule dans l'environnement
mémoire de .NET, pas celui de Windows. Il y a donc une communication entre .NET et le Task
Manager pour simuler le fait qu'une application roule dans Windows, et ce n'est pas toujours très
précis. Ta question m'a amené à faire quelques petits tests qui m'ont prouvé qu'on ne pouvait
pas tellement se fier au Task Manager pour une application .NET. Tu devrais pouvoir reproduire
ça très facilement chez toi. Note que je suis sur Windows XP Pro, il est possible que le
comportement soit différent dans d'autres systèmes d'opération. J'assume que tu es à l'aise avec
le code à écrire. Si ce n'est pas le cas, fais-le moi savoir et je t'enverrai un exemple tout fait.
16
1. Crée un projet ne contenant qu'un formulaire vide et deux boutons. Compile et lance-le à partir
de bin. Note la mémoire utilisée.
2. Déclare une variable FSO au niveau de la classe qui définit ton formulaire, sans l'instancier
(pas de New). Si tu lances l'application à nouveau, tu constateras, sans surprise, que ça occupe
approximativement la même quantité de RAM. Un objet non instancié est simplement un
pointeur.
3. Sous le premier des deux boutons, crée une instance du FSO avec un New. Sous le deuxième
bouton, détruit l'instance en la mettant à Nothing.
4. Lance l'application avec le Task Manager en parallèle. Même utilisation de mémoire
qu'auparavant. En cliquant sur le premier bouton, ça monte d'environ 1 Mo, le FSO vient de partir
(interop + scrrun.dll + probablement une ou quelques autres librairies nécessaires pour les
interop, parce que interop + scrrun.dll ne font pas 1 Mo).
5. Clique sur le deuxième bouton. Il détruit l'objet. On devrait récupérer la mémoire, mais ça ne
se reflète pas dans le Task Manager.
L'objet n'est plus présent dans l'application, il est rendu dans le Garbage Collector. C'est vrai que
l'espace mémoire n'a pas été vraiment récupéré, mais on peut en réalité considérer que cette
mémoire est disponible.
On peut donc affirmer que l'affichage du Task Manager n'est pas représentatif de la vraie
utilisation de la mémoire par une application. Quand tu dis que ton application convertie occupe
12 Mo, il y a une partie de ça qui n'est plus vraiment là. En VB6, comme les objets ne passent
pas par le Garbage Collector, on ne sent pas ça.
Ensuite, le Task Manager ne tient pas compte du fait que plusieurs applications peuvent utiliser
simultanément le même dll. Part 2 copies de la même application, et tu constateras que le Task
Manager indique qu'elles utilisent à peu près la même quantité de mémoire, ce qui n'est pas tout
à fait vrai. Supposons que l'application demande elle-même 2 Mo de mémoire et utilise 10 Mo de
dll. Si tu en lances 2 copies, Task Manager indiquera 12 Mo pour chacune, laissant croire à un
total de 24 Mo. En réalité, le dll est partagé par les deux applications, de sorte que la mémoire
réellement utilisée est de 2 + 2 + 10 = 14 Mo.
Voyons ça sous un autre aspect.
Imagine que tu lances 3 applications Windows conventionnelles dans une session Windows qui
vient juste de démarrer : une en VB, une en C++ et une autre en Delphi. Chacune des
applications part un run-time différent. La somme de l'espace mémoire affiché dans le Task
Manager devrait ressembler à peu près à la réalité.
Maintenant, imagine que tu fais la même chose avec des versions .NET des 3 applications. La
somme de l'espace mémoire affiché dans le Task Manager sera beaucoup plus grosse, mais ne
sera pas significative. Les applications partagent le même run-time, mais Task Manager n'en
tient pas compte. Ça donne l'impression que .NET demande beaucoup plus de mémoire, alors
qu'en réalité, Task Manager a compté 3 fois un run-time qui n'est chargé qu'une seule fois en
mémoire.
En résumé : oui, ça demande plus de ressources (surtout tant qu'il y aura un "mix" d'application
.NET et Windows), mais pas autant qu'il n'y paraît. Mon expérience personnelle est que sur des
ordinateurs où la mémoire n'était pas un problème avant, les applications .NET roulent sans
problème. Mon vieux Compaq (Microprocesseur AMD Athlon 600 MHz et 196 Mo de mémoire
vive) était un dinosaure quand j'essayais d'y faire du développement .NET, mais j'y utilise
régulièrement une version avancée de PhotoCat (l'application d'exemple durant le cours) roulant
avec une base de données SQL Server locale (MSDE), en même temps que Word, Outlook et
Internet Explorer sont ouverts. C'est sûr que ça roule mieux sur un Pentium 4 à 2 GHz et avec
512 Mo de RAM, mais la performance sur le vieil ordinateur ne me fatigue pas du tout (et je suis
très facile à fatiguer sur cet aspect).
17
Par contre, dans un environnement où la mémoire était déjà limitée (j'utilise encore pour des
tests un vieux Pentium I 300 Mhz et 96 Mo de mémoire), ça n'est pas acceptable, quoique ça
fonctionne.
18
Je viens de commencer mon premier projet en vb.net. Nous avons besoin de réaliser un
projet qui possède plusieurs fenêtres ouvertes en même temps car plusieurs type
d’information doivent être afficher. J’ai tout de suite penser à une bonne vieille application
MDI. Par contre, nous voulons utiliser le « docking » pour attacher certaine fenêtres
enfants aux bords de la MDI (un peu comme visual studio le fait). Le hic s’est que dès
qu’une fenêtre enfant sort de la fenêtre parent, un scroll bar est automatiquement affiché.
Je pensais faire du code pour faire un resize de ma fenêtre enfant lorsque le pointeur de la
souris arrive au bord de la MDI, mais comme une portion de la fenêtre enfant sort de la
MDI avant le pointeur de souris, le scroll bar apparaît.
La question est la suivante : connaissez-vous un bon livre ou un site sur le design
d’application MDI ou je pourrais trouver des informations pertinentes?
Non, je ne connais aucun livre qui traite spécifiquement des applications MDI, et une recherche
rapide chez Camelot et Amazon ne sort rien. L'approche MDI est courante dans la "vraie vie",
mais la plupart des manuels n'y consacrent que quelques pages, et plusieurs n'en parlent même
pas.
Tout ce que je peux t'offrir, ce sont quelques réflexions de mon cru, en espérant que ça pourra te
servir.
Dans un premier temps, les formulaires ont une propriété AutoScroll qui détermine si des
scrollbars s'affichent quand un contrôle sort de la surface du formulaire. À bien des égards, un
enfant est vu comme un contrôle dans le parent. Peut-être que modifier cette propriété dans le
parent te permettrait d'empêcher l'affichage des barres de défilement avant que n'aies eu le
temps de redimensionner ton enfant.
Comme je l'ai peut-être mentionné dans le cours, la plupart de mes applications .NET sont en
MDI, et comme toi, j'ai eu quelques problèmes au début, même si ce ne sont pas les mêmes.
Mes applications n'ont généralement pas à afficher plusieurs fenêtre simultanées. J'utilise le MDI
pour plus facilement contrôler le départ et l'arrêt de l'application, ainsi que pour faciliter la gestion
des menus. L'idée est de donner aux utilisateurs l'idée qu'ils sont dans une fenêtre unique dont
l'affichage change selon l'opération à effectuer, sans qu'ils aient l'impression de changer de
fenêtre pour chaque formulaire. Si tu connais Microsoft Money, il utilise le même mécanisme :
une trentaine d'écrans différents, mais qui s'ajustent toujours à la grosseur du formulaire MDI.
Pour arriver à ça, il y a deux solutions.
La première, si elle est possible, est la plus facile au point de vue apparence : concevoir les
formulaires pour qu'ils aient tous la même dimension, soit l'espace disponible à l'intérieur du MDI.
Dans un tel cas, le MDI est normalement figé et ne peut être ni agrandi ni rapetissé
(FormBorderStyle = FixedDialog)
La deuxième est de concevoir tous les formulaires pour qu'ils s'ajustent automatiquement quand
ils sont redimensionnés (propriété Anchor de chacun des contrôles), et d'ouvrir chacun des
enfants en mode plein écran. De cette façon, peu importe la grosseur du parent, l'enfant s'affiche
correctement à l'intérieur du parent (on règle le MinimumSize du parent pour s'ajuster au plus
petit des formulaires enfant). Le problème de cette approche est qu'il est rare d'avoir une
application où tous les formulaires peuvent être agrandis et rapetissés à volonté. En travaillant
bien, on peut cependant y arriver. C'est le cas dans Microsoft Money, où peu importe la grosseur
de la fenêtre principale, tous les formulaires enfants, qui sont pourtant bien différents les uns des
autres, s'affichent toujours correctement (ou presque).
Il y a aussi l'approche hybride, qui consiste à ouvrir la plupart des formulaires comme des
enfants, mais certains d'entre eux comme des formulaires séparés, généralement avec un
ShowDialog (formulaire modal). Les fenêtres À propos de (About) et Options (configuration) des
mes applications entrent généralement dans ce cadre.
19
Si ça ne se prête pas à ton application, une autre solution, toujours si c'est possible, serait de
faire l'inverse de ce que tu tentes de faire. Plutôt que de redimensionner l'enfant, pourquoi ne pas
essayer de redimensionner le parent? Ça ne peut naturellement pas fonctionner si le parent est
"accoté" sur le bord de l'écran ou plein écran, mais dans un tel cas, il devrait y avoir moyen
d'empêcher l'enfant de sortir du parent. Tu pourrais réagir à l'événement Move de l'enfant pour
faire les ajustements nécessaires.
Un petit truc qui pourrait être utile ici, un formulaire possède une propriété ClientSize que bien
des programmeurs ne connaissent pas parce qu'il n'est disponible qu'en "run-time". Quand on
"joue" à l'intérieur d'un MDI, cette propriété est plus intéressante que Size, parce qu'elle donne la
surface d'affichage du formulaire, excluant la barre titre, la bordure et les menus. C'est en fait la
surface disponible pour les enfants. Je n'ai pas testé, mais je ne serais pas surpris que les
fenêtres "dockées" soient considérées comme faisant partie du parent, lors du calcul de la
surface restante.
20
J’essaie remplir un ComboBox manuellement à partir de DataReader, je parviens à mettre
des valeurs dedans, mais je veux aussi y mettre mes codes sans qu’ils soient visibles !!
Exemple :
110
Montréal
120
Québec
130
Ste-Julie
Mais je parviens juste à mettre des valeurs dans la liste, sans mettre aucun code.
Voilà ce que je fais :
Dim conn As New SqlClient.SqlConnection("…connection string")
Dim commande As New SqlClient.SqlCommand("SELECT …", conn)
Dim dtReader As SqlClient.SqlDataReader
conn.Open()
dtReader = commande.ExecuteReader
While dtReader.Read
'Il doit me manquer quelque chose ici
ComboBox1.Items.Add(dtReader(1))
End While
La solution la plus simple est de passer par un DataSet (ds) et d'assigner la table et les colonnes
à utiliser au ComboBox :
Combo1.DataSource = ds.Tables(0)
Combo1.DisplayMember = "nom du champ à afficher"
Combo1.ValueMember = "nom du champ caché"
Pour récupérer les valeurs sélectionnées par l'utilisateur, Combo1.SelectedValuedonne la valeur
cachée correspondant à la sélection de l'utilisateur.
C'est la solution la plus simple, mais ce n'est pas la plus efficace, parce qu'un DataSet demande
beaucoup de ressources qui ne sont généralement pas utilisées dans un ComboBox. C'est
pourquoi j'ai dit dans le cours qu'on utilise généralement un DataReader. La technique est plus
efficace, mais demande cependant plus de code.
En .NET, tout passe par des classes, et c'est le cas du ComboBox. Pour pouvoir y mettre plus
d'une "colonne", il faut que ce que les Items que tu y ajoutes soient un objet possédant plusieurs
propriétés. Il faut donc généralement créer une classe simple possédant une propriété pour
chaque colonne. Tu crées ensuite une collection qui accumule des objets provenant de cette
classe, puis tu associes la collection au ComboBox.
Dans l'application d'exemple utilisée durant le cours (PhotoCatBD), il y a dans le fichier
clsSujet.vb une classe Sujet qui sert à initialiser la liste de Sujets (cboSujet) en affichant le champ
Sujet et en cachant le NoSujet, exactement ce que tu tentes de faire.
Dans le formulaire principal, frmPhotoCat.InitSujets démontre la technique de création d'une
collection (objSujets au pluriel) en utilisant un DataReader et des objets de cette classe (objSujet
au singulier), puis comment l'assigner au ComboBox. En voici une copie abrégée au principal. Tu
peux consulter l'exemple sur le CD de cours pour une copie complète avec des commentaires
supplémentaires et une trappe d'erreur.
21
'Initialise la liste de sujets
Dim comSujets As OleDbCommand
Dim conPhotoCat As New OleDbConnection()
Dim dtrSujets As OleDbDataReader
Dim objSujet As Jbfi.Sujet
Dim objSujets As Collections.ArrayList
'Connexion à la base de données
conPhotoCat.ConnectionString = pcConnectionString
conPhotoCat.Open()
comSujets = New OleDbCommand("SELECT * FROM tbSujets", conPhotoCat)
dtrSujets = comSujets.ExecuteReader(CommandBehavior.CloseConnection)
'Création de la collection
objSujets = New Collections.ArrayList
While dtrSujets.Read
objSujet = New Jbfi.Sujet()
objSujet.NoSujet = dtrSujets.GetInt32(TbSujets.NoSujet)
objSujet.Sujet = dtrSujets.Item(chSujet).ToString
objSujets.Add(objSujet)
End While
'Initialisation du ComboBox
cboSujet.DataSource = objSujets
cboSujet.DisplayMember = "Sujet"
cboSujet.ValueMember = "NoSujet"
22
J'essaye d'obtenir les infos de la structure de ma table à partir de Vb.Net...Incapable...
Je remplis un dataset à partir d'une requête Sql. Par la suite, j'essaie de voir la propriété
DefaultValue d'une colonne. La value est toujours System.DBNull. Pour tant dans Sql
Server 2000 ma valeur par défaut est égale à 1.
Avez-vous une idée comment résoudre ce problème ?
Normalement, pour récupérer les détails de la structure d'une table, il suffit d'appeler la
commande FillSchema du DataAdapter avant de faire le Fill, comme ceci (dadPhotos est le
DataAdapter, m_dtsPhotos est le DataSet et tbPhotos est le nom que je donne à la table) :
dadPhotos.FillSchema(m_dtsPhotos, SchemaType.Source, "tbPhotos")
dadPhotos.Fill(m_dtsPhotos, "tbPhotos")
Malheureusement, FillSchema récupère bien des choses (PrimaryKey, AllowDBNull,
AutoIncrement, ReadOnly, etc.), mais pas la valeur par défaut. C'est explicite si on regarde dans
l'aide en ligne.
En faisant une petite recherche, j'ai trouvé l'article suivant qui tente d'expliquer pourquoi et qui
discute d'une technique permettant de contourner le problème. C'est à
http://dotnet247.com/247reference/msgs/18/91618.aspx.
23
J’ai une classe qui en référence une deuxième, et la deuxième référence aussi la première.
Dis en d’autres mots, les classes se référencent mutuellement 2. Lorsque je compile,
j’obtiens une erreur parce que j’ai une référence circulaire. Comment puis-je régler le
problème?
VB empêche les références circulaires entre 2 projets, mais les permet entre 2 dll. Deux dll
peuvent donc se référencer mutuellement, mais pas deux projets. Les deux projets doivent être
dans des solutions différentes, avec des références au dll, pas au code source.
Ça veut dire qu'en théorie, on ne peut déboguer les deux en même temps. Quand on en débogue
un, l'autre est déjà compilé. Quand on débogue le deuxième, il faut que le premier soit compilé.
Pas commode pour le débogage, à première vue, mais on peut utiliser une petite particularité de
Visual Studio dont je ne parle pas dans le cours (je peux pas tout dire, j'ai pas assez de temps).
Quand tu es en session de débogage, si tu appelles des fonctions qui sont dans un dll compilé,
mais que le code source des disponible sur la station de développement, le code source du dll
que tu appelles est automatiquement chargé dans l'environnement de Visual Studio quand il y a
une erreur ou que tu es en pas à pas.
Tu peux donc lancer une solution dans laquelle il n'y a que le projet Classe, puis quand il va
appeler Data, les fichiers source vont automatiquement s'ouvrir dans Visual Studio au besoin.
Pour faciliter le travail, j'avais l'habitude de lancer en même temps 2 copies de Visual Studio, une
avec la solution contenant Data et l'autre avec la solution pour Classe. Quand tu fais ça, le
débogueur passe automatiquement d'une copie à l'autre de Visual Studio, comme si les deux
projets étaient dans la même copie. La seule différence est qu'il faut s'assurer de compiler
individuellement chaque copie chaque fois que tu fais un changement. Si tu fais un changement
dans Data, Classe ne le voit pas tant que tu n'as pas recompilé Data, ce qui fait que c'est un peu
plus fastidieux à utiliser que quand on a les deux projets dans la même session de VS.
De temps en temps, il perd la synchronisation entre les projets, probablement à cause des
changements dans les numéros de version. Dans ce temps, supposons par exemple que Data ne
voit plus les changements de Classe, tu vas dans Data, tu enlèves la référence à Classe, tu
détruit le dll Classe qu'il a copié dans le dossier bin de Data, et tu recrées la référence. Il
resynchronise les numéros de version, et tu peux continuer.
2
Ça arrive fréquemment dans une classe d’accès aux données. Par exemple, dans une
application du type de celle utilisée dans le cours, une classe Photo peut référencer une classe
PhotoBD qui sert d’intermédiaire entre Photo et la base de données. La classe PhotoBD a bien
des chances de référencer aussi la classe Photo si c’est elle qui a la tâche de créer des objets
Photo à partir des données de la BD.
24