Archive for the ‘.Net’ Category

Pascal subprocedures in C#

Wednesday, December 31st, 2008

Sometimes I miss the embedded procedures feature of Object Pascal. OOP purists will throw a fit at this, but I know that the true Delphi fans will smile. Here’s the one liner delegate declaration required to implement subprocedures in C#:

/// <summary>
/// Use this delegate to simulate a pascal sub procedure i.e.
/// 
/// void OuterFunc() {
///     SubProcedure InnerProc = delegate() { ... };
/// 
///     ...
///     InnerProc();
///     ... 
///     InnerProc();
///     ...
/// }
/// </summary>;
public delegate void SubProcedure();

<french>

Les vrais fans de Delphi et de la programmation structurée conviendront avec moi que les sous-procédures sont bien cools. La simple déclaration de delegate décrite plus haut suffit pour émuler cette construction en C#.

</french>

Tweaking the output of XSD.exe to use generics

Monday, August 20th, 2007

A program I am working on heavily uses XML deserialization to build object models from XML files.

I didn’t have to write the deserialization code thanks to the excellent tool provided by Microsoft called XML Schema Definition Tool (Xsd.exe). This tool generates a bunch of C# classes that capture the data structure described in a given schema file (XSD files).

The generated code do have a few shortcomings though, like the use of arrays to handle multiple elements or the generation of FxCop unfriendly code. Jonathan ‘Peli’ de Halleux has already solved most of these problems in his XsdTidy, XSD mapping beautifier tool.

In my case, XsdTidy didn’t really work out of the box. My problems where slightly different:

  • Use generics for multiple elements instead of array, e.g. List<sometype> instead of SomeType[].
  • Use a tool runnable from the command line to integrate easily in my automated build system.

I could have hacked XsdTidy to solve these problems, but instead I went for the bad and the ugly: a quick and dirty regex script. I could have used perl, python or any other language that has a reasonably powerful regex engine, but I really have a soft spot for ruby. So here it goes, tweakXsd.rb, a quick and dirty, one-off job to tweak an xsd-generated class file to use generics.

Everytime I change my XSD schema files, I run a the MS-DOS script like the one below to regenerate C# classes, et voilà!

    REM 
    REM This script generates Foo.cs from Foo.XSD
    REM
    SET XSD="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\xsd.EXE"
    SET RUBY=C:\ruby\bin\ruby.exe
    %XSD% /c /namespace:My.Namespace /order Foo.xsd 
    %RUBY% tweakXsd.rb < Foo.cs > Foo.cs.tmp
    del Foo.cs
    ren Foo.cs.tmp Foo.cs

As a bonus, the script tweaks elements defined as XmlTextAttribute to string properties instead of string[]. To produce a XmlTextAttribute compatible element, use the following schema declaration:

 <xs:element name="elementWithText">
   <xs:complexType mixed="true" />
 </xs:element>

<french>

L’outil Xsd.exe proposé par Microsoft pour la création de classes de désérialisation XML à partir d’un fichier de schéma XML est réellement très utile. Le seul problème c’est que le code généré utilise des tableaux pour permettre l’accès aux collections d’éléments. Pour un projet je souhaitais pouvoir accéder à ces collections en utilisant des collections génériques de type List<T>. Après avoir écarté l’outil XsdTidy j’ai codé moi-même un script en mode “porcho” (cf. le Dictionnaire vosgien-français).

Le script tweakXsd.rb prend en entrée le résultat de “xsd.exe /c” et produit une version modifiée qui utilise les génériques et expose les attributs taggés XmlTextAttribute en tant que propriétés de type string au lieu de string[].

Le script MS-DOS cité plus haut montre un exemple d’automatisation du script.

</french>

ASP.NET Web Parts Default Provider Loading Error Fix

Friday, October 13th, 2006

If your Visual Studio 2005 setup diverges slightly from the default setup, you may run into issues when trying to use the ASP.NET web parts. For example, on my development machine I got rid of SQL Server Express. The first time I tried to create a test portal with web parts, I had the following error message: “An error has occurred while establishing a connection to the server…” This error occurred because the web parts system tried to mount a database on the “./SQLEXPRESS” server, which I removed from my system.

The issue is very easy to fix. Locate the machine.config file in %WINDIR%\Microsoft.NET\Framework\v2.x\Config and change the “LocalSqlServer” connection string to wherever is your ASP.NET application services database, usually called aspnetdb. You will easily locate this entry in the “<connectionstrings>” section. For example, I changed my entry to the following:

<connectionstrings>
 <add name="LocalSqlServer"
   connectionString="Data source=.;Integrated Security=
   SSPI;Initial Catalog=aspnetdb"
   providerName="System.Data.SqlClient" />
