Astuces DotNet (Sébastien Courtois)

16/04/2010

[Nouveautés C# .NET 4] Introduction au C# dynamique

Filed under: .NET, C# 4, Débutant — Étiquettes : , , , , , , — sebastiencourtois @ 09:42

Une des nouveautés qui a fait couler beaucoup d’encre est l’ajout des types dynamiques à .NET 4. Cela venait d’un besoin pour des langages “dynamiques” tel que le Javascript, Python ou encore le Ruby de pouvoir être facilement interopérable avec les langages plus traditionnels comme le C# ou le VB. Microsoft a ainsi rajouter une couche au framework : La DLR (Dynamic Langage Runtime) ainsi qu’un langage supplémentaire tirant entièrement parti de la dlr : le F#.

  • Le principe de fonctionnement

Le but des types dynamiques de pouvoir appeler des méthodes/propriétés d’un objet et que la résolution (le lien entre le code appelant et le code appelé) ne se fasse pas au moment de la compilation mais que cette résolution se fasse à l’exécution.

dlr Comme on peut le voir ci dessus, les types .NET sont résolus au moyen d’un “object binder” qui n’est autre qu’un code utilisant la réflexion. Pour les langages dynamiques, chacun a sa propre méthode de résolution.

Il est à noter quel la DLR s’appuie sur la CLR. Les langages C#/VB peuvent ainsi choisir d’utiliser le couple DLR/CLR ou uniquement la CLR (comme avant). Lorsque la DLR est utilisé, celle ci retraduit les appels pour qu’il soit exécutable par la CLR.

dlr2

  • Le mot clé dynamic en C#

Afin de décider le type de runtime nous allons utiliser, C# 4 introduit un nouveau mot clé dynamic. Ce mot clé permet d’indiquer que l’instance de l’objet sera interprété par la DLR et non pas par la CLR directement. Cela permet d’appeler n’importe quel méthode/propriété/indexer de la classe sans connaitre son nom et ses paramètres à la compilation.

int a = 0;
dynamic b = a;
b = 1;
//a = 0 , b = 1
List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5 };
dynamic listDynamic = list;
listDynamic.Add(6);
list.Add(7);
//list = {0,1,2,3,4,5,6,7}
//listDynamic = {0,1,2,3,4,5,6,7}

Ce code montre qu’il est possible de convertir tout type (valeur / références) dans des types dynamiques.

dlr3 Le fonctionnement général de la mémoire n’est pas bouleversé par le mot clé dynamique (les types références vont toujours sur le tas, les types valeurs sur la pile). La seule différence réside au niveau de l’object binder qui,dans le cas de types dynamiques, fera la résolution au moment de l’éxécution du programme.

public class Test
{
    public string ValA { get; set; }
    public int ValB;
    public dynamic ValC;

    public void Toto(int a){}
    public string Tata(dynamic b) { return string.Empty; }
}

Concernant le mot clé dynamic, il est aussi possible de l’utiliser dans les définitions des propriétés,les paramètres de méthodes, les types retours, les indexeurs … bref, on peut l’utiliser dans tous les cas.

  • On pouvait faire du dynamique en C# 3.5 ?

Il était possible de réaliser ce type d’opération en .NET 3.5. Voici un exemple de code permettant l’appel de méthode dont on passe le nom en paramètres.

public void CallMethod<T>(T instance, string methodName) where T : class
{
   Type t = instance.GetType();
   MethodInfo mi = t.GetMethod(methodName);
   if (mi == null)
     throw new InvalidOperationException(string.Format("La méthode {0} n'existe pas pour le type {1}", methodName, t.Name));
   mi.Invoke(instance,new object[]{});
}

On remarque que le code reste très complexe pour juste appeler une méthode d’une classe. Microsoft nous a donc maché le travail afin de ne plus à avoir utiliser la reflection dans ce genre de cas.

  • Un grand pouvoir implique de grandes responsabilités

Comme je l’ai dit au début de l’article, cette nouveautés a fait couler beaucoup d’encre. Je suis plutôt contre cette fonctionnalités pour les raisons suivantes :

  1. Lisibilité du code : A l’instar du mot clé var introduit en .NET 3.5, rendre un langage comme C# en partie dynamique va réduire la lisibilité du code car on ne saura plus le type des différentes variables car de nombreux développeurs vont préférer écrire des var/dynamic partout plutôt que typer correctement leurs instances.
  2. Intellisense : Le mot clé dynamic entraine une résolution à l’exécution. Cela veut dire que, au moment de la compilation, on ne dispose d’aucune informations sur la structure des objets que l’on utilise ce qui rend l’écriture du code complexe (une faute de frappe ou de majuscule et on obtient une erreur …. à l’éxécution.)dlr4
  3. Erreur de résolution : Comme expliqué ci-dessus, les fautes de frappes peuvent arriver lorsque l’on code (surtout sans aide de l’intellisense) et on se retrouve avec des erreurs à l’éxécution. Cela introduit un temps supplémentaire car on obtient les erreurs de résolutions après la compilation/exécution. De plus, pour un peu que l’on ne passe pas dans le code où se trouve l’erreur, on ne la voit jamais et c’est l’utilisateur final qui en ait victime.

