Denpendency Injection with Angular2

Vous aimeriez en savoir un peu plus au sujet d'Angular2 et comment se passe le design pattern d'injection des dépendances avec Angular2. Il me semble que c'est le sujet du moment celui que tous les web développeur aimeraient connaître. Je viens de lire plusieurs posts concernant ce sujet sur d'autres sites.

Le truc le plus marrant que j'ai lu ou vu c'est ça :

ADependency Injection in Angular2

https://pascalprecht.github.io/slides/di-in-angular-2/#/ non n'existe plus !

Claire net précis, ce n'est pas une vidéo, plutôt une présentation animée, rapide ; et c'est Fun, très Fun ! C'est pourquoi j'en prend note ici.

https://angular.io/guide/dependency-injection

Pourquoi faut-il un "framework" d'Injection des dépendances ?

Pour la testabilité. En prod on construira le système avec les "vrais objets" en test on utilisera des Mock Objets c'est à dire des objets avec un comportement spécial de test. Il se trouve que ce Design Patterns d'injection des dépendances est mieux fait en "Angular2", ce que montre cette présentation.

This To Be Continued !

Je viens d'avoir une démonstration de ce design pattern dans une présentation de ASP.NET Core ...

Coder une calculette en C#

Passer le test de la Calculette en C#.NET, on vous a déjà fait le coup ? Pour un recrutement, un poste de développeur, on vous demande d'écrire un programme en C# avec Visual Studio qui fonctionnera comme la calculatrice de Windows. C'est ici !

Coder une Calculatrice Windows en C# - C'est le test de la calculette

Alors permettez que je vous présente ma solution.

Ce code source fonctionne avec toute version de Visual Studio mais cette solution a été développée avec Visual Studio Community 2017.

Visual Studio Community 20017

Cahier des charges de la Calculatrice en C#

On va d'abord se fixer quelques limites dans un mini cahier des charges.

Présentation du projet

Il s’agit d'écrire un programme qui fasse la même chose que la Calculatrice livrée avec Windows, dans sa version "standard". On ne développera pas la version "calculatrice scientifique".

Pour simplifier encore un peu le développement

On ne développera pas le menu, ni l’aide, ni les fonctions suivantes : "Rac", "%", "1/x".
La calculatrice ressemblera donc à ceci :

Maquette de la Calculatrice Windows en C#

Et on va se fixer un temps limite développement du projet disons 4 heures.

Livraison du projet

Ecrire l'application comme s'il s'agissait d'une "vraie" application professionnelle, en vue d'être commercialisée.

Le code source de l'application doit être fourni, sous la forme d'un fichier .ZIP contenant le répertoire complet du projet C#.

Le projet en C#

Choix du Template de départ : Application Windows Forms (.NET Framework)
Donc on y a va, on fait : Ficher->Nouveau->Projet, on choisi :

Solution Visual Studio Calculette

Structure de la solution du projet :

Structure de la Solution Calculatrice

On verra que l'on va utiliser deux objets. La Form s'appelle FormCalculatrice et j'ai ajouté un petit fichier "readme.txt" ça fait plus pro. On peut y écrire par exemple l'historique du développement ou une ToDoList des chose qu'il reste à faire.

Conception Objet de la Calculatrice

On a besoin de deux objets, l'un pour effectuer le Calcul, l'autre pour gérer les fonctions Mémoires.

Objet Calcul

Vous trouverez les sources en bas de cet article, je ne vais donc pas trop détailler mais simplement on imagine que l'objet Calcul.cs prendra 3 états :

Les trois états de l'objet Calcul.cs

Objet Memoire ou Memory

Vous rappelez-vous à quoi servent les touches mémoires de la Calculatrice ?

MC : Memory Clear
MR : Memory Read
MS : Memory Save
M+ : Memory Add

Heureusement, j'avais un bon vieux Windows XP sous la main, il est vrai pour l'instant que l'aspect de cette calculatrice ressemble plus à celle de Windows XP qu'à celle de Windows 10... en tous les cas celle que j'ai sous Windows 7 ne me présente plus l'aide de la Calculette Windows et son aspect est très différent mais restons à nos moutons.

