Cours Fonctions asynchrones et sockets en .NET
Questionnaire : POO .NET (C#) - 2009-2010
1. Expliquez l’intérêt d’utiliser simultanément les environnements de développement Visual Studio et Expression Blend pour créer une application « Silverlight ». Quels sont les caractéristiques de ces deux environnements ? Chacun de ces deux environnements permet-il de développer un projet « Silverlight » entièrement, et cela en se passant totalement de l’autre ? Expliquer l’architecture de base d’une application « Silverlight » : type(s) de projet(s) – type(s) de fichier(s). Comment insère t’on un contrôle « Silverlight » dans une application Web ?
L’intérêt principal est que l’on peut avoir un beau design graphique de la page web grâce à Silverlight. On peut développer une application Silverlight sans utiliser expression Blend mais la mise en place des composants (ex : bouton, textbox ) est beaucoup plus fastidieuse.
Caractéristiques principales : Tout deux permettent de modifier le fichier XAML, la différence est que Visual studio permet de développer du code et Expression Blend permet de travailer le design de l'application.
Les deux programmes (Visual et Expression Blend) permettent de développer une application Silverlight mais pour une application complète avec gestion des événements, accès base de données, design facilement mit en place il faut utiliser les deux programmes
Les applications Silverlight peuvent être écrites dans n’importe quel langage de programmation .NET. De même, n’importe quel outil de développement qui peut être utilisé avec les langages .NET peut fonctionner avec Silverlight, dû au fait qu’il pourra cibler directement le noyau CLR de Silverlight, à la place du CLR .NET.
Les versions 2.0 et 2.5 de Microsoft Expression Blend ont été pensées pour la conception des utilisateurs des applications Silverlight 1.0 et 2.0 respectivement. Visual Studio 2008 peut être utilisé pour développer et déboguer les applications Silverlight. Mais il faudra pour cela installer préalablement « The Silverlight Tools for Visual Studio ».
Tout d'abord on lance Visual Studio 2008 et on crée un nouveau projet de type Silverlight Application. Un projet Silverlight contient les fichiers et qui initialisent le plugin Silverlight pour l’utilisation dans des pages HTML, un fichier XAML pour l’interface utilisateur, et des fichiers de code pour les codes de l’application. Les applications Silverlight sont déboguées de la même manière que les applications . Le « Remote Cross Platform Debugging » du CLR de Visual Studio peut être utilisé pour déboguer les applications Silverlight tournant sur différentes plates-formes.
Pour insérer un control web 2 solutions existent :
• La première (la plus facile) : sous Expression Blend faire glisser un composant sur la page web puis dans ses propriétés gérer ses événements (exactement comme en Java ou C# application normal). Cette solution génère automatiquement la modification dans le fichier XAML.
• La deuxième, en modifiant le fichier XAML : par exemple pour un bouton :
| <Button x :name= "mybutton" Content="Click Me !" Click="myButton_Click" Width="100" Height="50"> </Button> |
Où Name est le nom du bouton, Content son contenu (le texte écrit dessus), Click l'événement généré, Width la largeur et Height la hauteur.
Méthode plus compliquée car pour l'événement il faut aller rajouter dans le fichier (par exemple, ) le code suivant :
private void myButton_Click(object sender, RoutedEventArgs e)
{
myButton.Content = "You clicked !";
}
2. A l’aide d’un exemple, expliquez comment peut-on, dans un projet « Silverlight », définir un nouveau look pour un bouton (ex : forme d’étoile). Quel code doit-on écrire et où doit-on le placer ? Plusieurs possibilités s’offrent-elles à nous ? Si oui, lesquelles ? Comment effectuer un choix ? Expliquez comment peut-on tenir compte d’un paramètre dans ce code (ex : largeur de l’étoile).
Nous pouvons réaliser cela en ajoutant un style dans notre , où nous allons définir la propriété Template.
<Style x:Key="StarButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Image Source="" Width="200" Height="200"/>
<TextBlock Text="Push Me !"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Et lorsque nous créons un bouton ça ne change pas :
<Button Style="{StaticResource StarButton}"/>
Le problème ici est que la taille et le texte du bouton sont mis en dur dans le code, mais nous pouvons évidemment remédier à ça.
| <Style x:Key="StarButton" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid> <Image Source="" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> |
Maintenant la taille de l'image sera la même que la taille spécifiée lors de la création du bouton.
| Button Style="{StaticResource StarButton}" Width="200" Height="200" Content="Push Me !" /> |
Une autre possibilité est de créer son Template bouton sur Silverlight. La via quelque click, on crée le bouton souhaiter que l'on utilisera ensuite comme bouton de référence.
3. Donnez une définition de Linq. A quelle version du framework .NET se trouve t’on ? Idem au niveau du la version du langage C# ? A partir d’un exemple, expliquez la syntaxe et le fonctionnement d’une requête effectuant une sélection avec filtrage et tri. Linq s’adresse t’il « uniquement » aux bases de données ? Si non, citez les différents modules de Linq ?
Le LINQ, Language Integrated Query,est un modèle de programmation permettant d’établir des requêtes sur des données dans n’importe quel langage Microsof .NET. Il permet au développeur d'accéder à des ressources de données quelconques de manière unique et simplifiée. En effetn à aucun moment il n'y aurait à entrer du code SQL par exemple. Ce langage est une nouveauté du Framework 3.5 et profite des améliorations du C# 3.0.
Il existe de nos jours plusieurs sources de données : base de données, fichiers Microsoft Access, fichiers Microsoft Excel, fichiers XML, etc, chacun possédant une amnière spécifique d'accès aux données. Par exemple, on utilise très souvent du SQL pour accéder à une base de données ou encore du « Document Object Model » (DOM) pour le XML.
C'est ici qu'intervient LINQ. Pour faciliter la manipulation de données à travers un programme, vous ne devez connaitre plus qu'un seul langage : le LINQ. A travers ses différentes extensions, il permet un accès universel à toute source de données facilitant ainsi la tâche des développeurs.
On trouve ainsi :
• un module nommé « LINQ to objects » permettant d’interroger (+ récupérer) des collections d’objets classiques
• un module nommé « LINQ to » permettant de manipuler toutes les sources de données . Il se décompose en trois parties : LINQ to DataSet, LINQ to Entities et LINQ to SQL (DLINQ)
• un module nommé « LINQ to XML » (XLINQ) permettant de manipuler des fichiers XML
Exemple :
| string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; IEnumerable<string> expr = from s in names where s.Length == 5 orderby s select s.ToUpper(); foreach (string item in expr) Console.WriteLine(item); |
4. A partir d’un exemple, expliquez le principe des modules :
• Linq to Object
• Linq to (à décomposer en 3 sous parties)
• Linq to XML
Exemple : « LINQ to objets »
List<String> source = new List<String>(); ("texte"); ("string"); ("chaine"); ("caractères");
La première requête ci-dessous est une requête simple var requete1 = from s in source where s.Length < 10 select s; foreach (var e in requete1)
{
Console.WriteLine(e);
}
();
Cette requête sélectionne notre liste de chaines de caractères « source », dont il identifie chaque objet à tour de rôle par « s », tous les objets de la liste (ici des « String ») ayant une longueur inférieure à 10 caractères. La boucle « foreach » permet d’afficher le contenu de la variable « requête1 » qui a stocké les résultats de notre requête.
Exemple : « Linq to XML » :
| Création d'un fichier XML |
| XElement xml = new XElement("Personnes", new XElement("Personne", new XAttribute("Nom", "Romio"), new XAttribute("Prenom", "Alfonso"), new XAttribute("Age", "31") ), new XElement("Personne", new XAttribute("Nom", "Vilvens"), new XAttribute("Prenom", "Claude"), new XAttribute("Age", "51") ) ); (""); |
| Lecture d'un fichier XML |
| XDocument loaded = (@""); var personnes = from pers in loaded.Descendants("Personne") where (int)pers.Attribute("Age") > 35 select (string)pers.Attribute("Nom") + " " + (string)pers.Attribute("Prenom"); foreach(var s in personnes) (s); |
« LINQ to » se décompose en trois parties :
• LINQ to DataSet
• LINQ to Entities
• LINQ to SQL (DLINQ)
Pour les exemples qui suivent, nous utiliserons la table personnel suivante :
LINQ to SQL
Créez la classe personnel correspondant à la table :
[Table(Name="Personnel")] public class Personnel
{
[Column(IsPrimaryKey=true)] public string PersonneID;
[Column] public string Nom;
[Column] public string Prenom;
[Column]
public string Naissance; }
Créez le datacontext et query
| DataContext db = new DataContext(connectionstring); // Recupere la table Table<Personnel> Personnel = db.GetTable<Personnel>(); // Personnel s'appelant toto var q = from p in Personnel where p.Nom == "toto" select p; foreach (var pers in q) Console.WriteLine("PersonneID = {0}, Naissance = {1}", pers.PersonneID , pers.Naissance ); |
LINQ to Entities est à peu de choses près similaires à LINQ to SQL. En effet, la seule différence réside dans le fait que LINQ to Entities n’utilise pas la base de données physique, mais plutôt un modèle conceptuel de cette base de données. LINQ to Entities a été imaginé afin de permettre aux applications d’interagir avec des données représentées sous forme relationnelle.
L’extrait de code suivant permet de récupérer l’ID, le nom, le prénom et la date de naissance d’une personne grâce à son nom :
| using (LINQtoEntitiesEntities MyEntities = new LINQtoEntitiesEntities()) { ObjectQuery<Personnel> Personnel = MyEntities.Personnel; //Nous utilisons la propriété Naissance à la place de //Date_de_naissance var requete = from p in Personnel where p.Nom == "TOTO" select new {p.PersonneID, p.Nom, p.Prenom, p.Naissance}; foreach (var ligne in requete) Console.WriteLine(ligne.PersonneID + " " + + " " + ligne.Prenom + " " + ligne.Naissance); } |
LINQ to Dataset : L’exécution de requêtes sur une DataTable est relativement similaire à l’établissement de requête un objet contenant un ensemble de données, dont les classes ayant permis de les créer implémente l’interface IEnumerable du Framework .NET. Cependant, la classe DataTable n’implémente pas cette interface. C’est pourquoi, il est nécessaire de lui appliquer la méthode AsEnumerable() pour requêter l’ensemble des DataRow composant les DataTable, et la méthode Field<T>() / Field (Of T) sur les DataRow (lignes) des DataTable pour accéder aux DataColumn (champs).
Voici un bloc d’instructions, permettant d’obtenir la liste du personnel via une requête LINQ, triés suivant le nom et le prénom dans l’ordre alphabétique, et de l’afficher dans une grille de données via une opération de DataBinding :
DataView oListePersonnel =
(from oPersonnel in oDataSet.Tables["Personnel"].AsEnumerable() orderby oPersonnel.Field<string>("Nom"), oPersonnel.Field<string>("Prenom") select oPersonnel).AsDataView();
LstPersonnel.DataSource = oListePersonnel;
5. Expliquez comment fait-on, dans une application Silverlight, pour accéder à une base de données en utilisant la technologie Linq ?
Dans une application Silverlight il est actuellement impossible d'accéder directement à une base de données. Cela n'empêche qu'il est parfois indispensable de pouvoir le faire. Pour contourner ce problème nous utiliserons un service WCF et une query Linq.
Notre première étape sera de créer notre projet Silverlight ainsi qu'une application web qui contiendra notre service WCF.
Linq est une nouveauté de la version 3 de C#, il prétend à être la technique recommandée pour accéder aux bases de données depuis Silverlight.
Nous allons ajouter un élément de type Linq to SQL Classes. Cette classe fera le mapping entre notre objet .Net et la table dans la base de données.
Nous créerons ensuite une connexion vers la base de données dans le Server Explorer de Visual Studio et nous ajouterons les tables nécessaire dans notre schéma (pour cela il suffit de "drag and dropper" nos tables).
Par défaut les classes ne sont pas sérialisable, cela va poser problème lorsque l'on voudra les utiliser au travers de notre service WCF. Pour lesrendre sérialisable rien de plus simple il suffit de modifier la propriété Serialization Mode en mettant la valeur Unidirectional.
Maintenant que nos classes Linq sont créées et donc connues par le système il nous reste à écrire les méthodes permettant de travailler avec ces objets. Pour cela nous allons faire appel à un service WCF.
Nous avons créé une application Silverlight et un service WCF, reste maintenant à lier les deux.
Pour cela : clic droit sur le projet Silverlight --> add Service Reference.
Reste ensuite à utiliser le proxy que nous venons de créer au travers du fichier xaml.
6. Citez et expliquez en quelques mots les apports du C#3 Les apports du C#3 sont :
• les propriétés automatiques
• l'instanciation des objets
• l'inférence de type d'une variable locale
• les types anonymes
• les expressions lambdas
• les méthodes d'extension
Les propriétés automatiques les concepteurs de la version 3 du langage C# ont introduits la notion de propriétés automatiques. C’est à dire qu’il suffit de dire qu’on désire avoir une propriété d’un certain type, portant un
certain nom et de spécifier si on désire avoir un accès en lecture ET en écriture. public String Nom { get; set; }
L'instanciation des objets
Il est désormais possible de laisser libre choix à l’utilisateur de votre classe de déterminer le nombre de propriétés pour lesquelles il décide donner une valeur d’initialisation particulière lorsqu’on instancie un objet.
Autrement dit, vous n’avez la responsabilité d’écrire toutes les versions correspondantes aux différents cas de figure qui auraient un sens (ex : initialiser le nom ET le prénom ? 1 constructeur d’initialisation à écrire – initialiser le nom ET la date de naissance ? un deuxième constructeur à écrire, etc …), puisque l’utilisateur de la classe peut écrire le genre de code repris ci dessous.
Soit la classe Personne reprise ci-dessous : public class Personne
{
public String Nom { get; set; } public String Prenom { get; set; } public String DateNaissance { get; set; }
public Personne()
{
Nom = "";
Prenom = "";
DateNaissance = "";
}
}
On peut désormais écrire :
Personne p1 = new Personne { };
Personne p2 = new Personne { Nom="Durand" };
Personne p3 = new Personne { Nom="Dupuis", Prenom="Michel" };
Personne p4 = new Personne { Nom = "Duchnok", Prenom = "Gabriel",
DateNaissance="06/09/1969" };
Remarquons l’utilisation des accolades plutôt que les parenthèses traditionnelles des constructeurs « classiques ». Seules les propriétés de la classe sont accessibles dans ce genre de constructeurs. Enfin, c’est la virgule qui fait office de séparateur entre l’initialisation de deux propriétés.
Quid au niveau des collections de données ? Les nouveautés syntaxiques exposées ci-dessus permettent également de créer une collection de données en spécifiant la liste des objets qu’on y place dès le départ.
List<Personne> personnes = new List<Personne> { p1, p3};
L'inférence de type d'une variable locale
Il est désormais possible de déduire / inférer le type d’une variable lors de la compilation. Le type var permet à l’utilisateur de laisser la responsabilité au compilateur de déterminer le type d’objet retourné par une assignation simple, une fonction, etc … (intéressant pour LINQ).
Les types anonymes
Il est possible de créer un objet instanciant un type de données … qu’on a pas définit ! En fait, il s’agit de définir les caractéristiques (en fait, uniquement une série de propriétés) de l’objet au moment où on l’instancie. A nouveau, cette nouveauté prendra tout son sens et son intérêt pour LINQ.
Les expressions lambdas
Les expressions lambdas permettent d’écrire les fonctions anonymes de manière plus condensée et plus « intuitive ».
On peut remplacer le code suivant :
| (new Predicate<Personne>(delegate(Personne p) { if (p.Nom == "Toto") return true; return false; })); |
par celui-ci :
(p => p.Nom == "Toto");
Les méthodes d'extension
Il est désormais possible d’étendre la liste de méthodes d’une classe. Cela peut s’avérer
particulièrement pratique lorsqu’on ne métrise pas le code source de la dite classe. public static class StringExtensions
{
public static String AddStars(this String str)
{
return "***" + str + "***";
}
}
Notons que les méthodes d’extensions sont toujours définies dans des classes statiques. On notera également que la méthode est (forcément) statique et qu’elle utilise le mot clé this suivi du nom du type que l’on désire étendre …
7. Qu'est ce que LINQ. A partir d'une requête simple, expliquez où interviennent les nouveautés du C# 3
Le LINQ, Language Integrated Query,est un modèle de programmation permettant d’établir des requêtes sur des données dans n’importe quel langage Microsof .NET. Il permet au développeur d'accéder à des ressources de données quelconques de manière unique et simplifiée. En effetn à aucun moment il n'y aurait à entrer du code SQL par exemple. Ce langage est une nouveauté du Framework 3.5 et profite des améliorations du C# 3.0.
Il existe de nos jours plusieurs sources de données : base de données, fichiers Microsoft Access, fichiers Microsoft Excel, fichiers XML, etc, chacun possédant une amnière spécifique d'accès aux données. Par exemple, on utilise très souvent du SQL pour accéder à une base de données ou encore du « Document Object Model » (DOM) pour le XML.
C'est ici qu'intervient LINQ. Pour faciliter la manipulation de données à travers un programme, vous ne devez connaitre plus qu'un seul langage : le LINQ. A travers ses différentes extensions, il permet un accès universel à toute source de données facilitant ainsi la tâche des développeurs.
La requête LINQ :
IEnumerable<string> expr = from s in names where s.Length == 5 orderby s select s.ToUpper();
peut également s’écrire de la manière suivante :
IEnumerable<string> expr = names
.Where(s => s.Length == 5)
.OrderBy(s => s)
.Select(s => s.ToUpper());
Cette représentation de la requête met en évidence l’utilisation, ainsi que l’utilisé, des expressions lambdas et des méthodes d’extensions (les méthodes Where, OrderBy et Select étant des méthodes d’extensions de la « classe » string[]).
