Configuration lisible de TimeSpan dans .NET

Jan 29 2023
Les TimeSpan sont une fonctionnalité intéressante de .NET et sont répandus dans tout l'écosystème.

Les TimeSpan sont une fonctionnalité intéressante de .NET et sont répandus dans tout l'écosystème. Mais que se passerait-il si nous pouvions les rendre un peu plus conviviales lorsque nous voulons les définir dans des fichiers de configuration ?

Les TimeSpan sont courants lors de l'écriture de code pour .NET, car ils peuvent servir à une multitude d'objectifs. Quelques exemples de ceux-ci incluent, mais ne sont pas limités à :

  • Définir les temps d'attente/retards
  • Définition des délais d'attente
  • Planifier une tâche pour plus tard
  • Manipuler les dates

Quelques exemples de pourquoi nous voudrions que ces valeurs soient configurables pourraient être…

…Un temps mort ? Peut-être souhaitez-vous que cela soit un peu plus long dans les environnements de test, car vous utilisez des machines moins puissantes et plus lentes.

… planifier une tâche ? Vous voudrez peut-être que cela soit très rapide dans les environnements de test afin de pouvoir affirmer qu'il s'est déclenché, mais plus longtemps dans les environnements de production.

…ou peut-être réagissez-vous simplement aux besoins changeants de votre application.

Alors, comment configurons-nous TimeSpan?

Commençons d'abord par les bibliothèques d'extension Microsoft standard. Microsoft a créé plusieurs packages pour fonctionner avec la configuration, ce qui nous permet de la créer facilement via plusieurs sources, puis de nous fournir diverses API pour récupérer et lier notre configuration à des types forts.

Nous réutiliserons les API IConfigurationBuilder et IConfiguration pour configurer nos TimeSpan dans cet article. Ces API sont utilisées prêtes à l'emploi dans Asp.Net Core par le générateur d'hôtes, vous les connaissez donc peut-être déjà.

Cet article ne se concentrera pas sur ces API en profondeur, donc si vous voulez une explication plus détaillée sur celles-ci, ou pour comprendre comment les utiliser, consultez la documentation de Microsoft.Extensions.Configuration .

Les valeurs de configuration de votre TimeSpan peuvent être stockées via n'importe quelle source de configuration que vous souhaitez. Mais, pour plus de simplicité, et le fait qu'ils ne soient pas "secrets", nous utiliserons les fichiers appsettings.json. Le package dont vous aurez besoin pour cela est Microsoft.Extensions.Configuration.Json

Notre code pour construire cette IConfiguration pour cet exemple est aussi simple que :

ReadableTimeSpan.EnableConfigurationBinding();

var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

Nous pouvons ensuite définir notre TimeSpan dans notre fichier JSON. C'est pris en charge hors de la boîte, dans un format de chaîne, mais ce n'est pas très intuitif à lire.

Prenez ceci par exemple :

{
  "Timeout": "00:01:00"
}

  • Il peut être difficile de savoir ce que cette valeur représente
  • Il est très facile de faire une erreur - l'erreur humaine se produit tout le temps

Pour ceux d'entre vous qui connaissent les formats de chaîne TimeSpan, vous savez peut-être ce que cette valeur représente (pour la transparence, c'est 1 minute), mais pour les développeurs plus juniors ou peu familiers, ce n'est pas si évident.

Cela peut devenir encore plus déroutant si vous voulez commencer à mélanger les jours, les heures, les minutes, les secondes et les millisecondes.

{
  "Timeout": "1.12:10:05.100"
}

ReadableTimeSpanReadableTimeSpan

Pour résoudre ce problème, j'ai créé une bibliothèque appelée ReadableTimeSpan .

Cela vous permet de définir la configuration de TimeSpan dans un format facile à lire et à comprendre. La bibliothèque peut être trouvée sur GitHub àhttps://github.com/thomhurst/ReadableTimeSpan

Pour l'utiliser dans votre projet, ajoutez simplement le package NuGet TomLonghurst.ReadableTimeSpan et avant d'ajouter à votre IConfigurationBuilder, appelez la méthode statique :

ReadableTimeSpan.EnableConfigurationBinding()

Pour le code, c'est tout. C'est super facile à configurer et vous pouvez maintenant commencer à définir des configurations faciles à lire. Il existe des options pour la sténographie ou la sténographie, et divers séparateurs pour distinguer différentes unités. Discutez avec vos pairs de la syntaxe que vous préférez utiliser.

Les options complètes sont disponibles sur le fichier readme de GitHub, mais voici quelques exemples de la manière dont vous pouvez désormais écrire votre configuration :

{
  "Timeout": "1 day and 12 hours and 10 minutes and 5 seconds and 100 milliseconds"
}
{
  "Timeout": "1d + 12h + 10m + 5s + 100ms"
}
{
  "Timeout": "1day|12hr|10mins|5secs|100mils"
}

Liez maintenant votre configuration à vos types forts et utilisez vos TimeSpan !

var timeout = configuration.Get<TestOptions>().Timeout;

Vous pouvez également utiliser ReadableTimeSpan en dehors de la liaison de configuration. Il a des API similaires à la classe TimeSpan habituelle, vous fournissant les méthodes Parse et TryParse.

var timespan = ReadableTimeSpan.Parse("1 sec & 500ms");
if (ReadableTimeSpan.TryParse("1 sec & 500ms", out var timeSpan))
{
    return timeSpan;
}

Si vous devez sérialiser ou désérialiser ReadableTimeSpan à partir de JSON, il existe des packages qui fournissent des convertisseurs pour les sérialiseurs Newtonsoft et System.TextJson.

Ce sont respectivement :

  • TomLonghurst.ReadableTimeSpan.Newtonsoft.Json
  • TomLonghurst.ReadableTimeSpan.System.Text.Json

ToReadableString

En prime, si vous souhaitez générer un TimeSpan dans une chaîne lisible, il existe une méthode d'extension ToReadableString. Cela fonctionne aussi sur les TimeSpan normaux.

var readableString = myTimespan.ToReadableString();

Bien qu'il s'agisse d'une bibliothèque petite et simple, elle a la capacité d'améliorer la lisibilité et de réduire potentiellement les bogues. Si vous l'avez trouvé utile ou intéressant, donnez-lui une étoile sur GitHub, partagez-le et faites-moi part de vos réflexions !