Il m'a suffit de faire "bouton droit" sur la touche et de Cliquer sur "Qu'est ce que c'est ?" pour obtenir la réponse :

Calculatrice en C# Trouver les fonctions mémoires

L'application Calculatrice m'affiche maintenant la réponse à quoi sert la touche "MC" :

Calculatrice fonctions mémoires

Voici l'aide correspondante à la touche "MC" de la Calculatrice. L'objet mémoire aura donc trois états :

Les trois états de l'objet Memory.cs

Conception de l'IHM

Aujourd'hui on dit UI ou UX bref, elle nous est donnée donc on copie au plus prêt :

Windows Forms de la Calculatrice

Il faut un outil de graphiste pour trouver la taille des boutons en pixels, je vous donne le résultat :
  • Width : 35
  • Height : 25

Programme principal de la Calculette

Pour la Testabilité & Evolution tous les boutons "chiffre" sont câblés sur la même gestion d'events :

buttonNumber_Click()

Tous les boutons "Operands" sont également câblés ainsi :

buttonOperand_Click()

On y gère l'état de l'objet "Calcul" qui passe de AquireOperand1 à BeginAquireOperand2

Enfin la gestion de l'events clique sur "Equal" qui exécute le calcul en utilisant l'Opérand1 et l'Opérande2 :

buttonEqual_Click()

Qui prend en compte le fonctionnement particulier de la Calculette comme par exemple lorsque le résultat du calcul précédent devient l'Opérande1 pour le calcul suivant.

Je vous laisse découvrir le reste des codes sources dans le .ZIP à télécharger à la fin de cet article.

Gestion des touches tapées au clavier dans la Calculette

La Calculatrice Windows est utilisable au clavier numérique pad et touches d'opérations. Pour faire la même chose dans notre Calculette nous allons cabler l'event KeyPress de la Form :

FormCalculatrice_KeyPress()

Code source de la fonction FormCalculatrice_KeyPress()

FormCalculatrice_KeyPress()

Astuce concernant la gestion des touches du clavier

Si vous en restez là, cela ne fonctionne pas. En effet il faut passer l'event à la Form sinon elle ne le gère pas. Pour ce faire il faut setter la propriété "KeyPreview" de la Form à True.

Pour gérer les événements clavier mettre à True la propriété KeyPreview

Conclusion

Voilà c'est fini ! En gros les grandes parties de ce petit projet "Test de la Calculette Windows". Qui n'est finalement pas si petit.

C'est vraiment désobligeant quand on vous demande d'effectuer ce genre de test pendant l'entretien d'embauche alors que vous avez une expérience comme la mienne en développement de logiciel.

Que même s'il existe un "mini" cahier des charges les pièges sont nombreux et vous ne manquerez pas de tomber dedans. Donc j'espère avoir cassé les pattes de ces recruteurs peu scrupuleux.

La prochaine fois nous verrons comment coder une calculette en WPF avec le modèle MVVM (Model View ViewModel) de Prims et l'utilisation d'un EventToCommand.

Ou peut-être que l'on choisira ASP.NET avec le modèle MVC (Model View Controller) pour en faire une application Web, ou bien en faire une application Multi-plateforme avec ASP.NET Core et Angular2.

Revenez nous voir.

Download calculator sources code

Here on github :


Here you can find Calculator sources code 

Download Source Code - Calculator in C#

Have fun! Don't forget to go to the beach!

Statistiques over years

2017 : 1826 visites
22/10/2018 : 2294
22/06/2019 : 3944 quel succès apparemment le sujet vous intéresse.
24/11/2020 : 7140 bientôt tout le monde saura coder une calculette.
17/11/2022 : 13302

En 2022, j'ai pu exécuter les sources sur ma machine Windows 10 avec Visual Studio Community 2019.