dlr5

  • Conclusion

L’ajout de la DLR est une fonctionnalité sympathique pour l’interopérabilité entre langages statiques et dynamiques. Cela devrait décupler les possibilités des langages .NET et surement entrainer de nouveaux pattern de développement. Toutefois, à l’instal du mot clé var, il se peut que cela soit au détriment de la qualité/lisibilité du code.

Si vous avez des commentaires/questions sur le sujet, n’hésitez pas à commenter.

15/04/2010

[Nouveautés C# .NET 4] Paramètres nommés et optionnels

Filed under: .NET, Débutant — Étiquettes : , , , , — sebastiencourtois @ 12:43

Suite de notre tour sur les nouveautés de C# 4. Après une présentation de la Co-Contravariance, nous allons nous intéresser à une fonctionnalité qui faisait cruellement défaut à .NET : les paramètres nommés / optionnels.

  • Paramètres optionnels

Qui n’a pas écrit ce type de code dans un programme :

public void MaFonction(int a)
{
  this.MaFonction(a, "toto");
}
public void MaFonction(int a, string b)
{
   this.MaFonction(a, b, null);
}
public void MaFonction(int a, string b, StringBuilder c)
{
   //Fait le traitement
}

une suite (parfois sans fin) de méthodes s’appelant les unes les autres avec des ajouts de paramètres pour arriver à “la fonction qui fait tout”. Cela a pour désavantage d’augmenter sensiblement (et inutilement) la taille du code source et cela peut être la source d’erreurs dans l’attribution des paramètres.

Pour parer à ces inconvénients, Microsoft a introduit, dans .NET 4, une nouvelle fonctionnalité : les paramètres optionnels. Il s’agit de définir des valeurs par défaut aux paramètres que l’on souhaite définir comme optionnel.

Le code précédent peut donc s’écrire en .NET 4 :

public void MaFonctionNET4(int a, string b = "Toto", StringBuilder c = null)
{
    //Fait le traitement
}

Au niveau de l’Intellisense, on se retrouve avec les affichages suivants : 

params1params2

Intellisense pour la version classique

Intellisense pour la version .NET 4

Remarque : Les paramètres optionnels doivent toujours apparaitre après les paramètres obligatoires. Ainsi le code suivant génère une erreur de compilation.

params3 
  • Paramètres nommés

Lorsque l’on a des méthodes avec beaucoup de paramètres, il arrive que l’on ne se rappelle plus de l’ordre de chacun des paramètres. Récupérer l’information par l’IntelliSense ou en allant voir dans le code source peut prendre parfois un peu de votre temps au combien précieux.

Pour pallier ce problème, .NET 4 permet d’utiliser les paramètres nommés.

Prenons une méthode classique :

public void MaFonctionNET4WithName(string param1, int param2 = 0, double param3 = -42.424242)
{

}

.NET 4 permet de définir les paramètres en fonction de leur nom et non plus en fonction de leur ordre. On peut ainsi écrire :

t.MaFonctionNET4WithName(param1: "Test",param2: 5);

Il est à noter que les paramètres nommés et les paramètres optionnels peuvent cohabiter.

Remarque : Lorsque l’on utilise les paramètres nommés pour l’appel d’une méthode, il faut le faire sur l’ensemble des paramètres il faut indiquer les paramètres nommés après les paramètres classiques (qui, eux, doivent être dans l’ordre)  . Dans le cas contraire,on récupère l’exception suivante. Dans le cas contraire,on récupère l’exception suivantes.

params4 

En revanche, l’exemple suivant est valide :

  t.MaFonctionNET4WithName("Toto", param3: 34.45, param2: 8); // Fonctionne car les paramètres non nommés sont en premiers

  • Conclusion

J’attendais cette fonctionnalité depuis un moment (surtout parce que je l’avais déjà utilisé dans d’autres langages). Il faut avouer que c’est une fonctionnalité simple,rapide à mettre en place et qui apporte une meilleur lisibilité et stabilité au code produit.

Merci à François Guillot pour avoir détecté l’erreur concernant l’ordre des paramètres.

12/03/2009

[Virtual Earth] Développement Microsoft Virtual Earth Web Services – Part 1

Filed under: .NET, Débutant, Virtual Earth — Étiquettes : , , , , , , , — sebastiencourtois @ 18:57

Au travers de mes stages et autres projets personnels, j’ai été amené à travailler avec des outils cartographiques divers (de Microsoft MapPoint à GoogleMap en passant par d’autres éditeurs dont je ne citerai pas le nom). Travaillant aujourd’hui majoritairement en environnement .NET, j’ai décidé de me pencher sur l’offre cartographique de Microsoft : Microsoft Virtual Earth.

Liens des posts sur blog:

  1. Introduction à Microsoft Virtual Earth (Part 1)
  2. Géocoding / Géocoding Inverse (Part 2)
  3. Récupération des images satellites (Part 3)
  4. Calcul d’itinéraires (Part 4)

Microsoft Virtual Earth ?

Virtual Earth est composé d’une série d’outils et de services Internet fournissant des informations cartographiques. Ces informations peuvent être de plusieurs types :

  • Images satellites
  • Du Géocoding : Traduire une adresse postale en coordonnées géographiques.
  • Géocoding Inverse : Traduire des coordonnées géographiques en adresse postale.
  • Moteur de recherche : A partir de données diverses, on récupère un ou plusieurs localisations (avec un degré de précision/confiance).
  • Calcul d’itinéraire : A partir de deux adresses/localisations, on récupère l’ensemble du chemin à effectuer en voiture (orientation lors des croisements, distance entre chaque croisement…).

Microsoft Virtual Earth : Comment ça marche ?

A l’inverse de Microsoft MapPoint où les données devait être stockés sur le poste client (ou sur des postes serveurs proche du client), les données de Virtual Earth sont stockées sur les datacenter Microsoft à travers le monde et l’utilisateur ne demande que les données qu’il souhaite visualiser.

Ces données ne sont pas accessible directement depuis les datacenters. Il faut passer par une couche de services Web pour y accéder. Il existe deux façons de faire :

  • Utilisation d’un contrôle ASP.NET Ajax fourni avec le SDK de Virtual Earth (démonstration : http://maps.live.com/)
  • Utilisation du Web Service Virtual Earth (SOAP over HTTP)

Blog6-1

Nous ne parlerons pas du contrôle ASP.NET dans ce tutorial. Vous pourrez trouver les informations voulues pour le développement avec ce type de contrôle à l’adresse suivante : http://dev.live.com/Virtualearth/sdk/

Microsoft Virtual Earth Web Service

Virtual Earth est composé de 5 Web Services :

  • Common (asmx) : Web Service contenant l’ensemble des données communes à tous les services Virtual Earth ainsi que les fonctions d’authentification et de sécurité.
  • Geocode Service (WCF) : Web Service de Géocoding/Géocoding Inverse.
  • Route Service (WCF) : Web Service de calcul d’itinéraire.
  • Imagery Service (WCF) : Web Service de récupération des images.
  • Search Service (WCF) : Web Service du moteur de recherche.

Microsoft Virtual Earth Web Service : Authentification

L’authentification à Virtual Earth se réalise en deux étapes :

  1. Le client fournit un couple login/password au Web Service Common.
  2. Si les informations sont correctes, le Web Service renvoie un token d’authentification sous la forme d’une longue chaine de caractères.

Les appels suivants à l’ensemble des Web Services  Virtual Earth se fera toujours en fournissant ce token.

Dans ce tutorial, nous allons voir comment récupérer un token d’authentification puis faire un appel à une fonction de Geocoding.

  • Récupération Login/Password sur la plateforme développeur Virtual Earth

Avant toute chose, il faut récupérer un couple login/password auprès de Microsoft. Pour cela, il faut une Windows Live ID (https://login.live.com).

Il faut ensuite se connecter sur la plateforme développeur Virtual Earth (https://mappoint-css.live.com/mwssignup) pour demander un compte “free evaluation developer account”. Ce type de compte est gratuit et comporte certaines limitations comme des images contenant des messages “Staging" au milieu des images satellites et une déconnexion automatique en cas d’un nombre trop important de requêtes (j’ai été très peu déconnecté pour ce motif en utilisant les services).

Une fois inscrit, aller dans “Manage account” pour récupérer votre “Account ID”  (i.e login) et pour définir votre mot de passe.

  • Configuration de la solution Visual Studio

Créer une nouvelle solution (selon le type de projet que vous souhaitez faire).

Nous allons ajouter une référence Web vers le Web Service Common. Cliquer droit sur le projet puis aller dans “Add Service Reference”. Au sein de cette fenêtre, cliquer sur “Advanced” en bas à gauche puis sur “Add Web Reference”. Indiquer dans URL l’adresse : https://staging.common.virtualearth.net/find-30/common.asmx?wsdl. Il est possible qu’une popup vous demande vos informations de login/password. Une fois validé, indiquer un nom pour la Web Reference (TokenService dans notre exemple) puis cliquer sur “Add Reference”. Il est à noter que cette opération est longue car le Web Service Common est un service asmx (ancienne génération).

Pour chacun des autres Web Service WCF, il suffit de faire “Add Service Reference” puis d’indiquer une des quatre adresses suivantes puis cliquer sur “GO” puis donner un nom de namespace (le nom des services dans la liste suivante est un convention de ma part) puis cliquer sur “Add Reference”:

Ne pas oublier d’inclure les lignes suivantes au début du code :

using VETutorial.TokenService;
using System.Net;

//Récupération de l'adresse locale
string ipadr = "127.0.0.1";
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
	if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ||
	    ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
	{
		ipadr = ip.ToString();
	}
}
//Création du proxy d'accès au CommonService
CommonService common = new VETutorial.TokenService.CommonService();
common.Credentials = new NetworkCredential("AccountID", "password");
TokenSpecification tokenSpec = new TokenSpecification();
//Adresse IP de la machine du client
tokenSpec.ClientIPAddress = ipadr;
//Durée de validité du token (entre 15 et 480 minutes)
tokenSpec.TokenValidityDurationMinutes = 20;  

//Appel au Web Service Common pour récupération du token
string token = common.GetClientToken(tokenSpec);

On commence par récupérer l’adresse IP locale visible de l’extérieur. Cette adresse nous sera nécessaire pour la partie d’authentification (cette étape est inutile pour les applications Web).

On instancie ensuite la classe proxy CommonService puis on lui fournit le couple login/password récupéré sur la plateforme développeur. Cela se fait grâce à la propriété Credential de CommonService. On crée un NetworkCredential auquel on passe les informations nécessaires et on attribut ce NetworkCredential à la propriété Credential de CommonService.

La récupération d’un token se réalise grâce à la méthode GetClientToken (existe en version synchrone et asynchrone) à laquelle on passe un objet TokenSpecification.

Le TokenSpécification contient :

  • Propriété TokenValidityDurationMinutes: Le temps de validité du token en minutes (entre 15 et 480 minutes)
  • Propriété ClientIPAddress : L’adresse IP du client (inutile pour une application Web).

GetClientToken renvoie une chaine de caractères contenant le token.

  • Appel à une méthode Géocoding

Afin de vérifier que tout est bien configurer, on va demander les coordonnées géographiques de la ville de Paris.

GeocodeServiceClient geoCodeSvc = new GeocodeServiceClient();
GeocodeRequest geoCodeRequest = new GeocodeRequest();
geoCodeRequest.Credentials = new Credentials();
geoCodeRequest.Credentials.Token = token;
geoCodeRequest.Query = "Paris";
var result = geoCodeSvc.Geocode(geoCodeRequest);

On instancie un proxy pour GeocodeService. On crée un objet GeocodeServiceClient contenant une méthode GeoCode qui prend un paramètre un GeocodeRequest contenant les informations nécessaires à la requête. En général, les paramètres de requêtes des Web Services Virtual Earth demandent le token d’authentification dans la propriété Credential.Token. Afin de faire la recherche la plus simple possible, on fournit une chaine de caractères contenant “Paris” à la propriété Query. (nous reviendrons sur les requêtes plus complexe de Géocoding dans un autre post).

On obtient un GeoCodeResponse en retour qui nous fournit un certain nombre d’informations dont la localisation exacte de la ville de Paris.

Dans un prochain post, nous verrons plus en détail le Géocoding (et Géocoding Inverse) ainsi que les requêtes basiques au Web Service d’imagerie satellite.

02/03/2009

Premier post de ce blog

Filed under: Hors Catégorie — Étiquettes : , , , , , , — sebastiencourtois @ 22:59

Bonjour à tous,

Je vais commencer par me présenter :

Je m’appelle Sébastien Courtois.

Je suis Consultant / Chef de projet .NET chez Winwise à Paris.Je fait partie du pôle RIDA (Rich Internet and Desktop Application). Pour résumer, je travaille régulièrement en Winforms, ASP.NET, Silverlight, WPF, ASP.NET MVC …

Afin de rendre ce blog unique, je vais essayer de publier un article/astuce par jour. Je ne sais pas si je tiendrais le rythme :).

Les articles et astuces seront principalement des cas pratiques tirés de ma propre expérience ou des expériences/questions d’autres personnes avec qui j’ai l’habitude de travailler (ils se reconnaitront surement assez vite). Ce ne seront souvent pas des exemples très poussés mais plus des petits problèmes quotidiens qui nous font perdre un temps précieux en projet.

En espérant que ce blog vous aidera et vous plaira. N’hésitez pas à m’envoyer des retours sur les erreurs ou les améliorations possibles (il y en aura surement :)).

Créez un site Web ou un blog gratuitement sur WordPress.com.

%d blogueurs aiment cette page :