Si vous avez un peu de temps et que vous souhaitez vous mettre à Azure, MS organise un dev Camp le 20 juin à Issy les Molineaux:

Au programme:
· Présentations et démos exclusives des nouveautés de la plateforme
· Échanges avec des membres de l'équipe de développement Windows Azure spécialement venus de Seattle
· Des contests avec des Nokia Lumia 800 et plein d'autres prix à gagner
· Sans oublier des pizzas, des goodies et des offres sympas de nos partenaires !
l’une des (belle) nouveauté de VS 11 et dont on ne parle pas assez a mon sens est l’intégration des différents framework de tests (tout le monde n’a pas la chance d’avoir Resharper) tels que NUnit.
Pour cela, rien de plus simple, il vous suffit d’aller chercher dans votre “gestionnaire d’extensions” (oui, je suis un boulet, j’ai encore installé VS en francais…) et de rechercher l’addin :”Nunit Test Adapter:

Une fois que c’est installé, vous pouvez jouer vos tests unitaires qui utilisent le framework Nunit depuis l’explorateur de tests unitaires (le “Unit Test Explorer”):

Et cerise sur le gâteau, la couverture de code fonctionne 

PS: il faut bien evidement avoir télécharger (via NuGet) NUnit.
Les traitements parallèles/asynchrones présentent pas mal d’avantages et l’introduction des Tasks et d’async/await nous permettent de les utiliser (d’en abuser) simplement on améliorer la lisibilité de notre code.
Cependant, il reste un point qui, à mon avis, mérite un petit post parce qu’il n’est pas aussi trivial qu’il n’y parait: l’annulation des tâches en cours d’exécution.
Un petit exemple pour poser le problème:
J’ai une application qui doit charger des données et ce traitement prend un certains temps, d’un autre coté, j’ai la possibilité d’annuler ce chargement (pour une raison quelconque).
j’ai donc une application WPF qui ressemble a ca:

et le code suivant:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
CancellationTokenSource cts = new CancellationTokenSource();
void Button_Click_1(object sender, RoutedEventArgs e)
{
CancelTest1();
//CancelTest2();
//CancelTest3();
//CancelTest4();
//CancelTest5();
//CancelTest6();
}
void CancelTest1()
{
listBox.Items.Add("start loading...");
Task<string>.Run(() =>
{
System.Threading.Thread.Sleep(3000);
},cts.Token).ContinueWith(t => listBox.Items.Add("finish"),
TaskScheduler.FromCurrentSynchronizationContext());
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
cts.Cancel();
listBox.Items.Add("Cancel!");
}
}
On utilise un CancellationToken (produit par l’objet CancellationTokenSource) on le passe en paramètre de la méthode Task.Run() qui est chargée de lancer mon traitement. Pour l’exécution de l’annulation, j’appel
simplement la méthode Cancel sur mon objet de type CancellationTokenSource (celui à partir duquel j’ai créer mon objet CancellationToken).
Ca marche pas!
Si je lance un chargement et que je l’annule dans la foulée, j’obtient le résultat suivant:

Je me rend compte que ma tâche ne s’annule pas! pire, elle termine sont traitement et maj mon interface!…bref, ca marche pas (…comme ca).
Ca marche TOUJOURS pas!
Du coup, je me dit que je doit tester le statut de la Tâche pour ne pas avoir à maj mon UI (temps pis si la tâche s’éxécute jusqu’au bout…dans un premier temps). Je test donc le code suivant:
void CancelTest2()
{
listBox.Items.Add("start loading...");
Task.Run(() =>
{
System.Threading.Thread.Sleep(3000);
}, cts.Token).ContinueWith(t =>
{
if (t.IsCanceled)
listBox.Items.Add("finish...but canceled");
else if (t.IsCompleted)
listBox.Items.Add("finish");
else if (t.IsFaulted)
listBox.Items.Add("Error during loading");
listBox.Items.Add("Task status->" + t.Status);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Je test le statut de ma tâche; et en fonction de celui-ci, je maj de manière différente mon UI, de plus, j’affiche le statut de cette tâche. On obtient le résultat suivant:

ca marche pas! et pire encore, la tâche à le statut RanToCompletion (ie: j’ai fini sans problème coco) !!
…Tout ca pour dire que ca n’est pas aussi simple que le laisse penser les API TPL:
il ne suffit pas de passer un CancellationToken et de faire cancel sur la source pour que cela fonctionne OOB.
si vous voulez le faire…vous ne ferez pas l’économie d’un tour sur la msdn
.
Si on souhaite que cela fonctionne, il éxiste plusieurs méthodes qui peuvent correspondre a des scénarios différents, je vais donc tenter de les présenter par la suite:
Je vérifie à la fin de la tâche si celle-ci à été interrompue et je gère en fonction mon affichage:
On test tout simplement l’objet CancellationToken au lieu du statut de la tâche:
void CancelTest4()
{
listBox.Items.Add("start loading...");
Task.Run(() =>
{
System.Threading.Thread.Sleep(3000);
}, cts.Token).ContinueWith(t =>
{
if (cts.IsCancellationRequested)
listBox.Items.Add("finish...but canceled");
else if (t.IsCompleted)
listBox.Items.Add("finish");
else if (t.IsFaulted)
listBox.Items.Add("Error during loading");
listBox.Items.Add("Task status->" + t.Status);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Ce qui nous donne :
Ca fonctionne mais la tâche s’est exécuté complètement. C’est bien lorsque l’on a des tâches de traitement qui ne sont pas “gênantes” pour l’utilisateur comme les traitements “court” et qui ne consomment pas trop de resources,…
On en fait le moins possible et on s’attend à une exception qui interromps le traitement: utilisation Task.Wait/WaitAll/WaitAny :
async void CancelTest3()
{
try
{
listBox.Items.Add("start loading...");
var status = await Task.Run(() =>
{
var t = Task.Run(() =>
{
System.Threading.Thread.Sleep(3000);
}, cts.Token);
t.Wait(cts.Token);
return t.Status;
});
listBox.Items.Add("Finish");
listBox.Items.Add("Task status->" + status);
}
catch (Exception e)
{
listBox.Items.Add(e.Message);
}
}
Dans cette exemple, j’utilises async/await pour éviter d’avoir a lancer deux tâches (une pour annuler la première) et complexifier mon exemple: sans cela, je ne peut pas cliquer sur le bouton Cancel car mon UI est bloquée. Je lance une première tâche asynchrone qui lance la tâche qui simule le traitement. Derrière j’attend qu’elle se termine avec la méthode t.Wait().
Si je fait mon test (lancer le chargement et cancel dans la foulée) j’obtient ca:

Je me mange une exception tout de suite après avoir cliquer sur le bouton Cancel, du coup, un petit try/catch me permet de gerer simplement la stratégie de MAJ de mon UI en cas d’annulation de ma tâche.
Ca marche, c’est un peu crade pour cet exemple mais c’est très utile si par exemple vous lancez plusieurs tâches de chargement (BDD, profil utilisateur,…) et que vous souhaitez les annuler simplement.
Je gère dans mon traitement de chargement l’interruption de la tâche
AU final, je pense que c’est le cas que l’on doit le plus privilégier. Dans la méthode de chargement, je sait comment m’interrompre “proprement” et faire remonter soit une exception, soit un statut “propre” à l’appelant:
Sans exception:
void CancelTest5()
{
listBox.Items.Add("start loading...");
CancellationToken token = cts.Token;
Task<string>.Run( () =>
{
string s = "step1";
System.Threading.Thread.Sleep(3000);
s = "step2";
if (!token.IsCancellationRequested)
{
System.Threading.Thread.Sleep(1000);
s = "step3";
}
return s;
}, cts.Token).ContinueWith(t =>
{
listBox.Items.Add(t.Result);
listBox.Items.Add("Task status->" + t.Status);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Ici, on à découper le traitement de chargement en plusieurs étapes (step1, step2,…)et on test au fur et a mesure (via la propriété IsCancellationRequested) si la tâche est annulé et on réagit en conséquence (dans notre cas, on ne fait pas la 3e étape). On obtient le résultat suivant:

Ca marche (mais on a tjr le statut de la tâche à RunToCompletion
).
void CancelTest6()
{
listBox.Items.Add("start loading...");
CancellationToken token = cts.Token;
Task<string>.Run(() =>
{
string s = "step1";
System.Threading.Thread.Sleep(3000);
token.ThrowIfCancellationRequested();
s = "step2";
token.ThrowIfCancellationRequested();
System.Threading.Thread.Sleep(1000);
s = "step3";
return s;
}, cts.Token).ContinueWith(t =>
{
listBox.Items.Add(t.Result);
listBox.Items.Add("Task status->" + t.Status);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
On va juste utiliser la méthode ThrowIfCancellationRequested qui est liée au CancellationToken au lieu de tester la valeur de la propriété IsCancellationRequested.
Tout le monde est unanime pour dire que la programmation multi-thread et asynchrone est en train de devenir un sujet incontournable.
Beaucoup de choses sont arrivées avec le framework 4 pour le code parallèle (TPL, PLinq,…) et bientôt, on va avoir le droit à l’api async/await pour la partie Async.
Au temps vous le dire de suite, j’ai pas tout de suite compris les subtilités apportés par Async et j’étais donc en mode (idiot) “Async? m’en fous, ca sert a rien, avec TPL on peut déjà tout faire” …MAIS, je me suis dit que si Microsoft l’avait sortie et intégré dans le framework, c’est que ca mérite quelques heures à faire joujoux avec.
après avoir installé la CTP d’async, ma première bonne surprise est la qualité et la richesse de la documentation (a quand la même chose sur les API TFS
?):

Pour le coup, il y a vraiment tout pour bien commencer.
Maintenant, entrons dans le vif du sujet: le code!
on va prendre un exemple simple; une classe qui contient deux méthodes qui simulent des traitements court (1s) et le second long (2s):
1: public class AsyncExemple
2: {
3: private string TraitementLong()
4: {
5: System.Threading.Thread.Sleep(2000);
6: return "traitement long fini";
7: }
8:
9: private string TraitementCourt()
10: {
11: System.Threading.Thread.Sleep(1000);
12: return "traitement Court fini";
13: }
14: }
Avec les Tasks, si je souhaite effectuer les deux traitements en parallèle, il me suffit de faire ca:
1: public void ParallelTaskRun()
2: {
3: Task.Factory.StartNew(() =>{Console.WriteLine(TraitementLong());});
4: Task.Factory.StartNew(() =>{Console.WriteLine(TraitementCourt());});
5: }
et si j’exécute le code suivant:
1: Console.WriteLine("Début du traitement");
2: AsyncExemple e = new AsyncExemple();
3: e.ParallelTaskRun();
4: Console.WriteLine("Fin du traitement");
5: Console.ReadLine();
On a le résultat (attendu) suivant:

On a lancé nos deux traitements dans des Threads séparés, du coup on a le message de fin de traitement avant d’avoir ceux des traitements long et court ET le traitement court se fini avant le long.
Maintenant la même chose avec async, prenons le code suivant (on simule en plus un chargement):
1: public async void Run()
2: {
3:
4: System.Threading.Thread.Sleep(5000);
5: Console.WriteLine("...fin du chargement");
6: string text1 = await TaskEx.Run(() => { return TraitementLong(); });
7: Console.WriteLine(text1);
8: string text2 = await TaskEx.Run(() => { return TraitementCourt(); });
9: Console.WriteLine(text2);
10: }
On obtient le résultat suivant:
Là, ca devient intéressant. On remarque que :
- le chargement s’effectue de manière séquentiel malgré le fait qu’il soit dans la méthode marquée async.
- les traitements marqués avec await s’exécutent bien de manière asynchrone par rapport à la méthode appelante (le Thread sur lequel s’exécute la méthode qui appelle la méthode async) MAIS de manière séquentiel.
Ce qui est asynchrone est donc ce qui est préfixé avec le mot clé await et est relatif au contexte de la méthode qui appelle la méthode async.
Prenons un autre exemple pour clarifier cette dernière phrase:
1: public void Run()
2: {
3: TraitementLongAsync();
4: TraitementCourtAsync();
5: }
6:
7: public async void TraitementLongAsync()
8: {
9: string text = await TaskEx.Run(() => { return TraitementLong(); });
10: Console.WriteLine(text);
11: }
12:
13: private async void TraitementCourtAsync()
14: {
15: string text = await TaskEx.Run(() => { return TraitementCourt(); });
16: Console.WriteLine(text);
17: }
On a encapsulé les tratiements dans des méthodes asynchrones distinctes et on les lance depuis une méthode Run…si vous avez bien compris ce que j’ai dit plus haut, vous devriez savoir quel va être le résultat qui est …

…le même qu’avec les Tasks ! logique 
les méthodes se lancent de manière asynchrone par rapport au contexte de la méthode appelante Run.
On a donc:
- la méthode Run appelle la méthode asynchrone chargée de lancer le traitement long.
- Celle-ci lance le traitement long en asynchrone et rend la main à la méthode Run
- qui lance la méthode chargée de lancer le traitement long
- …vous avez compris la suite
On voit bien ici qu’il y a quelques subtilité à appréhender. Ce qu’il est important de comprendre également c’est que sur une console ca n’a pas beaucoup de sens d’utiliser async, par contre, lorsque vous avez à faire des applications graphiques, cela devient extrêmement puissant. Si on prend l’exemple du Thread UI abordé dans mon post précédent. avec async il suffit juste de faire ca pour ne plus avoir à se poser de questions:
1: private async void button1_Click(object sender, RoutedEventArgs e)
2: {
3: textBox1.Text = await TaskEx.Run(() =>
4: {
5: System.Threading.Thread.Sleep(2000);
6: return "toto";
7: });
8: }
le code est tout de même beaucoup plus élégant et on a plus besoin de se demander comment on retourne sur le Thread UI….ou comme le dirait Squizz; “la classe! totaaaale”.
RQ: on a la possibilité de faire ca directement sur le code du bouton car il a le bon gout de ne rien renvoyer (void).
Pour finir et voir si vous avez bien compris, que ce passe t’il si j’exécute le code suivant:
1: private async void button1_Click(object sender, RoutedEventArgs e)
2: {
3: textBox1.Text = await TaskEx.Run(() =>
4: {
5: System.Threading.Thread.Sleep(2000);
6: return "toto";
7: });
8:
9: System.Threading.Thread.Sleep(5000);
10:
11: textBox1.Text = await TaskEx.Run(() =>
12: {
13: System.Threading.Thread.Sleep(2000);
14: return "tata";
15: });
16: }
sans l’exécuter bien sûr 
Je viens de passer quelques temps au TechDay’s et j’ai pu voir pas mal de session intéressante. Par contre une chose m’a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, beaucoup de speaker expliquaient qu’avec l’API Task, il est très compliqué de revenir vers le thread UI sauf à passer par les méthodes old school (BeginInvoke,EndInvoke)…du coup, comme on se tape toute la tuyauterie, plus besoin de Task
.
Pour eux, la solution passe par l’utilisation de async/await ce qui va nous permettre de régler ce problème de manière élégante MAIS mon problème ce que pour moi, il existe des moyen technique assez simple (aussi simple que async/await) pour régler ce problème, en particulier avec PRISM.
Du coup, je me suis dit que ca valait peut être le coup de faire un petit post là dessus.
Je vais donc vous montrer ici comment je fais ca simplement avec la classe Eventaggregator (disponible avec PRISM)
Prenons l’exemple suivant:un bouton qui lorsque l’on click dessus renseigne le contenu d’une textBox avec un petit sleep pour simuler une activitée qui prend du temps:
1: private void button1_Click(object sender, RoutedEventArgs e)
2: {
3:
4: System.Threading.Thread.Sleep(5000);
5: textBox1.Text = "toto";
6:
7: }
si j’exécute mon appli, mon interface est gelée pendant 5 secondes…ce qui est inacceptable pour un utilisateur. Du coup, on souhaite faire ca en parallèle. Mon code devient donc:
1: private void button1_Click(object sender, RoutedEventArgs e)
2: {
3: var t = Task.Factory.StartNew(() =>
4: {
5: System.Threading.Thread.Sleep(5000);
6: textBox1.Text = "toto";
7: });
8:
9: }
…mais a l’exécution j’ai la fameuse erreur du Thread UI:

et pour régler ca, j’utilise l’EventAggregator:
1: public partial class MainWindow : Window
2: {
3: private IEventAggregator eventAggregator = new EventAggregator();
4: public MainWindow()
5: {
6: InitializeComponent();
7: eventAggregator.GetEvent<CompositePresentationEvent<string>>().
8: Subscribe(val => textBox1.Text = val
9: , ThreadOption.UIThread);
10: }
11:
12: private void button1_Click(object sender, RoutedEventArgs e)
13: {
14: var t = Task.Factory.StartNew<string>(() =>
15: {
16: System.Threading.Thread.Sleep(5000);
17: return "toto";
18: }).ContinueWith((task) =>
19: eventAggregator.GetEvent<CompositePresentationEvent<string>>()
20: .Publish(task.Result));
21: }
22:
23:
24: }
Il y a trois choses importantes dans ce code:
- On passe par un évènement pour synchroniser notre interface graphique avec notre tâche. Cet évènement est complètement géré par PRISM via la classe EventAggregator (qui est une pur merveille). Ici, j’ai utilisé l’objet de base (CompositePresentationEvent<string>) mais dans la pratique on va pouvoir avoir des objets plus complexes et mieux adaptés: si notre traitement renvoi un objet de type Client pour mettre à jours un ensemble de contrôles, on va plutôt utiliser la classe CompositePresentationEvent<Client>.
- L’utilisation de l’EventAggregator pour repasser dans le thread UI: la méthode Subscirbe qui permet de s’abonner à notre évènement à comme paramètre ThreadOption.UIThread, sans cette option, rien ne marche.
- A la fin de ma tâche, on lance une action qui à uniquement pour but de lever un évènement avec le résultat du traitement. Comme on est dans le ContinueWith, on est sûr que le traitement est fini et OK.
Je suis tombé sur cet article il y a peu de temps et je pense qu’approfondir ses connaissances sur le garbage collector est d’actualité pour pas mal de consultant.
Vous savez tous que, comme les oiseaux, les consultants on également une période de migration qui coïncide généralement avec la nouvelle année: si si, elle est en générale déclenchée juste après une visite (si vous avez de la chance…sinon un coup de tel ou un mail) de votre manager vous explique que “malgré vos bon résultats…bla bla bla… mais tu comprend le contexte économique…bla bla bla….pas d’augmentation cette année…”
Alors, le consultant prépare son CV et prend son envol vers de nouveaux cieux (SSII) en passant par des étapes plus ou moins difficile parmi lesquelles le fameux “entretien technique”.
Et c’est la que ce magic lien vous permet de faire le malin pendant vos entretiens 
Plus sérieusement; vous y trouverez un article bien construit qui présente de manière très simple le nouveau fonctionnement du garbage collector.
Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous trouverez l’introducton ainsi que les liens vers les autres articles ici .
Definition:
Le principe d’inversion de dépendance, toujours énoncé par Robert Martin, indique que les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions. Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions.
Le principe DIP se propose donc d’isoler les modules en intercalant une interface (abstraction) entre les deux: l’idée sous-jacente de ce concept est donc qu’une abstraction doit faire le lien entre les modules de hauts et de bas niveaux. Une abstraction est le plus souvent une interface mais on peut également utiliser le concept « Factory Pattern ».
Prenons l’exemple standard d’une application type qui présente des problèmes de dépendance forte peut être désignée ainsi : la Couche Présentation est dépendante de la Couche Métier qui est dépendante de la Couche Accès aux Données. Cela nous donne le schéma suivant:

Le changement d’un module de bas niveau engendre la modification de ceux de haut niveau, les modules de hauts niveaux ne peuvent donc pas être réutilisés au sein d’autres contextes techniques: il nous est impossible de complètement isoler nos modules (On peu aussi dire qu’il est très difficile de faire des tests unitaire a cause de ce couplage…).
Si on devait respecter le principe DIP, on aurait le schéma suivant:

L’introductions des interfaces (en jaune) nous permet de réaliser l’isolation voulue car notre module de présentation dépend uniquement de l’interface Interface Couche Metier.
Exemple:
Prenons maintenant un exemple plus concret. Ici la classe n’est dépendante d’aucune autre classe, les seules références à des objets sont typées via des interfaces :
1: public class ValidationManager
2: {
3:
4: private IValidatable _validatableObject;
5:
6: public ValidationManager(IValidatable validatableObject)
7: {
8:
9: _validatableObject = validatableObject;
10:
11: }
12:
13: public void RunValidation()
14: {
15:
16: _validatableObject.Validate();
17:
18: }
19:
20: }
La classe « ValidationManagerFactory » se charge de résoudre les dépendances : elle associe un objet qui respecte l’interface « IValidatable » à un objet de type « ValidationManager ».
1: public class ValidationManagerFactory
2:
3: {
4:
5: public ValidationManager GetValidationManager(IBusinessObject bo)
6:
7: {
8:
9: return new ValidationManager(bo);
10:
11: }
12:
13: }
14:
Conclusion:
L’introduction d’interface permet donc d’inverser les dépendances et appliquer entre les classes de deux modules; d’obtenir dans notre exemple des couches indépendantes.
Le seul problème que j’ai avec ce principe est de savoir a quel niveau on doit inverser les dépendances: l’assembly? le package (namespace)?, la classe comme dans notre exemple?
La classe est un niveau trop fin, on ne va pas s’amuser a créer une interface pour toutes les classes que l’on utilise.
Le namespace me parrait être un bon choix, mais le fait qu’il ne soit qu’une séparation logique et non pas physique me pose un problème si je souhaite intervertir un package…
Mon avis est que la bonne granularité est l’assembly pour deux raisons:
- il existe des framework tel que Unity permettant de faire de l’IOC.
- l’assembly est un regroupement physique (dans la majorité des cas).
Ce principe amène de la flexibilité dans les applications, les modules étant réutilisables. L’application de ce principe coupe donc totalement les liens pouvant exister entre deux modules mais complexifie le code en augmentant le niveau d’abstraction. Il faut donc savoir l’utiliser avec parcimonie.
Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous trouverez l’introducton ainsi que les liens vers les autres articles
ici
.
Définition:
Un client ne doit jamais être forcé de dépendre d’une interface qu’il n’utilise pas (Robert C. Martin).
Ce principe est somme toute assez simple et ressemble beaucoup au principe de responsabilité unique. L’idée sous jacente étant de limiter au maximum le couplage en limitant le “bruit” généré par la modification d’une interface.
Exemple:
Prenons un exemple simple avec l’interface suivante:

Alors oui, cet exemple est mauvais car on ne respecte pas le principe de responsabilité unique et que c’est une très mauvaise idée que d’avoir la persistance au même endroit que le stockage des informations….mais on est dans un exemple dont le but est la compréhension du principe.
On a donc une interface IBusinessObject qui présente des groupes de méthodes que l’on peut facilement regrouper en deux parties:
- Persistance des données
- validations
Maintenant, supposons que nous ayons deux clients distincts qui s’intéressent à la validation et à la persistance:
1: public class ValidationManager
2: {
3: public void ValidateBusinessObjects(List<IBusinessObject> businessObjects)
4: {
5: if (businessObjects != null)
6: {
7: foreach (IBusinessObject bo in businessObjects)
8: {
9: bo.Validate();
10: }
11: }
12: }
13: }
14:
15: public class PersistManager
16: {
17: public void InsertAll(List<IBusinessObject> businessObjects)
18: {
19: if (businessObjects != null)
20: {
21: foreach (IBusinessObject bo in businessObjects)
22: {
23: bo.Insert();
24: }
25: }
26: }
27: }
Nos deux classes sont couplés à l’interface IBusinessObject, et donc chaque modification de cette interface est susceptible d’avoir un impact sur ces deux classes…même si l’impact ne concerne pas le boulot effectué par la classe.
Une solution serait donc d’avoir une structure différente:

De cette manière, si un client doit dépendre de la partie liée à la validation, il utilisera l’interface IValidatable, la persistance: l’interface IPersistable…et des deux parties l’interface IBusinessObject.
Ca nous donne donc le code suivant:
1: public class ValidationManager
2: {
3: public void ValidateBusinessObjects(List<IValidatable> validatableObjects)
4: {
5: if (validatableObjects != null)
6: {
7: foreach (IValidatable vo in validatableObjects)
8: {
9: vo.Validate();
10: }
11: }
12:
13: }
14: }
15:
16: public class PersistManager
17: {
18: public void InsertAll(List<IPersistable> persistableObjects)
19: {
20: if (persistableObjects != null)
21: {
22: foreach (IPersistable po in persistableObjects)
23: {
24: po.Insert();
25: }
26: }
27: }
28: }
On casse donc ainsi le couplage indirect entre les classes PersistManager et ValidationManager.
Conclusion:
Ce principe met donc en exergue des défaut de design qui ont le mauvais gout d’ajouter du couplage inutile. Dans une expérience très récente, nous avons été confrontés à ce genre de problème et nous avons eu pas mal d’impact sur le code du SI que nous avions à gérer (ajout de dépendances sur des dll inutiles, ajout de code…inutile!): une interface de très bas niveau comportant plusieurs dizaines de méthodes complètements disjointes imposait un couplage extrêmement couteux alors qu’une simple réorganisation de cette interface aurait suffit pour ne pas générer du couplage et donc du code inutile. C’est donc un principe simple, facile à comprendre, facile à corriger…on a donc aucune raison de ne pas l’appliquer!
Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous trouverez l’introducton ainsi que les liens vers les autres articles
ici
.
Avec le principe de substitution de Liskov, on s’attaque au principe le plus difficile à comprendre mais aussi le plus interressant et celui qui a le plus grand impact dans le code que l’on est amené à écrire.
Je vais donc tenter de l’expliquer le plus simplement possible à travers ce post tout en abordant le maximum de choses.
Comprendre l’objectif du principe
Le principe de substitution de Liskov nous dit (définition de Robert C. Martin) :
Les méthodes qui utilisent les objets d'une classe doivent pouvoir utiliser des objets dérivés de cette classe sans même le savoir.
En d’autres termes:
Une classe de base doit être substituable par ses classes dérivées sans que cela nécessite des modifications dans la méthode qui utilise ces classes.
Si on prend le problème dans l’autre sens, on a quelque chose d’un peu plus compréhensible:
Si je souhaite faire une classe A qui hérite d’une classe B, je dois m’assurer de ne pas introduire de modifications dans son fonctionnement qui rend inutilisable tout objet de type A utilisé comme un objet de type B.
toujours pas clair?…. c’est normal, prenons un exemple concret:

Ca ressemble à un canard, fait le même bruit qu’un canard mais ca a besoin de batteries, vous avez probablement la mauvaise abstraction!
L’idée qui se cache derrière cette image est que le canard électrique est une spécialisation du canard naturel (la classe canard électrique hérite de la classe canard)…et qae cela pose un problème parce que le canard électrique à un besoin impératif de batterie pour fonctionner contrairement au canard naturelle.
Regardons le code maintenant:
1: public class Duck
2: {
3: public DuckState State {get; private set;}
4:
5:
6: public virtual void Fly()
7: {
8: State = DuckState.Fly;
9: }
10: }
11:
12:
13: public enum DuckState
14: {
15: Rest,
16: Fly
17: }
La classe canard possède une méthode Fly qui permet de positionner l’état du canard à Fly.
Regardons maintenant la classe Canard Electrique:
1: public class ElectricDuck: Duck
2: {
3:
4: public bool SwitchOn { get; set; }
5: public override void Fly()
6: {
7: if(SwitchOn)
8: base.Fly();
9: }
10: }
Celle-ci hérite de la classe canard, possède une propriété SwitchOn qui correspond à l’allumage du canard et on modifie la méthode fly en vérifiant que le canard est bien allumé. Fonctionnellement cela est cohérent et techniquement l’héritage “semble” justifié.
Regardons le code suivant:
1: private static void Exemple1(List<Duck> myList )
2: {
3:
4: int nbDucks = 0;
5:
6: foreach (var duck in myList)
7: {
8: duck.Fly();
9: if (duck.State == DuckState.Fly)
10: nbDucks++;
11: }
12:
13: Debug.Assert(nbDucks == myList.Count, "All ducks are not in
the sky!!");
14: }
Si on exécute cette méthode (on fait voler les canards et on vérifies bien qu’il y en a 2 qui sont en train de voler) avec en paramètre les objets suivant:
1: List<Duck> myList = new List<Duck>() { new Duck(), new Duck() };
2: Exemple1(myList);
tout marche bien et on est content.
Maintenant introduisons nos fameux canard électriques:
1: List<Duck> myList = new List<Duck>() { new Duck(), new ElectricDuck(),
new Duck() };
2: Exemple1(myList);
Et la …ca nous envoi une erreur à l’exécution! Pourquoi? parce que l’on ne respecte pas le principe de Liskov. reprenons la définition et complétons la avec les acteurs de cet exemple:
Les méthodes [La méthode Exemple1] qui utilisent les objets d'une classe [La classe Duck] doivent pouvoir utiliser des objets dérivés de cette classe [La classe ElectricDuck] sans même le savoir.
Sauf que pour le coup, ca marche pas: le canard electrique n’ayant pas pu décoller on a une erreir…donc le principe de Liskov est violé 
On pourrait proposer la correction suivante:
1: private static void Exemple1(List<Duck> myList )
2: {
3:
4: int nbDucks = 0;
5:
6: foreach (var duck in myList)
7: {
8:
9: if (duck is ElectricDuck)
10: ((ElectricDuck)duck).SwitchOn = true;
11: duck.Fly();
12:
13:
14: if (duck.State == DuckState.Fly)
15: nbDucks++;
16: }
17:
18: Debug.Assert(nbDucks == myList.Count, "All ducks are not in the sky!!");
19: }
Ca fonctionne sauf que la méthode Exemple1 a besoin de connaitre le type réel des objets pour pouvoir les traiter correctement…donc on viole Liskov ET au passage le principe OCP!
Au final, faire hériter la classe ElectircDuck de Duck est une mauvaise idée.
Le principe de Liskov est donc un critère qui va nous permettre de dire si l’héritage est cohérent du point de vue fonctionnel des clients ou pas.c’est EXACTEMENT CA ET RIEN DE PLUS!
Comment détecter les violations?
He bien pour le coup, la mère Liskov (c’est une femme au passage) elle ne nous dit rien; débrouiller vous 
On doit donc trouver un moyen technique qui va nous permettre de définir comment être sûr qu’une classe qui hérite de “moi” ne va pas me faire violer le principe…Evaluons les réponses suivantes:
Je doit tester toute ies classes sur du code qui utilise mes classes de bases!
>>sauf que je ne maitrise pas toujours l’utilisation de mes classes et encore moins dans le cadre du développement d’un framework
Je cèle mes classes (sealed) et pas de polymorphisme!
>>Je dois quand même respecter OCP …et faire de la POO 
J’utilise Code Contracts parce que j’ai lu le (super) blog de Fathi 
>> Exact! tu est un super développeur et tu ira loin!
Monsieur Bertrand Meyer [Zorro] est arrivé !!
La solution est apporté par Monsieur Bertrand Meyer: pour valider nos classes dérivés et les modifications faites dans les méthodes modifiées, on utilise le paradigme de programmation Design by contract. Je vous invite a lire ce post ici pour comprendre un peu comment fonctionne l’API CodeContract qui est à mon sens une réponse parfaite a cette problématique.
L’utilisation de ce concept dans les programmes consiste à établir des contraintes fonctionnelles dans l’utilisation des objets, ces contraintes définissant les conditions correctes d’utilisation d’un objet.
Il existe trois types de contrat :
· Les pré-conditions : tester l’état des objets avant le traitement (tester les paramètres)
· Les post-conditions : tester l’état des objets à la fin du traitement (tester les objets modifiés ou les résultats produits par le traitement)
· Les invariants : s’assurer que certains objets ne changent jamais pendant un traitement
Les modifications effectuées dans les sous-types sont donc encadrées par le biais de contrats « fonctionnels ». Cependant, il faut s’assurer que les fonctionnalités dans les sous-types respectent toujours les mêmes contraintes. Dans le cas où l’on souhaite utiliser le polymorphisme pour faire évoluer les fonctionnalités, les règles suivantes doivent être respectées…sinon pas de Liskov! :
· Aucune modification des invariants dans une classe dérivée
· Aucun renforcement des pré-conditions dans une classe dérivée
· Aucun affaiblissement des post-conditions dans une classe dérivée
Revenons en à nos canards et adaptons notre code pour integrer certaines conditions:
1: public class Duck
2: {
3: public DuckState State {get; private set;}
4:
5:
6: public virtual void Fly()
7: {
8: State = DuckState.Fly;
9:
10: Contract.Ensures(this.State == DuckState.Fly);
11: }
12: }
13:
14:
15: public enum DuckState
16: {
17: Rest,
18: Fly
19: }
J’ai ajouté la ligne :
Contract.Ensures(this.State == DuckState.Fly);
Qui signifie que fonctionnellement, a la fin de la méthode Fly, le canard doit être en train de voler!
Du coup, utiliser la classe ElectricDuck en l’état aboutirai a une exception si on refait le test ci-dessus (execution de la méthode methode1). Une exception qui t’indique que tu casse le principe de Liskov quelque part
.
Du coup, dans la classe ElectricDuck, je dois faire la modification suivante si je souhaite respecter ce principe:
1: public class ElectricDuck: Duck
2: {
3:
4: public bool SwitchOn { get; set; }
5: public override void Fly()
6: {
7: if (!SwitchOn)
8: SwitchOn = true;
9:
10: base.Fly();
11: }
12: }
Le canard c’est s’allumer tout seul…pas terrible hein! Il est donc préférable de ne pas hériter de la classe Duck tout court.
Pour en revenir à la règle sur les pré-conditions, je vous invite a regarder l’exemple très connu du carré qui hérite du rectangle proposé par Robert C. Martin dans son ouvrage et de réfléchir à quel type de contrat je dois ajouter à la classe Rectangle pour respecter Liskov.
Pour conclure
Le principe de Liskov apparait donc comme un complément du principe Ouvert-Fermé, il ajoute un aspect fonctionnel qui permet de s’assurer du bon fonctionnement des traitements.
Mais celui-ci va encore plus loin! car il vous permet de déterminer quel doit être la stratégie de gestion des exceptions dans vos applications (surement le sujet d’un post plus tard)…et je parle pas de la co-variance/contra-variance (peut être au cours d’une futur soirée Geek).
Et surtout, on a la puissance de l’API Code Contracts proposé par MS qui est un pur bijoux et permet de répondre parfaitement au défi proposé par Barbara Liskov, l’utiliser c’est réellement l’adopter!
Vous trouverez les sources liées aux posts sur SOLID sur codeplex:http://solidincsharp.codeplex.com/
Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous trouverez l’introducton ainsi que les liens vers les autres articles
ici
.
Définition
“les entités logicielles telles que les classes et les méthodes doivent être ouvertes pour l'extension, mais fermées à la modification.” (Bertrand Meyer)
C’est-à-dire que leur comportement peut être étendu ou bien complètement modifié si elles doivent remplir de nouveaux besoins (ouverte à l’extension) tout en s’assurant que leur code source ne peut pas être directement modifié, aucune modification n’est autorisée (fermé à la modification).
Comment l’appliquer
Après avoir lu cette définition, vous devez vous dire que cela semble contradictoire ! Comment une classe ou une méthode peut être à la fois ouverte pour extension et fermée à la modification ?!
Cela signifie simplement qu’une application doit être structurée de manière à pouvoir ajouter des fonctionnalités en touchant au minimum au code existant. A chaque modification de code, la possibilité de rajouter des bugs existe. Des impacts imprévus peuvent survenir amenant à la modification du comportement de la classe et donc de l’application. L’implémentation devient fragile, difficilement maintenable et sujette aux régressions.
Le principe OCP est également à l’origine de plusieurs bonnes pratiques de développement Objet comme par exemple:
- Les membres (field) d’une classe doivent toutes être privés et non pas public ou encore protected: Lorsque les membres d’une classe changent, chaque fonction qui dépend de ces membres doivent être modifiées. Donc, aucune fonction qui dépend d'un membre public ou protected ne peut être fermé par rapport à ce membre.
- Pas de variables global: même cas que précédement, chaques méthode qui va dépendre d’une variable global ne sera pas fermé par rapport à cette variable.
- Pas d’opération sur les types: cela entraine tres souvent l’impossibilité de fermer une méthode…on le verra dans l’exemple suivant et dans ce cas, il existe certains patterns qui nous assurent un respect du principe
Privilégier ces patterns, c’est éviter les violations du principe OCP!
Exemple!
Passons a un exemple afin de mieux cerner le problème: prenons le cas d’une classe qui écris des messages de Log en base de donnée ou sur un fichier.

1: public class Logger
2: {
3:
4: private TypeLog _typelog;
5:
6: public Logger(TypeLog typelog)
7: {
8: _typelog=typelog;
9: }
10:
11: public void WriteLog(string message)
12: {
13: switch (_typelog)
14: {
15: case TypeLog.File:
16: WriteInFile(message);
17: break;
18: case TypeLog.DataBase:
19: WriteInDataBase(message);
20: break;
21: default:
22: break;
23: }
24: }
25:
26: private void WriteInFile(string message)
27: {//Do stuff
28: }
29:
30: private void WriteInDataBase(string message)
31: {//Do stuff
32: }
33:
34: }
35:
36: public enum TypeLog
37: {
38: File,
39: DataBase
40: }
41:
42:
Le problème étant que si je dois en plus prendre en compte l’écriture via un service distant…on est obligé d’ajouter une valeur à l’énum et de modifier la classe Logger (ajout de la méthode + prise en compte). Bref on viole OCP deux fois.
La solution passe par l’implémentation du pattern Stratey (et un peu d’IoC au passage) comme il suit:

On ne dépend plus que de l’interface ILogger et on injecte dans le constructeur l’objet qui est en charge d’effectuer ce travail. Si on souhaite ajouter une nouvelle stratégie d’écriture de log, on a juste a implémenter l’interface ILogger et ca roule 
La classe logger devient:
1: public class Logger
2: {
3:
4: public ILogger _logger;
5:
6: public Logger(ILogger logger)
7: {
8: _logger= logger;
9: }
10:
11: public void WriteLog(string message)
12: {
13: _logger.WriteLog(message);
14: }
15:
16: }
On a l’interface ILogger:
1: public interface ILogger
2: {
3: void WriteLog(string message);
4: }
ET les loggers:
1: public class FileLogger : ILogger
2: {
3:
4: public void WriteLog(string message)
5: {
6: //do stuff
7: }
8: }
9:
10: public class ServiceLogger : ILogger
11: {
12:
13: public void WriteLog(string message)
14: {
15: //do stuff
16: }
17: }
18:
19:
20: public class DataBaseLogger : ILogger
21: {
22:
23: public void WriteLog(string message)
24: {
25: //do stuff
26: }
27: }
Dans cette exemple, on n’aborde pas la manière de choisir le “bon” logger, on pourrais imaginer dans ce cas une “Abstract Factory” qui aurait donc la charge de cette responsabilité.
Vous trouverez les sources des exemples ici:http://solidincsharp.codeplex.com/
Vous trouverez dans lire “Programmez” de décembre un article écrit par Jason et moi qui présente l’API Code Contracts.

Vous pouvez avoir un aperçu ici et ici.
Dans le même numéro (juste après notre article), vous aurez également le bonheur de lire un article sur la programmation GPU fait par B. Boucard.
Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous trouverez l’introducton ainsi que les liens vers les autres articles ici.
Définition Wikipédia:
In object-oriented programming, the single responsibility principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.
Définition de Robert C. Martin:
A class should have one, and only one, reason to change.
Selon Robert C. Martin, plusieurs responsabilités au sein d’une même classe sont couplées. car tout modification d’une responsabilité impacte la classe et donc toutes les responsabilités qui sont incluses dans cette même classe. En des termes plus simples, une classe doit gérer une responsabilité unique, une responsabilité doit être vu comme un regroupement de fonctionnalités ayant un sens fonctionnel commun.
Appliquer le principe de la responsabilité unique permet d’éviter les défauts de design, de bénéficier d’une meilleure lisibilité du code et d’une meilleure cohésion, d’abaisser le couplage et de garantir l’encapsulation de l’information.
Bien qu’il nous semble plein de bon sens et simple à comprendre, mon expérience ma montré que c’est l’un des principes les moins respecté surtout lorsque l’on maintient une application: combien de fois a t’on ajouté une méthode a une classe sans se demander si il n’est pas préférable d’en créer une nouvelle? ou encore à la fin d’un dev on se dit qu’au final ces deux classe, c’est mieux de les redécouper en trois…Le problème est (a mon sens) plus liée à un manque de recul par rapport au code lorsque l’on est en train de l’écrire plutôt qu’a un niveau de connaissance technique.
Pour bien appliquer ce principe j’ai quelques pistes:
- Avant l’implémentation : il faut au préalable faire une première phase d’analyse en définissant l’ensemble des méthodes nécessaires à la réalisation des fonctionnalités attendues. A ce stade, nous avons une liste de méthodes non organisées entre elles. A partir de cette liste, on va regrouper les méthodes qui répondent à un besoin commun au sein d’une même classe. Il ne faut pas hésiter à créer autant de classes que nécessaires, même si certaines méthodes se retrouvent seules.
- A la fin du développement : demander a quelqu’un de relire votre code pendant que vous relisez le sien
- Lorsque l’on souhaite faire évoluer le code: une nouvelle méthode correspondant à un besoin déjà existant sera rajoutée à la classe correspondante. Par contre, s’il s’agit d’un nouveau besoin on devra créer une nouvelle classe.
Une manière de détecter quelles sont les classes qui ne respectent pas ce principe est par exemple de contrôler le nombre de lignes de code et le nombre de méthodes pour une classe: un trop grand nombre de lignes de code et de méthodes indiquent très souvent un cas de non respect du principe SRP. Un nom de classe trop générique ou pas clair est aussi un signe que ce qui est implémenté dedans vise plusieurs responsabilité.
Exemple d’un design qui ne respecte pas le principe SRP: prenons le cas du pattern Active record appliquer à la gestion des données des utilisateurs d’un logiciel quelconque :

On a ici une classe qui à plusieurs responsabilités distinctes:
- stockage de l’information (nom, prenom, date de naissance,…)
- la persistance en base des informations (méthodes save/update)
- le calcul d’informations (est un utilisateur valide,calcul de l’age)
On va donc couper ca en trois classes distinctes, une par responsabilité…ce qui nous donne ca:

On se retrouve donc avec :
- Une classe (POCO) User pour le stockage et le transport des informations métiers.
- Une classe UserDataAccess qui a pour responsabilité la persistance de ces informations
- Une classe UserInfo qui pour un utilisateur donné vous renvoi les informations calculés liées : l’âge et si il est valide.
Ici, on pourrais se dire que l'âge et la validité répondent à un besoin fonctionnel différent, il est donc préférable au sens SRP de les mettre dans des classes différentes et c’et juste. Par contre, il faut savoir faire la part des choses et ne pas non plus tomber dans un excès qui va nous conduire à avoir trop de classes et donc de baisser la lisibilité. Il faut savoir rester pragmatique: oui on ne respecte pas SRP dans ce cas car on ne souhaite pas démultiplier les classes et parce que nos responsabilités sont “petites” (une seul méthodes). Par contre, si on ajoute une méthode liée à la validation…on n’hésitera pas a couper notre classe.
Vous trouverez les sources des exemples ici:http://solidincsharp.codeplex.com/
Ces derniers temps, j’ai la chance de travailler au sein d’une équipe qui s’est décidé de faire la guerre au code tout pourri…et c’est la que les principes SOLID on fait leur apparition.
Du coup, j’ai le bonheur d’écouter et parfois de participer à des débats enflammés à leur sujet et bien sûr on a le droit à un bonne dose de mauvaise foi; de coup sous la ceinture; de chevilles qui enfles…bref de bonnes tranches de rigolades surtout lorsque l’heure fatidique du “verre” approche (si vous ne voyez pas de quoi je parle, demandez à un de vos amis alcoolique).
J’ai donc décidé de (re) présenter ces principes sur ce blog parce que c’est un sujet que je trouve passionnant et qui m’interresse beaucoup. Mon objectif sera d’utiliser des exemples les plus compréhensibles possible mais sans être complètement déconnecté de la réalité. Je vais également m’appuier sur l’article que j’ai publié à ce sujet sur le magazine Programmez avec Jason De Oliveira.
Je vais donc suivre le plan suivant:
- Présentation générale des principes (ce post)
- présentation des principes:
- Conclusion: concrètement on fait comment?
Pourquoi SOLID?
Lorsque je demande ce qu’il faut pour sortir un logiciel de qualité , j’ai souvent les réponses suivantes:
- faire des tests unitaires
- contrôler la couverture de code
- contrôler les dépendances de nos modules
- contrôler le niveau de commentaires dans le code.
- avoir un bon outil de gestion de sources
- Avoir un bon bug tracker
- utiliser une bonne méthodologie (agile) de conduite de projet
- controler le code (fxcop, styleCop,gendarme…)
- avoir une build pour tout automatiser et tout remonter de manière automatique
Tout ca c’est bien, mais il manque à mon sens une chose importante: la qualité du design!
Aujourd’hui, vous pouvez avoir un code avec une excellente couverture de code, sans erreurs FxCop, bien commenté et s’assurer que vous avez une complexité cyclomatique inférieur à 13 tout plein de metrics qui nous permettent de porter un jugement sur certains aspect du code … et avoir un design calamiteux. pourquoi? parce tout ca manque de cohésion: on a pas de but à atteindre ni de direction à suivre.
Ce que j’éssaie de dire ici, c’est qu’aujourd’hui vous pouvez démarrer un projet avec un super outillage sur deux parties essentiel :
- le “bas niveau” : check du code avec les outils précédement cités
- le “haut niveau” : la conduite de projet avec les méthodologies agiles
Par contre pour ce qui est du niveau intermédiaire la qualité du design (pas du code) : RIEN!
…enfin presque rien, on a tout de même les principes SOLID.
SOLID c’est quoi ?
C’est un ensemble de principe regroupé par Robert C. Martin qui concerne la programmation orienté objet. Le but de ces principes est d’améliorer le design de vos applications et ainsi les rendre plus facilement maintenable et lisible et faciliter les éventuelles évolutions. Ils sont au nombre de 5
- Single Responsibility Principle (Principe de la responsabilité unique)
- Open-Closed Principle (Principe Ouvert-Fermé)
- Liskov Substitution Principle (Principe de substitution de Liskov)
- Interface Segregation Principle (Principe de ségrégation des interfaces)
- Dependency Inversion Principle (Principe d'inversion de dépendance)
Ces principes ne s’intéresse pas au code dans le sens ou il ne vont pas vous imposer de nommer vos variables de tels ou tels manières, de bien commenter votre code, ou encore de rendre toutes vos classes d’exception serialisables. Elles vont plustout vous indiquer quelles sont les erreurs de design qui sont dans votre code et comment les supprimer.
Pour finir (la chose la plus intéressante de ce post), je me permet de copier ce qu’en dit Robert C. Martin sur le site de sa société:
The SOLID principles are not rules. They are not laws. They are not perfect truths. The are statements on the order of “An apple a day keeps the doctor away.” This is a good principle, it is good advice, but it’s not a pure truth, nor is it a rule.
The principles are mental cubby-holes. They give a name to a concept so that you can talk and reason about that concept. They provide a place to hang thefeelings we have about good and bad code. They attempt to categorize those feelings into concrete advice. In that sense, the principles are a kind of anodyne. Given some code or design that you feel bad about, you may be able to find a principle that explains that bad feeling and advises you about how to feel better.
These principles are heuristics. They are common-sense solutions to common problems. They are common-sense disciplines that can help you stay out of trouble. But like any heuristic, they are empirical in nature. They have been observed to work in many cases; but there is no proof that they always work, nor any proof that they should always be followed.
Je vous donne donc rendez-vous sur le prochain post pour parler de SRP!
Vous trouverez les sources des exemples ici:http://solidincsharp.codeplex.com/
J’ai la chance d’être speaker au MS Days de Grenoble qui ont lieu le mardi 07 juin.
La session sera une présentation de la plateforme Azure assortie d’une petite démonstration.
A la suite de cet évènement, je démarrerai certainement une série de post sur Azure afin de partager avec vous autour de cette techno assez surprenante.
Juste un petit post pour vous dire que je viens, avec Jason de publier un article dans le magazine Programmez n. 142:
![image[3] image[3]](http://blogs.developpeur.org/blogs/fathi/image3_thumb_03B31C93.png)
Le but de cet article est de présenter quelques nouveautés incluses dan EF et en particulier l’approche CodeFirst et la nouvelle API: DbContext.
vous trouverez les sources de l’exemple ici: http://codefirst.codeplex.com
Je préfère le dire de suite, ce post à pour seul objectif de s’amuser en codant et il est fort peu probable de retrouver ces lignes de code en production 
Ca fait un bout de temps que je regarde la possibilité d’utiliser les classes dynamiques arrivés depuis C# 4 et franchement, mon esprit ne trouve que des exemples qui n’ont pas grand intérêt.
Du coup, j’en profite pour partager avec vous mes délires de programmeur du jeudi soir en vous montrant ce qu’il est possible de faire avec ces objets.
Un truc chiant lorsque l’on utilise des objets dynamic, c’est que l’on perd l’auto-completion, du coup on est sensible à la case…et ca devient vraiment pénible, je me suis alors demandé si il n’est pas possible de résoudre ce problème…et bien figurer vous que j’ai trouvé!
Je vous montre d’abord le résultat 
J’ai une classe Test qui implémente une UNIQUE méthode dummy:
1: public string DummyMethod()
2: {
3: return "Dummy!";
4: }
et j’exécute le code suivant:
1: Console.WriteLine(t.dummymethod());
2: Console.WriteLine(t.dummyMetHoD());
3: Console.ReadKey();
J’obtient le résultat suivant!

Comment j’ai fait? très simple, il suffit de jeter un œil sur la classe System.Dynamic.DynamicObject.
On y trouve entre autre les méthodes (aux nom explicites ) virtuelles suivantes:
- TryGetMember/TrySetMember
- TryInvoke
- TryInvokeMember
Pour rendre mes appelles case sensitive, il me suffit donc de modifier le code au moment ou il tente d’invoker un membre de ma classe:
1: public class Test: DynamicObject
2: {
3:
4: public string DummyMethod()
5: { return "Dummy!"; }
6:
7: public override bool TryInvokeMember(InvokeMemberBinder binder,
8: object[] args, out object result)
9: {
10:
11: bool retVal = false;
12: result = null;
13: string methodName = binder.Name;
14: var goodMethodInfo= this.GetType().GetMethods().
15: Where(m => m.Name.Equals(methodName,
16: StringComparison.CurrentCultureIgnoreCase)).
17: Single();
18:
19: if (goodMethodInfo!=null)
20: {
21: result = goodMethodInfo.Invoke(this, args);
22: retVal = true;
23: }
24: return retVal;
25: }
26:
27: }
Je récupère le nom de la méthode que je tente d’exécuter. Je cherche la méthode qui à le même nom (en ignorant la casse) que j’exécute dans la foulé et le tour est joué 
Bien sûr, ma classe hérite de DynamicObject et cela n’est pas forcément utile dans un projet réel…mais ca montre bien que derriere les dynamics, se cache pas mal de réflexions.
J’ai la chance de rebosser sur un sujet qui m’a beaucoup intéressé ces dernières années a savoir l’intégration continue (ou plutôt dans mon cas actuel : de la build tout court
).
Et lorsque l’on compile quelque chose d’un peu plus compliqué qu’un projet “hello word”, l’outil incontournable c’est NAnt. Pas besoin de vous faire un long discours dessus, si vous êtes un peu sensible au sujet, vous connaissez certainement NAnt!
le truc vraiment cool avec NAnt, c’est la facilité avec laquelle on peut ajouter des bouts de script custom dans le language que l’on souhaite, on peu:
- créer un “target” custom directement NAnt,
- créer une “task” en C#,
- créer des fonction en C# directement dans le script ou bien dans une dll écrite en C#.
Ainsi, on a la liberté de choisir le langage le mieux adaptés à ce que l’on souhaite faire. Par exemple:
- les opérations sur les string sont plus simples en C#, on va ainsi écrire des fonctions en C# et les utiliser en NAnt,
- par contre, tout ce qui concerne la manipulation de fichiers est plus simple en NAnt, on va donc privilégier du NAnt.
Mais, il y a tout de même quelque chose qui manque dans NAnt: lorsque vous créer des “target”, vous n’avez pas la possibilité de définir des paramètres (comme pour une méthode) et dans ce cas, vous faites souvent un truc comme ca:
<?xml version="1.0"?>
<project name="NAnt Examples" default="main">
<target name="main">
<loadtasks assembly="D:\nant\sandBox\MacroDef.dll" />
<property name="message" value="Hello" />
<call target="printMsg"/>
<property name="message" value="Word" />
<call target="printMsg"/>
</target>
<target name="printMsg">
<echo message="${message}" />
</target>
</project>
lorsque l’on execute NAnt, on a le résultat suivant:

on définit une variable (message) que l’on utilise dans la target chargé d'effectuer le traitement (un simple print)…bref c’est moche.
MacroDef permet de faire la même chose de manière élégante. On va définir un “macro” qui effectue le même traitement et qui défini un paramètre d’entré à notre taret:
<?xml version="1.0"?>
<project name="NAnt Examples" default="main">
<!--Load macro def asm-->
<loadtasks assembly="D:\nant\sandBox\Macrodef.dll" />
<target name="main">
<macroMsg msg="Hello" />
<macroMsg msg="Word" />
</target>
<macrodef name="macroMsg">
<!--Parameters definition-->
<attributes>
<attribute name="msg"/>
</attributes>
<!--Core-->
<sequential>
<echo message="${msg}" />
</sequential>
</macrodef>
</project>
la macro possède les élements suivants:
- un nom (name) de macro (qui sera utilisé lors de l’appel)
- des paramètres (attributes) , une fois définis, ils sont obligatoires
- un traitement que l’on écris en NAnt à l’intérieur des balises sequential.
les appels sont plus clair et propre (pas d’utilisation de paramètres globaux):
<macroMsg msg="Hello" />
<macroMsg msg="Word" />
Le résultat:

have fun!
Comme beaucoup, l’annonce faite par Redgate de rendre payant Reflector m’a beaucoup attristé: après PostSharp, voila encore un manifique bout de code qui devient payant…
Mais voila, la communauté étant ce qu’elle est (très réactive) face à ce genre de changement; je suis tombé sur ce nouvel outil au nom assez singulier: MonoFlector!
L’idée étant d’ajouter une interface graphique à l’outil de reverse ingeenering inclus dans Mono: Cecil Decompiler
Alors, oui il part de loin (de très loin même) par rapport à Reflector et c’est pas demain qu’il va lui arriver à la cheville (mon titre est un poil provoc)…mais je pense qu’il a un bel avenir devant lui!
quelques screen shot pour vous faire “saliver”:

Ca met le code …sans les couleurs

Ca charge uniquement les asm du GAC 
Bref c’est encore le début du bignou…souhaitons leur bon courage pour la suite!
Lors de mes deux derniers posts (ici et ici), j’ai eu l’occasion de parler du framework proposé par Microsoft pour faire du Design by Contract.
J’ai pas abordé des sujets tels que l’analyse statique ou encore toutes les types de contrats possible car cela est déjà très bien documenté et amha le plus important est de savoir en quoi (en terme de design) cet outil à un intérêt dans l’amélioration de nos dev: l’analyse statique est pour moi quelque chose d’excellent et de très utile…mais qui ne n’impacte pas la manière de designer une application.
Parler de CodeContract et ne pas parler de PEX c’est passer à coté de quelque chose d’extremement important lorsque l’on utilise CodeContracts…c’est ce que je vais tenter de vous montrer ici!
Une fois que l’on est convaincu que le DbC est quelque chose d’important et que l’on souhaite utiliser, la premiere question que l’on se pose est :
-“je met quoi moi sur cette méthode comme contrat?”
et la réponse est :
-“bah je vérifie que les paramètres de ma méthodes sont pas nulls”
et si on est très fort, on ajoute:
-“…et je contrôle ma valeur de retour”
Cela est bien sûr un bon début mais pas suffisant, on doit s’assurer de pas mal de choses comme par exemple si les valeurs passés sont valides: par exemple la division par 0; les valeurs limites; etc…
Et c’est la que PEX entre en jeux: il va analyser votre code de manière intelligente et vous sortir un certains nombre de jeux de paramètres et des valeurs de sorties qui y correspondent. du coup vous pourrez voir rapidement si quelques chose cloche…on va voir ca sur un exemple simple et tenter de mieux comprendre comment PEX marche:
Cas simple; la fameuse division:
1: public int Division(int a, int b)
2: {
3: return a / b;
4: }
On execute pex dessus (pour cela, il suffit de faire click droit sur le nom de la methode et faire “run pex”):

On obtient trois jeux de tests:
- le premier nous dit que l’on plante pour une histoire de division par zéro (on s’y attendais)
- le deuxième…bah pas de surprise c’est OK (PEX n’est pas Sylvain Mirouf, il n’est pas capable de comprendre votre code et vous dire que le résultat est ok…c’est a vous de checker)
- le troisème…pas mal, je pense que beaucoup n’y aurais pas pensé (moi le premier).
Un option sympa dans PEX, est le panneau des suggestions; vous le trouverez ici:

et une fois ouvert, vous obtiendrez le résultat suivant:

Et c’est ici que les choses intéressantes commencent:
PEX vous suggère trois choses pour améliorer votre code:
la premère est de vérifier que b n’est pas nulle en utilisant…Code Contracts!!!!!
si vous double clicker sur la target et que vous valider l’insertion…vous obtenez la modification suivante:
1: public int Division(int a, int b)
2: {
3: // <pex>
4: Contract.Requires(b != 0);
5: // </pex>
6:
7:
8: return a / b;
9: }
PEX analyse donc notre code, trouves des failles et insert le contrat qui va bien…no comment BRAVO.
Mais si on se rappel bien: Harry n’était pas un si chic type que ca…
voyons voir les autres suggestions :
1 on évite les valeurs aux limites:
>> Contract.Requires(a != int.MinValue);
OK c’est cool
2

!!! il nous suggère de ne pas accepter la valeur –1!
La raison est simple, le jeux de données qui a fait planter la méthode était le suivant : Int.Max et –1, PEX n’est pas capable de dire (et c’est normal) lequel des deux paramètres est mauvais…du coup, il vous suggère d’interdire les deux.
On doit donc être très prudent et faire bien attention lorsque l’on ajoutes les contrats: notre exemple était simple et avec peu de paramètres, imaginez-vous un cas réel avec des objets en paramètres et des dizaines de lignes de code…on va prendre un cas un peu plus complexe:
1: public int GetValue(List<int> values)
2: {
3: int retVal = 100000;
4: values.ForEach(v => retVal = retVal/v);
5: return retVal;
6:
7: }
On divise un valeur par une liste d”entier, pex nous propose les jeux de données suivants:

PEX a détecter la liste null et deux tests possibles qui aboutissent à une exception (division par zéro)…si on regarde le panneau de suggestion:

PEX perd un peu les pédales:
- les suggestions grisés ne sont pas applicables à notre classe (il propose d’ajouter du code dans le constructeur…mais on en a pas)
- il propose de vérifier que certaines valeurs de la liste ne sont pas nulles
Contract.Requires(values._items[0] != 0);
et
Contract.Requires(values._items[1] != 0);
…pas terrible: en plus ca ajoute un possible bug dans notre code dans le cas ou ma liste ne contient qu’un seul élément (mais un deuxième coup de pex vous le fera voir)
Pour conclure: PEX vous permet de mettre le doigt sur les possibles failles de votre code –ce qui justifie amplement son utilisation!-, il vous suggère également certains contrats pour y remédier pour des cas simple…mais pas pour des cas complexes.
Les 10 derniers blogs postés
-
[PowerShell 3] Télécharger et installer la documentation en ligne par
Blog de SPBrouillet (Pierrick BROUILLET) le il y a 19 heures et 43 minutes
-
[#SharePoint 2010][#SQLServer 2012] AlwaysOn pour SharePoint (1/4) : Configuration (1ère partie)… par
Le blog de Patrick [MVP SharePoint] le 05-16-2012, 12:10
-
Job Day @MIC Brussels - .Net Developers on Mobile applications par
Le Blog (Vert) d'Arnaud JUND le 05-15-2012, 20:26
-
[SharePoint 2010] – SharePoint 2010, Windows (Server) 8 et des erreurs IIS sont dans une VM… par
Blog de SPBrouillet (Pierrick BROUILLET) le 05-14-2012, 12:10
-
[Event] Windows Azure dev Camp le 20 juin! par
Fathi Bellahcene le 05-13-2012, 09:29
-
Comment redimensionner une image avec WinRT : plusieurs solutions par
Richard Clark le 05-11-2012, 15:43
-
Event : Swiss SharePoint Club Meeting #20 à Yverdon par
Blog Technique de Romelard Fabrice le 05-11-2012, 15:24
-
Réflechissons un peu ce matin à propos des ORM par
Richard Clark le 05-11-2012, 08:48
-
#SharePoint Solutions Roadshow le 5 juin à Issy ! par
Le blog de Patrick [MVP SharePoint] le 05-09-2012, 15:10
-
SharePoint : Mes alertes ne marchent pas … Que faire ? Comment réparer ou agir ? par
The Mit's Blog le 05-08-2012, 14:59