Archive

Archive for août 2011

Feeds Of The Week #8

Cette semaine, pas mal de choses.

Déjà, comme il est toujours bon de garder en mémoire les bases : A Brief Introduction of Fundamental OOP.

Ensuite, des liens qui suivent des conversations que j’ai eu avec des collègues.
Par habitude maintenant (et parce que c’est super pratique), j’utilise beaucoup d’expressions lambdas (sauf quand je dois rendre mon code compatible VS2005…). Résultat, une discussion avec un collègue qui disait que les lambdas, c’est pas forcément simple de comprendre comment ça fonctionne. Kodefuguru a répondu à ma place : Lambdas for Junior Developers.

Avec les lambdas, il y a souvent Linq (les méthodes d’extensions System.Linq dans mon cas). Et là, on a discuté de performances. J’avais lu, il y a pas mal de temps, que ceux qui constatent des performances moindres (Linq to SQL), c’était aussi ceux qui employaient mal Linq. Je suis plutôt d’accord avec cet avis. Et du coup : LINQ query performance (Count & Any).

Question optimisation, il y a aussi les génériques. Dans notre cas, on a un socle qui a été fait en .Net 1.1 (sic…) et migré par parties (comprendre : quand les devs avaient que ça à faire). Du coup, on se trimballe parfois des méthodes qui usent (abusent) du cast (tout est object, et je dis bien object, pas objet…).
Mais les génériques, on  peut aussi optimiser un peu : Optimization and generics, part 1: the new() constraint & Optimization and generics, part 2: lambda expressions and reference types.

Pour en revenir un peu à Linq. Un autre billet sur les méthodes d’agrégation : Five Easy Sequence Aggregators.

Après, d’autres liens un peu en vrac !

Voilà, ça fait déjà pas mal de choses ^^

Sinon, concernant mes helpers Ext.Net.
J’ai eu à affronter un cas auquel je n’avais pas pensé durant le développement du helper pour le GridPanel.
Et c’est en cherchant à le résoudre que j’en ai résolu d’autres ^^
Pour résumer, voici les problèmes :

  • L’une de nos données à afficher est stockée dans un Dictionary<String, Double>, la clef est l’identifiant de la monnaie (EUR, USD, JPY…) et le double est le montant :
    • Dans certains cas, il faut afficher le montant de la devise sur la même ligne (1 ligne = 1 contrat)
    • Parfois, il faut afficher le montant de la devise dans une autre devise (quand on change la devise sur l’écran)
  • Les objets que l’on utilise sont énorme (il y a bien trop d’infos à l’écran…), ce qui fait que la sérialisation Ext.Net (pour stocker les données dans le store) prend :
    • TOUT l’objet
    • Uniquement les propriétés primitives (String, Int32…en sommes les types du namespace System)

La solution…Et bien, ça a été de créer un dictionnaire de données (littéralement : Dictionary<String, Object>) pour stocker les données (en utilisant la réflexion pour le charger). Ce ne fut pas une mince affaire, mais au final le résultat est plutôt concluant.
Je mettrais donc, sous peu, à jour le repository GitHub. Et je ferais donc le billet qui va bien.

En conclusion : A t-on encore besoin de développeurs ?
Je réserve mon avis, pour le moment… Il y a quelques années, j’entendais partout que les développeurs iraient en Inde/Chine/Maroc/etc. Aujourd’hui, il y a toujours des développeurs. Il y a même des entreprises qui se payent des consultants (j’en sais quelque chose…) pour…pisser du code. Wait and see!

Catégories :.Net, Divers, Feeds

[Ext.Net] Helper pour la création d’une ComboBox

Série de billets sur les helpers que j’ai réalisés autour d’Ext.Net. Le sommaire référençant les helpers est ici : Présentation des helpers.

Avec Ext.Net, il y a plusieurs types de Combobox disponibles.
Pour ma part, j’ai pris la plus simple : celle qui affiche le contenu d’une liste dont le contenu est connu avant la création de la combo.

