Partager via


Cet article a fait l'objet d'une traduction automatique.

À la pointe

Regard sur ClearScript

Dino Esposito

Téléchargez l'exemple de Code

Dino EspositoAns, j'étais fasciné par la perspective d'accueillir l'ensemble moteur VBScript de pages Active Server dans une application de Visual Basic. Je pourrais créer une étonnante preuve de concept pour une société disposée à vendre du contenu rédactionnel sur CD qui pourrait réutiliser le contenu de pages Active Server existant aux abords de serveurs Web locaux ou distants.

C'était la fin des années 1990. Il n'y n'avait aucun Microsoft .NET Framework. Il n'y n'avait aucun HTML5. Seulement quelques uns d'entre nous ont été activement explorer les profondeurs du HTML dynamique, pourtant le moteur de script d'hébergement ne pouvaient pas été plus facile. J'ai dû faire référence à un contrôle ActiveX , publier mes objets ActiveX dans l'environnement de script et j'étais prêt à aller.

Plus récemment, un client m'a interrogé sur la façon la plus efficace pour extraire les fichiers texte de requêtes SQL Server . Cette question a été à l'extérieur de la gamme habituelle des sujets à que traiter, donc j'ai été tenté de répondre avec quelque chose comme: « Désolé, je ne sais pas. » Cependant, je savais que ce client était fort dans les opérations de base de données. Je me doutais bien qu'il n'y avait plus de fond derrière la question.

Le client a été régulièrement produisant des fichiers de texte brut (pour la plupart des fichiers CSV et XML) de contenu stocké dans les tables de la base de données dans une instance de SQL Server. Cela gênait son personnel de la base de données, comme les demandes venaient pour la plupart d'entreprise avec la rapidité habituelle de questions commerciales. Il n'y n'avait aucune logique récurrente qui pourrait aider à créer des routines reproductibles — au moins dans un environnement de SQL Server.

En fin de compte, le client recherchait une entreprise outil personnes pouvait programmer à l'aide de langages de script simple tel que VBScript. Les utilisateurs nécessaires accès contrôlé aux bases de données à des fins de lecture seule. Inutile de préciser que l'outil était d'offrir aux utilisateurs une chance de créer facilement des fichiers texte. Cela me rappelait les jours heureux des ActiveX et VBScript. J'ai presque eu une vague de regret quand j'ai entendu parler une relativement nouvelle bibliothèque nommée ClearScript (clearscript.codeplex.com).

Intégrer ClearScript Windows Presentation Foundation

ClearScript vous permet d'ajouter des fonctionnalités de script à une application .NET (aussi longtemps qu'il utilise le .NET Framework 4 ou supérieur). ClearScript prend en charge VBScript, JavaScript et V8. V8 est un moteur de JavaScript open source créé par Google et intégré avec Chrome. V8 dispose d'un moteur JavaScript de haute performance et s'intègre bien dans les scénarios de fonctionnement multi-threading et asynchrone.

L'effet net de l'ajout de ClearScript à une application .NET est vous pouvez passer des expressions JavaScript ou VBScript pour le moteur et ils vont être traitées et exécuter. Fait intéressant, vous n'êtes pas limité à l'utilisation des objets de script ordinaire tels que les tableaux, les objets JSON et les types primitifs. Vous pouvez intégrer des bibliothèques JavaScript externes et les objets .NET gérés par script.

Une fois que vous avez intégrées ClearScript dans une application, reste plus qu'à informer la bibliothèque sur les objets, il peut le script. Cela signifie que vous publiez vos propres objets dans le contexte de ClearScript et permettent aux utilisateurs autorisés de charger et exécuter des scripts existants ou écrire de nouveaux.

Si vous souhaitez ajouter une couche de personnalisation et de laisser l'utilisateur à ajouter des morceaux de sa propre logique sans encourir les coûts des demandes de changement, alors ClearScript est nécessaire, mais il pourrait ne pas suffire. ClearScript est qu'une pièce du puzzle. Vous pouvez fournir un moyen pour l'utilisateur de gérer ses propres scripts. En outre, vous devez créer quelques objets ad hoc qui simplifient les tâches courantes comme la création de fichiers.