</connectionstrings>

To initialize aspnetdb, you may have to run the aspnet_regsql.exe tool. See here for more information.

If you don’t want to change the machine.config, you can override the “LocalSqlServer” value in your web.config file as shown here:

<connectionstrings>
 <remove name="LocalSqlServer"/>
 <add name="LocalSqlServer"
   connectionString="Data source=.;Integrated Security=
   SSPI;Initial Catalog=aspnetdb"
   providerName="System.Data.SqlClient" />
</connectionstrings>

StringTemplate

Thursday, October 5th, 2006

L’une des grandes plaies du génie logiciel est la réinvention perpétuelle de la roue. Récemment confronté à un problème de génération de code, j’ai décidé de briser le cercle infernal. Ce que je m’apprêtais à ne pas redévelopper pour la énième fois s’appelle “template engine”. Travaillant dans le monde .NET, j’ai donc juste googlé “template engine .net” et je suis tout de suite tombé sur StringTemplate. Ayant déjà eu un bon feeling avec le compilateur de compilateur ANTLR je n’ai pas hésité à investir un peu de temps pour explorer le package.

Les points forts de StringTemplate sont:

  • Stricte séparation modèle/vue (en gros, pas de template spaghetti comme JSP ou ASP).

  • Fondements théoriques clairs et argumentés (ST, le langage de définition des templates, présente toutes les caractéristiques d’un langage fonctionnel).

  • Modèle push (toutes les données sont fournies au template avant l’évaluation i.e. pas de connexion à une base de données au sein du template!)

  • Une syntaxe très clean aussi bien pour les templates que pour l’API.

  • Bonne pérennité et bon support (ANTLR existe depuis 1989).

  • Disponible pour Java, .NET et Python.

En m’inspirant des exemples fournis, j’ai pu très vite monter mon système. En fait StringTemplate permet de faire les choses simples très facilement et possède assez de puissance pour rendre les choses bien plus complexes faisables sans trop bidouiller.

Pour le petit job que j’avais à faire les concepts de base m’ont suffit:

  • Groupe de templates (classe StringTemplateGroup) qui permet de définir une espèce de CLASSPATH où les fichiers template sont stockés (avec une extension “.st”). Un template stocké peut ensuite être référencé par son nom ou son chemin. En gros un template peut être vu comme une fonction.

  • Attribut multi-valué: il s’agit d’un attribut qui contient une liste de valeurs vs. attribut simple.

  • Application d’un template qui s’apparente à un appel de fonction.

Le principe de StringTemplate est plus long à expliquer qu’à coder. Imaginons que l’on veuille réaliser un mailing à partir d’une liste de noms et d’adresses. Il suffit de créer un fichier template appelé “c:\templates\mailing.st” avec le contenu suivant:

    Cher $nom$,

    Nous savons que vous habitez dans la ville de $ville$.

    Signé: Furax

Comme vous l’aurez deviné, les éléments du template sont isolés entre des dollars (”$”). Il est aussi possible d’utiliser les brackets à la HTML (”<” et “>”). Dans notre programme, le fichier mailing “mailing.txt” est généré grâce au code suivant:

    using System;
    using System.IO;
    using Antlr.StringTemplate;
    using Antlr.StringTemplate.Language;

    StringTemplateGroup group =
            new StringTemplateGroup("templates", @"c:\templates",
                    typeof(DefaultTemplateLexer));
    StringTemplate mailing = group.GetInstanceOf("mailing");

    mailing.SetAttribute("nom", "Jean Paul");
    mailing.SetAttribute("ville", "Paris");

    TextWriter tw = new StreamWriter("mailing.txt");
    tw.WriteLine(mailing.ToString());
    tw.Close();

Pour la petite histoire, j’ai bien apprécié la syntaxe de bloc inspirée de Smalltalk pour l’application de templates qui permet d’écrire des trucs du genre:

    $records:{ record |
        fields = new string[] {
            $record.fieldNames:{ f | "$f$"}; separator=", "$ };
        values = new object[] {
            $record.fieldCValues; separator=", "$ };
    }

Si records est une liste d’objets record dont l’attribut fieldNames contient une liste de noms de champs et l’attribut fieldCValues une liste d’expression C#, l’évaluation du template pourrait donner le résultat suivant:

    fields = new string[] { "A", "B", "C" };
    values = new object[] { 0, "32", DateTime.Today };
    fields = new string[] { "A", "B", "C" };
    values = new object[] { 44, "AA", DBNull.Value };

Je vais certainement réutiliser StringTemplate, notamment dans sa version pour Python. Par exemple, je pourrai l’utiliser avantageusemet comme une alternative gratuite à CodeSmith.