En pratique, cela veut dire que, dans la page, j’ organise le code comme il suit :

Etape 1 : déclaration des combobox comme propriétés de la page (du user control)

private ExtComboBox combo1;

Etape 2 : configurer la combobox

private ExtComboEntity GetConfigComboBox(int id)
{
    return new ExtComboEntity()
    {
        ComboID = String.Concat("Combobox", id),
        Resizable = true,
        DisplayField = "StringProperty",
        ValueField = "IntProperty",
        EmptyText = "Select value...",
        AllowRemove = true
    };
}

Note : normalement, la propriété EmptyText doit pointer vers une ressource (*.resx / *.resources), mais pour les exemples, je suis passé outre (voir solution d’exemples).

Etape 3 : dans l’évènement OnInit : création du contrôle (constructeur et appel de la méthode SetDataAndConfiguration)

combo1 = new ExtComboBox();
combo1.SetDataAndConfiguration(GetConfigComboBox(1), data.Take(10).ToList(), Combobox1Container);

Etape 4 : dans l’évènement Page_Load : présélection des champs

combo1.SelectedText = "I am property number 9";

En terme de fonctionnement interne, la liste passée en paramètre est transformée en une liste générique de type AnonymousObject.
En effet, j’ai dis à l’occasion de la présentation du helper pour le store que TOUT l’objet est sérialisé.
Dans mon exemple (voir le code sur GitHub), j’utilise un objet MySampleObject qui contient quatre propriétés. Si je laisse Ext.Net le sérialiser, j’aurais dans ma source les quatre propriétés.
A mon sens, cela pose deux problèmes majeurs : le poids de la page qui est chargée inutilement et, plus grave, une possible faille de sécurité.
Donc, avec un peu de réflexion (dans tous les sens du terme), il est possible de transformer, mon proxy est donc pas mal allégé.