Voici ce que j'ai fait pour aider un client à générer à partir d'un tas de services exposés via un back-end Web API texte et XML rapports. La principale exigence fonctionnelle était de permettre aux utilisateurs de créer des fichiers texte. Pour la preuve de concept, j'avais besoin d'une application de shell à l'hôte ClearScript. J'ai opté pour une application de Windows Presentation Foundation (WPF) avec un textbox pour saisir manuellement le code de script. Les itérations successives ajouté le support pour un dossier d'entrée par défaut et une interface utilisateur pour ouvrir/importer des fichiers de script existants. Figure 1 montre l'exemple d'application WPF en action.

exemple d'Application Windows Presentation Foundation hébergement du moteur de ClearScript
Figure 1 exemple d'Application Windows Presentation Foundation hébergement du moteur de ClearScript

Encore une fois, ClearScript est un projet open source, que vous pouvez référencer directement dans votre projet en associant des assemblys. Vous pouvez naviguer sur les paquets de tierce partie de NuGet, comme le montre Figure 2.

vous pouvez installer ClearScript via NuGet
La figure 2 vous pouvez installer ClearScript via NuGet

Initialiser ClearScript

Vous aurez à faire quelques travaux avant que vous pouvez utiliser le moteur de script par programme. Mais à la fin de la journée, une fois il est complètement mis en place, le code dans Figure 3 est suffisant pour déclencher l'exécution de code de script.

Figure 3 Code de Code de Script de déclenchement

public void Confirm()
{
  try
  {
    SonoraConsole.ScriptEngine.Execute(Command);
    OutputText = SonoraConsole.Output.ToString();
  }
  catch(Exception e)
  {
    OutputText = e.Message;
  }
}

La méthode Confirm appartient à la classe presenter supportant l'affichage principal de l'exemple d'application. Déclencher la méthode par tout clic sur le bouton Exécuter (visible dans Figure 1). La classe de SonoraConsole que vous voir référencée dans la liste est juste ma propre wrapper autour les classes principales de la bibliothèque de ClearScript.

L'initialisation du moteur de ClearScript se produit lorsque l'application démarre et s'est liée à l'événement Startup de la classe Application XAML :

public partial class App : Application
{
  void Application_Startup(Object sender, StartupEventArgs e)
  {
    SonoraConsole.Initialize();
  }
}

L'initialisation peut être aussi complexe et sophistiqué comme vous voulez, mais il a au moins initialiser le moteur de script de votre langue sélectionnée. Vous devez mettre à la disposition des autres parties de la demande l'instance du moteur de script. Voici une approche possible :

public class SonoraConsole
{
   public static void Initialize()
   {
     ScriptEngine = new VBScriptEngine()
   }
   public static ScriptEngine ScriptEngine { get; private set; }
   ...
}

Vous pouvez lire le fichier de configuration quel langage de script, vous devez activer l'application. Il s'agit d'un schéma de configuration possibles :

<appSettings>
  <add key="language" value="vb" />
</appSettings>

Une fois que vous avez une instance de votre moteur de script choisie prêt, vous pouvez exécuter tout code JavaScript (ou VBScript) valide. Il n'est pas que vous pouvez faire dans un scénario réel, jusqu'à ce que vous êtes armé avec ces fonctions de base.

Ajouter des objets scriptables

Tous les moteurs de ClearScript exposent une interface programmable grâce auquel vous pouvez ajouter des objets scriptables à l'environnement d'exécution. En particulier, vous utilisez la méthode AddHostObject, comme suit :

ScriptEngine.AddHostObject("out", new SonoraOutput(settings));
ScriptEngine.AddHostObject("xml", new XmlFacade());

