Carl de Billy
Tout ce que vous voulez de Carl, ou presque.
Carl de Billy
Navigation
  • Carl, le gars…
  • Parcours professionnel
You are here: Home › .NET › nventive se met à l’Open-Source et c’est très cool!

nventive se met à l’Open-Source et c’est très cool!

2018-02-11 | Filed under: .NET, Développement, Open-Source, Windows 10 and tagged with: .Net Framework, nventive, Roslyn, Uno

Au cours des derniers jours, j’ai personnellement participé à la publication en open-source de code qu’on a depuis un certain temps chez nventive. Et c’est très cool!

Ce n’est pas la première fois que nventive publie en open-source, mais la dernière fois, ça remonte quand même à longtemps où Umbrella v0.9 avait été publié.

Uno – le nom de l’Open-Source chez nventive

Tout d’abord, il faut savoir que tout ce qui est publié ou le deviendra sera sous le nom « Uno« . C’est le nom qui a été choisi pour tout ce qui est open-source. Le nom Umbrella existe toujours mais est plutôt utilisé pour les projets internes désormais.

Pour le moment, nous avons publié 4 projets:

  • Uno.Core : Une libraire qui contient BEAUCOUP de stock. Ce sont un grand nombre de petits utilitaires pour vous faciliter la vie avec .NET. Allant de simples extension methods jusqu’aux outils de gestion de concurrence (threading), en passant par le logging, bien sûr!
    NuGet
    Frameworks: .NETStandard 2.0, .NETFramework 4.6 & UAP 10.0
  • Uno.SourceGeneration : Ça, c’est big. Ou, plutôt, ça permet de faire des choses big : nventive a réussi à mettre dans un seul package tout ce qui est nécessaire pour coder un GÉRÉNATEUR DE CODE avec Roslyn.
    NuGet
    Frameworks: .NETFramework 4.6 (ça roule dans Roslyn!)

  • Uno.RoslynHelpers : Petit projet qui a pour but de fournir des outils pour faciliter l’écriture de code Roslyn. C’est vraiment tout petit et ce n’est absolument pas nécessaire pour créer un générateur de code en utilisant Uno.SourceGeneration.
    NuGet
    Frameworks: .NETFramework 4.6 (ça roule dans _Roslyn!)

  • Uno.CodeGen : Ça, c’est mon bébé. Une première version fonctionnelle devrait être disponible dans les prochains jours. Il s’agit d’un générateur de code (qui utilise Uno.SourceGeneration) qui permet de faciliter l’écriture d’ENTITÉES IMMUABLES et de la GESTION D’ÉGALITÉ dans votre code C#. Voir un exemple de code ci-bas.

    NuGet
    Frameworks: .NETFramework 4.6 (ça roule dans _Roslyn!)

Uno.SourceGeneration

Pour créer un générateur de source, suivre les étapes suivantes :

  1. Créer un projet de type librairie en .net 4.6
  2. Ajouter une référence nuget à Uno.SourceGeneration.
  3. Faire les modifications dans les fichier .csproj tel que décrit sur la page github
  4. Créer une classe publique qui hérite de SourceGenerator. Ne pas mettre de constructeur, elle sera créée automatiquement par les tâches MSBuild de génération.
  5. Utilisez le context reçu en paramètre pour analyser le projet existant et générer du code.

Fonctionnement des tâches de génération

Des tâches spéciales s’injectent dans le processus de MsBuild pour intercepter certaines opérations. Roslyn est utilisé intensivement pour l’analyze des sources, bien sûr!

  1. Tout d’abord, les tâches de génération vont charger les différents générateurs et identifier l’ordre d’exécution. En effet, les attributs [GenerateBefore] et [GenerateAfter] permettent de spécifier des dépendances entre les générateurs. Ça permet d’effectuer une génération basée sur le résultat compilé d’une autre, ce qui peut être très pratique.
  2. Ensuite, Roslyn est utilisé pour compiler le code du projet.
  3. Le résultat de la compilation (partielle ou complète, selon s’il y a des erreurs) sera passé au générateur.
  4. Le générateur produira du code qui sera à son tour intégré à la compilation. Les fichiers de code générés seront également copiés sur disque pour la vraie compilation.