new Ext.data.PagingMemoryProxy(
	[
	{"Text":"I am property number 0","Value":"0"},
	{"Text":"I am property number 1","Value":"1"},
	{"Text":"I am property number 2","Value":"2"},
	{"Text":"I am property number 3","Value":"3"}
	[...]

Au lieu de :

new Ext.data.PagingMemoryProxy(
	[
	{"StringProperty":"I am property number 0","DateProperty":"1946-01-15T10:13:50","IntProperty":0,"DoNotShowProperty":"I am the hidden one."},
	{"StringProperty":"I am property number 1","DateProperty":"1982-09-13T22:33:58","IntProperty":1,"DoNotShowProperty":"I am the hidden one."},
	{"StringProperty":"I am property number 2","DateProperty":"1960-02-21T22:15:14","IntProperty":2,"DoNotShowProperty":"I am the hidden one."},
	{"StringProperty":"I am property number 3","DateProperty":"1944-01-20T09:34:41","IntProperty":3,"DoNotShowProperty":"I am the hidden one."},
	[...]
Catégories :.Net, ASP.Net, C#, Ext.Net

[Ext.Net] Présentation des helpers

Ce billet sera relativement court, il a pour but premier de poser la problématique autour de laquelle tournera les suivants.

Sommaire des billets :

Les sources et exemples d’utilisations peuvent être trouvés sur Github.

J’ai déjà brièvement parlé d’Ext.Net, mais je vais faire un rappel ici.

Donc, Ext.Net se base sur le Framework Javascript ExtJS. Il a pour but de mettre à disposition des composants utilisables aisément afin de créer des interfaces web riches. Il suffit simplement de référencer les DLL qui conviennent et c’est tout, rien de plus simple.
Au sein du code, on va donc manipuler des balises à l’instar des balies <asp:…/>.

Voici deux exemples simplistes :

    <ext:ImageButton
        runat="server"
        ImageUrl="button.gif"
        OverImageUrl="overButton.gif"
        DisabledImageUrl="disabled.gif"
        PressedImageUrl="pressed.gif">
        <DirectEvents>
            <Click OnEvent="Button_Click" />
        </DirectEvents>
    </ext:ImageButton>

 

<ext:SpinnerField ID="SpinnerField1" runat="server" FieldLabel="Age" />

Comme on peut le voir, c’est assez simple (simpliste).
Par contre, dès que l’on veut utiliser des composants un peu plus complexes, comme un GridPanel, alors le code ASPX est bien plus long à faire.

La problématique qui s’est posée à moi était simple : sur un projet faisant la part belle au reporting sous forme de tableaux, j’avais un nombre assez considérable de GridPanel. Et comme je suis d’un naturel assez fainéant, j’ai préféré investir un peu de temps à créer un helper.
L’avantage est de pouvoir créer un nombre très important de GridPanel sans gros efforts et surtout de tout gérer dans le code C#, ce qui me permet donc de satisfaire à d’autres besoins qui sont, entre autres, d’avoir un même tableau avec les mêmes données, mais des colonnes affichées ou masquées suivant qui les voit.

Catégories :.Net, ASP.Net, C#, Ext.Net

[Ext.Net] Helper pour la création du store

Série de billets sur les helpers que j’ai réalisés autour d’Ext.Net. Le sommaire référençant les helpers est ici : Présentation des helpers.

La première chose à créer, lorsque l’on veut créer des composants avec des données, c’est le store.

Déjà, qu’est ce que c’est le store.
Le store, c’est comme une DataSource, ça permet de stocker les données (dans notre cas, des données sérialisées).
L’inconvénient, c’est que TOUT le store est stocké dans la page.

Prenons un exemple.
Je souhaite utiliser un GridPanel pour afficher les données d’une liste générique de type :

    public class MySampleObject
    {
        public String StringProperty { get; set; }
        public DateTime DateProperty { get; set; }
        public Int32 IntProperty { get; set; }
        public String DoNotShowProperty { get; set; }
    }

Dans la source de la page, on aura :

		[...Extrait partiel...]

this.MainContent_MyGridExtPanelStoreId=new Ext.ux.data.PagingStore(
	{
	proxyId:"MainContent_MyGridExtPanelStoreId",
	autoLoad:true,
	reader:new Ext.data.JsonReader(
		{
		fields:[
			{name:"StringProperty"},
			{name:"IntProperty",type:"int"},
			{name:"DateProperty",type:"date",dateFormat:"Y-m-dTh:i:s"}
			]
		}),
	directEventConfig:{},
	proxy:new Ext.data.PagingMemoryProxy(
		[
		{"StringProperty":"I am property number 0","DateProperty":"1988-03-01T06:53:34","IntProperty":746583876,"DoNotShowProperty":"I am the hidden one."},
		{"StringProperty":"I am property number 1","DateProperty":"1944-04-13T21:10:31","IntProperty":1822087014,"DoNotShowProperty":"I am the hidden one."},
		{"StringProperty":"I am property number 2","DateProperty":"2000-06-22T14:37:03","IntProperty":1922942219,"DoNotShowProperty":"I am the hidden one."}

		[...Extrait partiel...]

Expliquons un peu cet extrait :
J’ai créé un store (type : PagingStore; id : MainContent_MyGridExtPanelStoreId).
Le reader utilisé est un JsonReader, c’est lui qui s’occupe de la lecture des données.
Au sein du reader, on référence trois colonnes (fields) , se sont les propriétés à afficher :  StringProperty, IntProperty (de type int dans la grille) et DateProperty (de type date dans la grille et avec le format spécifié).
Enfin, les données à proprement parlées sont stockée dans la page (PagingMemoryProxy, à moins de faire appel à un handler).

Mon objet contient plus de champ, il y a la propriété DoNotShowProperty que je ne souhaite pas afficher.
Mais comme c’est l’objet ENTIER qui est sérialisé, il convient de faire TRES attention aux objets utilisés (au même titre q’une page d’erreur affichant du code, cela peut être une faille de sécurité).

Ainsi, je conseillerais d’utiliser des objets « présentation », c’est à dire des objets minimalistes avec uniquement les champs que l’on souhaite afficher (mais qui n’hérite pas des objets métiers, sinon on en revient au même problème…).

Le deuxième effet kiss cool, c’est que comme l’objet est sérialisé (et ça, on y peut rien), il faut bien prévoir que toutes les propriétés de l’objet puissent être sérialisée.

A noter que l’attribut XmlIgnore n’est pas pris en compte.

Pour créer le store, j’utilise donc la classe suivante :

public class StoreFactory
{
    public static Ext.Net.Store Create(String id, JsonReader jsonReader, IList data, String groupByField)
    {
        // Création du Store
        Ext.Net.Store store = new Ext.Net.Store();
        store.ID = id;
        store.Reader.Add(jsonReader);
        store.SerializationMode = SerializationMode.Complex;
        // Groupement sur les entrées
        if (!String.IsNullOrEmpty(groupByField))
            store.GroupField = groupByField;

        store.AutoLoad = true;
        store.AutoDataBind = true;
        store.RemoteSort = false;
        store.RemotePaging = false;

        store.DataSource = data;
        store.DataBind();

        return store;
    }
    public static Ext.Net.Store Create(String id, JsonReader jsonReader, IList data)
    {
        return Create(id, jsonReader, data, null);
    }
}
Catégories :.Net, ASP.Net, C#, Ext.Net

Feeds Of The Week #7

Au programme, cette semaine : fatigue, motivation en berne et temps de merde. Ah non, c’est pas au bon endroit, ça…

Sinon, c’est vrai, un billet assez light cette fois (j’ai beaucoup de brouillons, mais j’ai du mal à les finir…).

En premier, d’abord parce que je travaille plus dans le web, Philippe Vialatte qui parle du web.config. Tout d’abord pour dire qu’il faut y prêter grande attention et ensuite pour une suite de billets dont le premier élément tourne autour du débogage.

Ensuite, parce que j’aime bien le sujet : The Past, Present and Future of Parallelizing .NET Applications.

Le lazy loading aussi, avec ce billet : .net 4 et Lazy-loading thread-safe : un nouveau type bien pratique.

Et enfin, c’est pas la première fois que je renvois vers des billets de ce genre, mais c’est parfois un peu (trop ?) notable : Montre-moi ton expérience !

Et pour combler un peu, petite anecdote amusante (enfin, amusante…).
Dans le bureau, un collègue (on va l’appeler FUIJDT dans le but d’anonymiser les données…) est arrivé et a remarqué le cordon de téléphone (vous savez, le truc à spirales) totalement en vrac  d’un autre.
Par curiosité, FUIJDT appelle le service qui se charge des téléphones (qui n’est pas le même que celui qui installe les pc, qui n’est pas le même que celui qui les stock, qui n’est pas le même que celui qui fais les images…). Et là, on a eut droit à une discussion assez surréaliste.
FUIJDT demandait uniquement s’il était possible de changer le cordon (une information bête et méchante avec une réponse allant de « oui » à « non »…). En face, le gars lui a demandé son nom, prénom, adresse mail et numéro de téléphone pour créer un ticket d’activité et justifier des 5 secondes qu’aurait du durer l’appel…
Finalement, FUIJDT en a eu marre et à raccroché après deux bonnes minutes…

Catégories :.Net, Divers, Feeds

TechDays 2012

Juste une petite news en passant pour relayer ceci : les TechDays 2012 seront les 7, 8 et 9 Février !
Ainsi que la demande de feedback qui va avec.

Cette fois, je m’y prendrais à l’avance pour y aller !

Catégories :.Net, Evènements