Cette méthode requiert deux paramètres. Le premier paramètre est que les scripteurs nom public utilisera pour référencer l'objet en cours de publication. Le second paramètre est l'instance d'objet. En regardant à l'extrait de code précédent, dans n'importe quel JavaScript ou VBScript, vous pouvez utiliser le nom « out » pour appeler des méthodes publiques disponibles sur l'interface SonoraOutput. Voici un exemple en JavaScript qui fait référence à ce qui est montré dans Figure 1:

var x = 4;
out.print(x + 1);

Comme vous le savez peut-être, c'est une pratique courante en JavaScript aux membres de nom selon la convention de camelCase. Dans la programmation .NET, la convention de PascalCase est plus fréquent et aussi recommandé. Dans mon implémentation de la classe SonoraOutput, j'ai délibérément choisi de suivre la convention de JavaScript et appelle la méthode impression au lieu d'imprimer, comme ce serait le cas dans la plaine de programmation c#.

Selon mon expérience, il n'est pas beaucoup plus que vous devez savoir et comprendre pour commencer sur ClearScript. La plupart du temps, vous pouvez configurer un environnement de ClearScript au sein d'une application hôte dans le but essentiel de faire des objets spécifiques à l'application disponibles. Plus souvent qu'autrement, ces sont des objets sur mesure enroulées autour des objets d'affaires existants et rendu plus agréable à utiliser à partir d'un environnement de script.

Les principaux utilisateurs d'un environnement de ClearScript ne sont généralement pas des développeurs à temps plein. Ce sont des gens très probables avec certaines compétences développement doux qui trouveraient inutilement complexe et ennuyeux pour faire face à tous les détails des classes .NET. ClearScript vous permet d'exposer les gros morceaux du .NET Framework directement à JavaScript et VBScript. J'ai opté pour que les objets sur mesure conçus pour une simplicité extrême. Voici comment vous pouvez publier dans ClearScript un type au lieu d'un objet :

ScriptEngine.AddHostType("dt", typeof(DateTime));

Lorsque vous référencez un type, vous donnez aux utilisateurs le pouvoir de créer par programme des instances de ce type. Par exemple, la ligne de code précédente ajoute la puissance de l'objet DateTime .NET à l'environnement de script. Maintenant, le code JavaScript suivant devient possible :

var date = new dt(1998, 5, 20);
date = date.AddDays(1000);
out.print(date)

Partir du code JavaScript, vous prenez parti de toute la puissance des méthodes telles que AddDays et AddHours. Que se passe-t-il si vous souhaitez obtenir la différence entre deux dates ? Vous pouvez faire quelque chose comme ceci :

var date1 = new dt(1998, 5, 20);
var date2 = date1.AddDays(1000);
var span = date2.Subtract(date1);
out.print(span.Days)

Le TimeSpan objet est géré correctement et l'étendue de l'expression.Jours justes retours 1000. C'est en raison de la nature dynamique du langage JavaScript, qui détermine dynamiquement l'objet nommé "span" expose un membre nommé jours. Si vous souhaitez créer une instance de TimeSpan au lieu de cela, vous devez première laissez le moteur savoir qu'il est là.

Pour éviter d'exposer les 1 million de différents types, ClearScript vous permet d'héberger un assembly entier. Il s'agit d'une approche possible :

ScriptEngine.AddHostObject("dotnet",
  new HostTypeCollection("mscorlib", "System.Core"));

Le mot clé dotnet devient maintenant la clé pour accéder à n'importe quel types et les membres statiques dans mscorlib et System.Core. Créer un objet date nouvelle prend un peu plus longtemps, mais en contrepartie vous pouvez explicitement de travailler avec des objets TimeSpan :

var date1 = new dotnet.System.DateTime(1998, 5, 20);
var ts1 = new dotnet.System.TimeSpan(24, 0, 0);
var ts2 = ts1.Add(new dotnet.System.TimeSpan(24, 0, 0));
out.print(ts2.Days);

L'extrait de code JavaScript imprime le numéro 2, résultant de la somme des deux TimeSpan distincts des objets chaque comptage pendant 24 heures. Une chose qui ne fonctionne pas bien avec ClearScript est la surcharge d'opérateur. Qui n'existe simplement pas. Cela signifie que pour résumer de dates ou battues, vous devez utiliser des méthodes telles que Add ou soustraction. Il prend également en charge la réflexion.

