2. Introduction
• Couvre les bases jusqu’à certaines fonctionnalités de
.NET 4.0
• Destiné aux habituées de la POO avec de préférence une
expérience poussée en C++ ou en Java
• Inclus quelques bonus :
• Introduction à Linq
• Introduction à Entity Framework 4.0
• Introduction à Windows Phone 7
• Introduction au MVVM
4. Notion de projet, de solution
• Ici la solution est QCMService.
• Elle contient 2 projets :
• Un projet Data de type ADO.NET
EntityFramework
• Un projet QCMService de type WCF Service
• A la compilation chaque projet est
compilé de manière indépendante, puis
le projet par défaut est lancé :
• Ainsi on peut avoir une solution avec des
projets de différents types et langages
• Une dll (librairie) est donc générée par projet
• Un projet n’est pas au courant du contenu d’un
autre projet.
5. Dépendance de librairie
• Pour résoudre les dépendances entre
les projet (un projet a besoin de classes
d’un autre projet), on utilise la partie
Références :
• Ici on a référence les dll :
• De Microsoft (System.*)
• Du projet Data
6. Dépendance de namespace
• Chaque code trouve sa place dans un namespace
• Quand écrit un fichier, on utilise le mot clé using pour
signifier les namespace dont on dépant
• Sans ces using, une classe ne connait que son
namespace hôte
• Tips
• Si on utilise un code dépendant d’un autre namespace, VS ne
pourra pas identifier ce code, en revanche il pourra proposer de
rajouter automatiquement un using adapté tant que la dépandance
de librairie est renseignée
• Un clic droit dans le fichier permet de trier et de nettoyer les using
qui peuvent s’accumuler
7. Environnement : VS 2010
• Quelques tips :
• Les watchs ou espions
• La fenêtre d’exécution
• Extensions utiles (impératives) :
• Productivity power tools
8. Environnement : VS 2010
• Quelques raccourcis
• On peut définir des régions de code avec :
#region ma région
// mon code
#endregion
F1 sur une classe Documentation MSDN
CTRL + K,C Commenter
CTRL + K,U Décommenter
CTRL + K,D Formater
« for » + TAB Boucle for
« ctor » + TAB Constructeur
« prop » + TAB Propriété
… …
10. C# : Conventions
• Case Camel/Pascal :
• Les mots sont collés et se différentient par l’utilisation de la
majuscule
• Ce qui est public commence par une Majuscule
• class String
• public int Value
• public void MyFunction()
• Un champ privé commence par un underscore et une minuscule
• private int _value
• Une fonction privée ou une variable locale commence par une
minuscule
• private void myFunction(int integer)
11. C# : Commentaires
• On n’utilise par les commentaires bloc : /* … */
• On utilise les commentaire //
• TOUTE FONCTION DOIT ETRE COMMENTEE à l’aide
des commentaires de fonction :
/// <summary>
/// Return a list of category with the specified parent.
/// So, null is for the roots
/// </summary>
/// <param name="parent">The id of the parent</param>
/// <returns>The list of children categories</returns>
IEnumerable<CategoryDTO> GetCategories(int? parent);
• Astuce : entrez /// au dessus d’une fonction et le
commentaire se génère automatiquement
12. C# : Propriété
• C’est un mécanisme souple d’accession à une donnée
• On l’apparente à un couple d’accesseurs get/set
private bool _loaded;
public bool Loaded {
get { return _loaded; }
set { _loaded = value; }
}
• On peut même aller plus loins dans la custo
public string name { get; private set; }
13. C# : Typage implicite
• On peut éviter la redondance des types à la déclaration
grâce au typage implicite
var context = new QCMEntities();
• Ici le type est déduit implicitement : context est de type
QCMEntities
• La compilation remplacera var par le type explicite
14. C# : le mot clé as
• Pour le cast dynamique on pourrait faire :
var context = new QCMEntities();
ObjectContext objectContext = null;
if (context is ObjectContext)
{
objectContext = (ObjectContext)context;
}
• Mais il y a mieux :
var context = new QCMEntities();
var objectContext = context as ObjectContext;
• Attention, objectContext vaut null si le cast n’est pas possible.
15. C# : Les types nullables
• Un type nullable est un type qui supporte l’assignement à
null:
• int? a = null;
• Nullable<bool> b = null;
• MyClass? C = null;
• Un type nullable dispose de deux propriétés :
• HasValue
• Value
16. C# : Opérateur ??
• Au lieu de :
• variable != null ? variable : 1;
• Ecrivez :
• variable ?? 1;
17. C# : Initialisation d’objet
• On pourrait avoir :
var myObject = new MyClass();
myObject.Value = 12;
myObject.Name = "Hello";
• On pourrait éviter une telle redondance :
var myObject = new MyClass(12, "Hello");
• Mais cela impose la création d’un constructeur adapté à
chaque besoins
18. C# : Initialisation d’objet
• En C# on utilisera plutôt cette syntaxe pour éviter de créer
trop de constructeurs :
var myObject = new MyClass(){
Value = 12,
Name = "Hello"
}
• On peut l’utiliser pour l’initialisation d’éléments
énumérables :
var tab = new int[]{ 2, 5, 10 };
var list = new List<MyClass>(){
new MyClass(),
new MyClass()
};
19. C# : les classes partielles
• En C# on peut définir une même classe dans deux fichier
différents avec le mot clé partial
• Cela sert, par exemple, à avoir une classe partiellement
autogénéré mais également spécialisée
• Une page WP7 est un exemple de classe partielle
• Le xaml d’un coté qui va être interprété pour donner une partie
• Le .cs de l’autre qui donne l‘autre partie
20. C# : Les méthodes d’extension
• On peut vouloir ajouter une méthode à une classe sans
s’occuper de la dériver car :
• Opération couteuse forçant à utiliser manuellement le nouveau type
• Nuit à la lisibilité et à la simplicité des classes
• Ajouter au type String une méthode de slug
public static class Extension
{
public string Slug(this String s)
{
s = Regex.Replace(s, @"[^a-z0-9s-]", "");
s = Regex.Replace(s, @"s+", " ").Trim();
s = Regex.Replace(s, @"s", "-");
return s;
}
}
• Il suffit alors que la classe Extension soit chargée pour que la
classe String obtienne la méthode Slug (via using)
21. C# : les méthode d’extension
• La classe précédente était statique, ainsi chaque fonction
de la classe est statique également : une méthode
d’extension doit être statique, peut importe la classe
• Il doit toujours y avoir un premier argument, il inclue le
mot clé this ainsi que le type qui est étendu
• Le prototype complet est donc
public static string Slug(this String);
22. C# : Events
• Un évènement basique se déclare comme suit :
public event EventHandler LoadingStep;
• Il se lance comme ceci :
LoadingStep(this, new EventArgs());
• Quand l’évènement est lancé, il va déclencher toutes les
fonctions qui lui sont attachées. Celles-ci doivent avoir le
prototype suivant :
void maFonction(object sender, EventArgs arguments);
• On peut modifier le type de l’évènement EventHandler
pour supporter un prototype plus spécialisé avec autre
chose que EventArgs
23. C# : Events
• On peut s’attacher à un évènement comme ceci :
_client.LoadingStep += new EventHandler(Client_LoadingStep);
• Ou bien :
_client.LoadingStep += Client_LoadingStep;
• Ici la fonction Client_LoadingStep sera lancée
• On se détache avec l’opérateur -=
• Tips, utilisez TAB deux fois successives après avoir tappé +=
pour créer automatiquement l’attachement ainsi que la fonction
24. C# : Attributs
• Ils servent à ajouter des informations de déclaration au
code (classes, méthodes)
• Mécanisme similaire aux annotations en Java
• Exemple :
[System.Serializable]
public class SampleClass {
// Objects of this type can be serialized.
}
• Cet objet se voit conféré des propriétés de sérialisation
• On peut créer ses propres attributs
25. C# : les expressions lambda
• Une expression lambda est une déclaration allégée d’une
fonction anonyme (ou closure)
• On la stocke donc dans une délégué (pointeur de
fonction)
• Example :
delegate int del(int i);
static void Main(string[] args) {
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
26. C# : les expressions lambda
• Stoker une lambda dans une délégué n’est pas toujours
pratique
• Pour palier on utilise les classes Func<…> et Action<…>
qui encapsulent des délégués
• Func<…> retourne une valeur
• Action<…> ne retourne rien
// int comme paramètre, string comme retour
Func<int,string> exp1 = (s) => { return s.ToString(); };
// int comme paramètre
Action<int> exp2 = (b) => { Console.Out.WriteLine(b); };
27. C# : les expressions lambda
• Une expression lambda tient compte du contexte de
déclaration :
int a = 20;
Action<int> exp = (b) => { a *= b ; };
exp(10);
Console.Out.WriteLine(a); // print 200
• Plein de fonctions du Framework attendent une
expression lambda :
var a = "hello";
var eNumber = a.Count(c => c == 'e'); // eNumber = 1
28. C# : les expressions lambda
• Un autre exemple :
var a = "hello";
var vowels = new char[]{ 'a','e','i','o','u','y'};
// numberOfVowels = 2
var numberOfVowels = a.Count(c => vowels.Contains(c));
30. Linq : Définition
• Linq est une bibliothèque de requêtage amenée par le
Framework .NET 3.5
• Elle fonctionne essentiellement par méthodes d’extension
sur un type de base IEnumerable<T>
• Int[] est un IEnumerable<int>
• List<String> est un IEnumerable<String>
• Utilisation extensive des expression lambda
• La librairie de méthodes d’extension est dans
System.Linq
31. Linq : Select
• Sélectionne les éléments d’un objet selon un prédicat
• Sélectionner la longueur des chaines de caractère :
var tab = new List<String>{ "abc", "Hello", "World" };
var lenghts = tab.Select(s => s.Length);
• Mapper :
// map : DTO > entity
var categories = new List<CategoryDTO>()
{
new CategoryDTO(),
new CategoryDTO()
};
var entities = categories.Select(c => new Category()
{
ID = c.ID,
Name = c.Name,
Parent_ID = c.ParentID
});
32. Linq : Where
• Sélectionne des objets dans l’énumération selon un
prédicat
• Sélectionner les nombres pairs :
var even = tab.Where(i => i % 2 == 0);
• Truc compliqué :
var entities = categories.Where(c => c.HasChildren && c.P
arentID == 3);
33. Linq : Autres fonctions
• OrderBy
• ThenBy
• Count
• First
• FirstOrDefault
• Join
• Single
• SingleOrDefault
• ToArray
• ToList
• Contains
• …
34. Linq : Exemple
var result = context
.Questions
.Where(q => q.Questionary_ID == questionary)
.Select(q => new QuestionDTO()
{
Id = q.ID,
Label = q.Label,
Responses = q.ResponseJeus
.Select(r => new ResponseDTO()
{
Id = r.ID,
Label = r.Label,
Value = r.Value,
IdQuestion = r.Question_ID
})
.AsEnumerable(),
IdQuestionnary = q.Questionary_ID
})
.AsEnumerable();
35. Linq : syntaxe dédiée
• Linq apporte également une syntaxe dédiée
var result = from q in context.Questions
where q.Questionary_ID == questionary
select q;
• Cette syntaxe est moins verbeuse
• Elle se rapproche du SQL
• Elle reste typée et vérifiée à la compilation
39. EF4 : Structure de l’implémentation
• C’est un fichier Entity Data Model (le X signifie que c’est
un fichier de génération de code)
• On trouve donc :
• *.edmx fichier représentant le model et le mappage
• *.Designer.cs fichier auto-généré depuis le *.edmx
• App.Config contient la configuration de la BDD, dont la chaine de
connexion
• *emdx.sql contient le SQL auto-généré
40. EF4 : EDMX
• Peut être peuplé depuis la ToolBox
• Offre deux options :
• Générer la base
• Générer depuis la base
• Supporte :
• Héritage
• Entity spliting
• …
41. EF4 : Designer
• C’est le code généré par le *.edmx
• Ne jamais le modifier manuellement !
• Les classes sont partielles
• On peut donc les spécialiser sans les dériver
42. EF4 : Architecture
• QCMEntities est un ObjectContext
• Il contient les collections des types d’objets présents en
base :
• Categories
• Questions
• Questionnaries
• Responses
• Ce sont des entitées
43. EF4 : Lecture
// get the data context
var context = new QCMEntities();
var categories = context.Categories;
• Categories est IEnumerable, on peut donc utiliser
LinqToSql
// get the data context
var context = new QCMEntities();
var categories = context.Categories.Where(c => c.ID == 1);
44. EF4 : Ajout
// get the data context
var context = new QCMEntities();
context.Categories.AddObject(new Category()
{
Name = "Ma catégorie"
});
context.SaveChanges();
45. EF4 : SaveChanges
• Le contexte traque toute modification sur les entitées qu’il
contient
• Les entitées sont marqués
• Inchangé
• Nouveau
• Modifié
• Supprimé
• Les propriétés sont également marqués
• SaveChanges met à jour la base de données en rapport
avec les modifications traquées sur ses entitées
• On essaye de limiter/factoriser son utilisation
46. EF4 : Modification
var context = new QCMEntities();
var category = context.Categories.FirstOrDefault();
if (category != null)
category.Name = "New Name";
context.SaveChanges();
47. EF4 : Supression
var context = new QCMEntities();
var category = context.Categories.Single(c =>
c.Name.Equals("Delete Me")
);
context.Categories.DeleteObject(category);
context.SaveChanges();
48. EF4 : LinqToSql
• C’est l’implémentation de Linq qui transforme une requête
Linq en SQL
• La requête SQL est faite tardivement, lors de l’évaluation
du résultat
• Cela se remarque quand la collection n’est plus
IQueryable
• Cela permet de spécialiser la requête tardivement et en
plusieurs fois, tout en optimisant la transaction
50. WP7 : Silverlight and XAP
• L’interface est en Silverlight
• Le code behind est en C#
• Le SDK spécialise Silverlight et l’ensemble du Framework
• Une appli WP7 est packagée dans un XAP qui est un zip
des sources et des dll
51. WP7 : WPF
• Windows Présenter Fundation se base sur le language
XAML (prononcé zammel)
• Se base sur le marckup XML
• Il permet de :
• produire un code intelligible pour un designer
• empêcher l’introduction de logique dans la vue
• Le XAML est compilé en C# pour produire des classes
partielles complétées par le code behind
52. WP7 : Performance, Threading
• Dans un soucis de performance, la pluparts des opérations
« couteuses » sont threadées par le Framework
• Présence des fonction Async
var service = new ServiceReference.ServiceClient();
service.GetCategoriesCompleted += service_GetCategoriesCompleted;
service.GetCategoriesAsync(id);
• Seul le thread UI peut accéder à l’interface
• Présence du Dispatcher
void service_GetQuestionariesCompleted(object s, GetQuestionariesCompletedEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
QuestionnaryList.ItemsSource = e.Result;
});
var service = s as ServiceReference.ServiceClient;
service.CloseAsync();
}
53. WP7 : Demo
• Overview
• Présentation des contrôles
• Création de contrôle personnalisé
• Explication des xmlns
• Tilt effect
• Transition
55. MVVM : Retour sur le MVC
• Le MVC divise le code en 3 ensembles logiques
• Le modèle manage et contient les données
• La vue les affiche
• Le contrôleur, organise, accède, sécurise et coordonne
Modèle
VueContrôleur
56. MVVM : Les défauts du MVC
• Dans les applications à interface riches, des données
agrégées par un contrôleur pour un vue sont :
• De source multiple
• De type multiple
• Rendues différemment
• Cela amène de la confusion dans le contrôleur, comme
dans la vue
• De plus, les codes de la vue et du contrôleur deviennent
perméables et directement dépendants
57. MVVM : Apport du modèle de Vue
• MVVM : Modèle / Vue / Modèle de Vue
• Le modèle de vue est une « spécialisation » du
contrôleur, il a entre autre à sa charge de :
• Définir les données échangées entre le modèle et la vue
• Définir leur formatage
• Définir les méthodes d’extraction et de mise à jour
58. MVVM : Application pratique
• .NET 4.0 et Silverlight apportent des interfaces afin
d’appliquer le pattern
• Le binding : OnTime, OnWay, TwoWay
• Associe les champs du modèle de vue à la vue
• INotifyPropertyChanged
• Permet au modèle de vue de notifier la vue en cas de modification
• ObservableCollection<T>
• Permet à une collection du modèle de vue de notifier la vue
• Présence des Converters
59. MVVM : Demo
• Exemple d’une application Silverlight for Windows Phone
7