À savoir…

  • Dans la version actuelle, il faut une première compilation pour que le code généré soit disponible pour l’auto-complete de VisualStudio. Quelques fois il faut le forcer un peu. Nous travaillons actuellement à enlever cette limitation.
  • Il n’est pas possible de modifier du code, on peut simplement en ajouter. Le plus simple est généralement à travers des classes partielles. Par modifier, je veux dire qu’il n’est pas possible de faire ne sorte d’enlever du code analysé par Roslyn. Vous pouvez ajouter du code à la compilation, mais pas en enlever.
  • Une protection a été mise en place pour empêcher une recompilation de tout les projets dès que ces derniers ont un générateur. Si la compilation est identique à la compilation précédente, le fichier sur disque n’est pas remplacé, ce qui permet à MsBuild de ne pas recompiler inutilement le projet. Il va sans dire qu’il est nécessaire que votre générateur produise toujours le même résultant. Bref, évitez de mettre la date ou l’heure dans le code généré.

Uno.CodeGen

Le projet Uno.CodeGen est un regroupement des différents générateurs de code qui seront développés pour le Projet Uno. Pour le moment, il y a 2 générateurs :

  • ImmutableGenerator : Utilisé pour simplifier le code d’entités immuables.
  • EqualityGenerator : Utilisé pour automatiser le code nécessaire pour implémenter le .Equals(), .GetHashCode() et implémenter les interfaces IEquatable<t>, IKeyEquatable et IKeyEquatable</t><t>.

Ces 2 générateurs ont été mis en place pour diminuer les erreurs dûs à la répétition du code nécessaire pour effectuer ces fonctions.

Normalement vous devriez être en train de vous demander c’est quoi les interfaces IKeyEquatable et IKeyEquatable</t><t>. Il s’agit simplement des interfaces définies dans Uno.Core et qui servent à comparer les clés de 2 entités. Une version mise à jour d’une entité aura une équalité de clé (key equals) alors qu’elles ne seront pas equals.

Le code pour l’égalité de clé ne sera généré que si vous utilisez Uno.Core.

Le générateur d’entités immuables

Qu’est-ce qu’une entité immuable ? C’est une entité qui ne peut pas changer après sa création. Si vous voulez la modifier, vous devez en créer une nouvelle instance qui contient la modification. Travailler avec des entités immuables apporte un bon nombre d’avantages, spécialement quand on fait du code fonctionnel et du multi-threading.

Pour définir une entité immuable, voici d’abord les requis:

  1. Doit être une classe (les struct ne sont pas acceptés).
  2. Aucun champ (field) non-static n’est autorisé.
  3. Toutes les propriétés non-statiques doit être { get; } sans aucun setter de défini. Vous pouvez mettre des valeurs par défaut, ex:
    public string City { get; } = "Unknown";
  4. Le constructeur par défaut n’est pas autorisé. D’ailleurs vous n’avez pas besoin d’en définir un (c’est permis, toutefois).
  5. Vous devez ajouter l’attribut [GenerateImmutable] sur la classe.

Seront générés pour vous :
* Une classe T.Builder, soit un builder muable pour votre classe.
* Une propriétée statique T.Default qui contiendra une version par défaut de votre classe.
* Chaque propriété sera copiée dans le builder pour en avoir une version modifiable.
* Des méthodes .WithXXX() seront générés pour chaque propriétés (où XXX est remplacé par le nom de la propriété), permettant de manière fluente de modifier l’état du builder.
* Des méthodes d’extension sur la classe originale permettront également de faire .WithXXX() et d’obtenir un builder. Il s’agit de méthodes d’extension pour éviter un « null reference exception » quand la source est null.
* Des conversions implicites de T vers T.Builder et inversement.