Générer la sortie

L'outil que vous voyez dans Figure 1 doit être capable d'afficher des résultats à l'utilisateur. Par défaut, l'objet de SonoraOutput ajouté au moteur ClearScript juste maintient un objet StringWriter interne. Tous les textes, traités par la méthode d'impression sont écrite dans le writer sous-jacent. Le contenu de l'écrivain est exposé au monde extérieur par l'intermédiaire de la classe SonoraConsole. Cette classe est le seul point de contact entre le moteur de ClearScript et de l'application hôte. Le présentateur d'application hôte retourne seulement le contenu de l'écrivain de chaîne via une propriété. Cette propriété est alors liée à un TextBlock dans l'UI WPF. La méthode print écrit dans l'interface utilisateur par l'intermédiaire de l'écrivain de la chaîne. Le Common Language Runtime de la méthode efface la mémoire tampon et l'interface utilisateur.

Enregistrer dans un fichier texte

Mon client avait besoin seulement de créer des fichiers de texte, pour la plupart des fichiers CSV. C'est relativement facile à réaliser. Je n'ai fait créer une méthode de fichier et passez-lui un contenu de texte directement. Je pouvais aussi laisser saisir quoi que ce soit déjà imprimé à l'écran et enregistré dans la mémoire tampon interne. L'aspect le plus problématique à traiter quand il s'agit de fichiers est le nom et l'emplacement. Pour faire des scripts très vite, il doit être trivialement facile créer et récupérer des fichiers. J'ai réussi à avoir deux dossiers par défaut — une entrée et une sortie. Je suppose aussi que tous les fichiers sont TXT. Si aucun nom de fichier n'est spécifié, les fichiers assument un nom par défaut.

Ces hypothèses sont peut-être trop restrictifs pour certains scénarios, mais mon projet était tout simplement une preuve de concept pour un outil pour produire des fichiers, pas les entreposer. Comme Figure 4 montre, je pourrais facilement encapsuler l'objet XmlWriter dans un composant sympa et créez un fichier XML via le script.

créer un fichier XML via le Script
Figure 4 créer un fichier XML via le Script

Jaquette en haut

Quel est le point de créer un fichier XML via le script ? En fait, c'est la même que celle des fonctions de script dans certaines applications d'entreprise. Vous avez besoin de script parce que vous souhaitez automatiser des tâches. Dans certains cas, créant des fichiers XML ou texte ad hoc, c'est exactement ce qu'il vous faut. Peut-être vous pouvez exécuter des requêtes sur le SQL Server et importation CSV, mais qui nécessite un accès administratif à la base de données de production et, plus important, les compétences appropriées. J'aurais mal moi-même à l'aide de xp_cmdshell pour saisir des fichiers de texte hors SQL Server de requêtes. Pour un développeur, il ne serait pas difficile d'organiser des objets ad hoc, facile à utiliser qui sont prêtes à l'emploi pour le script.

Mon client a aimé cette idée, autant que j'ai aimé à l'aide de ClearScript. Il m'a demandé d'ajouter des objets beaucoup plus à l'environnement dynamique. Je me suis retrouvé en ajoutant une couche d'inversion de contrôle pour configurer les objets devant être chargés au démarrage. Il envisage également le déploiement ClickOnce dans l'ensemble de la société pour lorsque de nouveaux outils sont disponibles.


Dino Esposito est le co-auteur de « Microsoft .NET : Architecture de Solutions d'Applications mobiles pour l'entreprise » (Microsoft Press, 2014) et à venir « programmation ASP.NET MVC 5"(Microsoft Press, 2014). Un spécialiste technique pour le .NET Framework et les plates-formes Android à JetBrains et lors des événements de l'industrie dans le monde entier, Esposito partage sa vision du logiciel à software2cents.wordpress.com et sur Twitter à twitter.com/despos.

Remercie les experts techniques suivants d'avoir relu cet article : Équipe Microsoft ClearScript