Cet article vous a plu vous a aidé dans votre pratique de développeur, surtout laissez-moi votre commentaire.

Même, juste un petit merci, would be please ;) 

En C#, utiliser des Propriétés ou des Attributs et pourquoi ?

Je ne suis pas sûr de moi, je ne sais plus au fait pourquoi je déclare les propriétés publiques d'un objet à la façon snypet "propfull" alors que je pourrais utiliser un champ. Je cherche la réponse la plus pertinente et ce matin je tombe sur l'article suivant :

Développez.com .NET C# Propriété ou attribut ? Pourquoi ?
Développez.com .NET C# Propriété ou attribut ? Pourquoi ?

Je me dis alors que cela vaut le coup que je le lise ... Mais il est bien long alors résumons. Il s'agit donc bien de comparer les deux écritures de codes suivantes :

class Test
{
    public int MonChamp;
}

Et :

class Test
{
    private int _monAttributPrivé;

    public int MaPropriété
    {
        get
        {
            return _monAttributPrivé;
        }
        set
        {
            _monAttributPrivé = value;
        }
    }
}

Quelles sont les différences ? Bon, je me tape tout l'article et croyez moi ce n'est pas une sinécure. Pour finalement me dire que la deuxième écriture prépare mieux mon composant à de futures évolutions comme par exemple :

private int myProperty;
public int MyProperty {
     get { return this.myProperty; }
     set { this.myProperty = value < 0 ? 0 : value; }
}

Mais encore ? On nous dit qu'en cas d’utilisation de la sérialisation XML seules les propriétés des classes sont considérées les champs ne le sont pas.

Lors de la transformation d'un champ en propriétés les assemblys dépendantes seront affectés si elles n'ont pas été recompilées et affectera évidemment tout procédé utilisant la réflexion.

Pourquoi les propriétés plutôt que les champs ?

Heureusement, tout en bas "Guulh" qui devait être un peu énervé de voir cette discussion s'éterniser sans réelle bonne réponse fini par écrire :

Donc, pourquoi les propriétés plutôt que les champs ?

Ca m'épate qu'on puisse vouloir se passer volontairement des propriétés automatiques... Si on commence à dire qu'on veut garder des champs privés "parce que ça peut servir", alors autant remettre le constructeur par défaut "parce que ça peut servir", autant implémenter IDIsposable "parce que ça peut servir", autant définir explicitement add/remove sur les event pour la même raison. 

Parce qu'on ne peut pas définir de champ dans une interface
Parce qu'on ne peut pas rendre un champ virtuel
Parce que plein d'API faisant appel à la réflexion (sérialisation, binding, ...) ne gère que les properies et pas les champs
Parce que c'est un breaking change et donc une lib_B qui référence A ne marchera plus sans être recompilée si un champ de A devient une propriété
Parce que d'un point de vue perf, on s'en fout, c'est le jitter qui se chargera d'inlier tout ça
Parce que ça montre bien qu'une classe, en tant qu'unité d'encapsulation, ne donne jamais accès à son état interne sans se laisser la possibilité de valider/notifier/whatever
Parce que ça normalise ce qu'expose une classe/une interface: des propriétés, des méthodes, des events, et c'est tout.
Parce que c'est le standard, et que si chacun fait à sa sauce pour ce genre de choix consensuel, ça engendre un surcoût projet inutile en temps d'adaptation, de refactoring, etc ...

Pourquoi les propriétés automatiques plutôt que les propriétés manuelles (dans le cas of course où on fait rien dans le get set)
Moins verbeux!
pas de problématique de convention de nommage (je mets un underscore? une minuscule? du hongrois?
parce que l'intellisense n'est pas pollué à l'intérieur de la classe par deux fois plus de tokens que nécessaire

Bravo Guulh !

Conclusion

Il s'agit bien de prévoir l'évolution de notre Classe composant, c'est une bonne raison pour utiliser des propriétés plutôt que des champs.

Ne trouvez-vous pas ?

Merci de me laissez votre commentaire.