Voici un exemple de code :

[GenerateImmutable]
public class User
{
    public string Id { get; } = "";
        public string Email { get; } = null;
        public string Name { get; } = "Unknown";
}

[...]
// On peut d'abord utiliser le .Default
// qui donne les valeurs par défaut des propriétés
User u1 = User.Default;

// On peut aussi créer à partir du builder
User u2 = new User.Builder { Id = "123", Email="a@b.c" };

// Pour obtenir une version modifiée, utilisez les .WithXXX()
User u2bis = u2.WithName("Jean Dit");

// Il y a aussi des optimisations qui permettent
// de chaîner les .WithXXX() sans que les entités
// intermédiaires ne soient crées...
User u3 = User.Builder
    .WithId("234")
        .WithEmail("t@v.com")
        .WithName("Aristote");

Le générateur d’égalité

Le générateur d’égalité a un fonctionnement similaire au générateur d’entités immuables, c’est-à-dire qu’il suffit d’ajouter un attribut pour le déclencher.

Il peut être utilisé autant sur une class que sur une struct. Bien que l’immuabilité ne soit pas requis, idéalement ses membres ne devraient pas changer ou les résultats pourraient devenir étranges.

Voici les requis :

  1. Au moins une propriété (ou champ) devrait avoir l’attribut [EqualityHash] or [EqualityKey], sinon le HashCode aura toujours la même valeur.
  2. Éviter des types dont les valeurs exposées sont non-constants comme des IEnumerable</t><t>

À vos risques

Je crois qu’il est important de rappeler qu’il s’agit de code qui n’est couvert par aucune garantie de quelque manière que ce soit. Je ne peux garantir que le code présenté dans cet article fonctionnera avec les versions futures.

Cependant, comme vous avez accès aux sources, libre à vous de le forker et d’en faire ce que vous voulez – tant que vous respectez la license.

Faites-nous des commentaires!

Les PULL-REQUESTS sont acceptés. Si vous voyez des problèmes avec le code publié ou souhaitez faire des amélioration, n’hésitez pas, c’est là pour ça!

Did you like this article? Share it with your friends!

Tweet

Written by cdebilly

Laisser un commentaire Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Catégories

  • .NET
  • Développement
  • Internet
  • Javascript
  • NFC
  • Non catégorisé
  • Open-Source
  • Reactive Extension
  • Silverlight
  • Téléphonie
  • Windows 10
  • Windows 8
  • Windows Phone 8
  • Windows Server 2012
  • WPF

Archives

  • février 2018
  • janvier 2015
  • juin 2014
  • novembre 2013
  • octobre 2013
  • avril 2013
  • février 2013
  • novembre 2012
  • octobre 2012
  • avril 2012
  • septembre 2011
  • juillet 2011
  • février 2011
  • janvier 2011
  • novembre 2010
  • septembre 2010
  • août 2010

Bookmark or Pin us!

Carl de Billy supports many popular operating systems!

Supported platforms include:

  • FavIcons for desktop and mobile browsers
  • Windows 8 and Windows Phone 8.1 Live Tiles
  • iOS Home Screen Icons
  • iOS WebApp

Tags

.Net Framework 3g ADSL autocomplete C# Communauto contrat numérique css foursquare hadopi HoloLens internet IObservable jquery Microsoft Montréal ndef nfc nventive Observable Pixel shader RAID Reactive Extension Roslyn Rx rxjs semantic silverlight smartposter Storage Spaces styling tags Teksavvy telephonie Uno videotron Visual Studio web Windows 8 Windows 10 Windows Phone WP7

Navigation

  • Inscription
  • Connexion
  • Flux des publications
  • Flux des commentaires
  • Site de WordPress-FR

Mastodon

© 2025 Carl de Billy

Powered by Esplanade Theme and WordPress