Visual Studio 2010 RC à disposition du public

Le 11 février 2010 à 07:45

Après la mise à disposition des abonnés MSDN des versions RC (Release Candidate) de Visual Studio 2010 et du Framework .NET 4.0 lundi, Microsoft vient de les mettre à disposition du public.

Pour rappel, Microsoft s’est essentiellement concentré sur les problèmes de performances des précédentes versions Beta.
Scott Guthrie a d’ailleurs déclaré sur Twitter le 11 janvier 2010 “I'm testing on an ultra-thin which has a 3.3 Windows score (3.9 CPU, 3.3 graphics, 5400 RPM hard drive). VS10 now works well on it.”, ce qui présage quelque chose de bon pour cette version RC :).

Pour l’installation de la version RC, il ne faut pas oublier de désinstaller la version Beta.

Pour télécharger Visual Studio 2010 Ultimate, rendez-vous sur cette page.
Pour le Framework .NET 4.0, cela se passe ici.

Visual Studio 2010

A bientôt !

[.NET] Crypter la section « connectionStrings » du fichier app.config (ou web.config)

Le 2 février 2010 à 19:23

Pour rappel, la section « connectionStrings » du fichier App.config contient les informations d’accès à vos bases de données comme le chemin d’accès, le login et le mot de passe. Ces informations sont donc sensibles et ne doivent pas être dévoilés aussi facilement.
Malgré qu’il soit évident qu’il ne faut pas utiliser un compte « root » de la base de données, il est tout de même plus prudent de cacher cette partie aux yeux des utilisateurs. D’autant plus qu’avec cette méthode, l’utilisateur final ne pourra pas modifier le fichier manuellement.

Voici le fichier App.config et la section “connectionStrings” sous sa forme habituelle :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="SqlCustomersDB" 
         providerName="System.Data.SqlClient" 
         connectionString="Data Source=MPE-SERV\SQLSERVER_ITESTS;
                           Initial Catalog=CustomersDB;
                           User ID=perrein;
                           Password=P@ssw0rD" />
  </connectionStrings>
</configuration>

Et voici le même fichier App.config et la section “connectionStrings” que l’on va avoir sous sa forme “protégé” :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
      xmlns="http://www.w3.org/2001/04/xmlenc#">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
          <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
          <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <KeyName>Rsa Key</KeyName>
          </KeyInfo>
          <CipherData>
            <CipherValue>HvU+CmZBPbPfqGvhBLE8OC2QmO3V7w0gwpTr7CBkMifC15H8eQ8Z
                         AmyxCQRpP/Tz8gypkQ1PDyQdyYD26sa/I1PaJzrZpduypLD2mp9p
                         kyWXAygFRQvb0m4EL0OK8DoHDWMta1q7Q7BycVOU87ePeCQ8Z7MY
                         XGoySopx7nzvBeI=
            </CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>vo42yCFwoVO3s4Md+Jcl9rLHQCRcVDTXr9JGFxjN4ozlGdG9TFrI16+J
                     y1CTWzgi1bXwYtFCfSUgRjMJbYm6ULLGFcFaaX7h/1O+9tfUtrLjbBuJ
                     4wO6q0xr766lrOpQ98BG9rqxm6WwEVWZfT/FesDkzWVw/N+W8FPPk1rg
                     +QTSB7ZisjqhGSkoZERgVe2MsCtl5ZJyQawFvy0DreWdj7efNT2aMs1N
                     Ieogmef0/XTB4nXYjEA8I7R9AnjekWwDnXHAcpFzYjoqgmFx8zHG+XPQ
                     xeXVhCue5QmshNDzuRg=
        </CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>
</configuration>

Pour transformer le fichier, la mise en place n’est pas très compliquée, il faut utiliser la méthode SectionInformation. ProtectSection de la classe ConfigurationSection :

Configuration config = 
              ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection("connectionStrings");

if (section != null)
{
    if (!section.IsReadOnly() && !section.SectionInformation.IsProtected)
    {
        section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
        section.SectionInformation.ForceSave = true;
        config.Save(ConfigurationSaveMode.Full);
    }
}


On peut crypter cette section avec deux providers :
- DataProtectionConfigurationProvider : utilise l’API de protection des données (DPAPI) Windows pour chiffrer et déchiffrer
- RsaProtectedConfigurationProvider : utilise le chiffrement RSA pour chiffrer et déchiffrer les données de configuration

Pour lire une connectionStrings dans le fichier de configuration, rien ne changera par rapport à nos habitudes car le décryptage est totalement transparent. Par contre, s’il faut modifier ou supprimer une valeur, il faudra décrypter la section au préalable : 

Configuration config = 
              ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection("connectionStrings");

if (section != null)
{
    if (section.SectionInformation.IsProtected)
    {
        section.SectionInformation.UnprotectSection();
        section.SectionInformation.ForceSave = true;
        config.Save(ConfigurationSaveMode.Full);
    }
}
config.ConnectionStrings.ConnectionStrings["SqlCustomersDB"].ConnectionString = 
   @"Data Source=MPE-SERVER-02\SQLSERVER;Initial Catalog=CustomersDB;
                 Integrated Security=True;User ID=perrein;Password=P@ssw0rD";
config.Save();

// Modification du fichier de configuration
// ...
// On crypte à nouveau le fichier de configuration une fois les modifications 
// terminées et enregistrées

A bientôt :-).

Visual Studio 2010 Beta 2

Le 21 octobre 2009 à 09:04

Une petite nouvelle qui pourrait en intéresser plus d’un :).
Le téléchargement “tout public” est disponible sur le site de Microsoft (lien).


Bon téléchargement !

Stopwatch : mesurez le temps d’exécution de votre code

Le 17 septembre 2009 à 09:00

En développement, il existe une multitude de possibilités d’une opération pour arriver au même résultat final. Outre la « technicité » du développement, le critère des performances est un élément important à prendre en compte. La meilleure mesure dans ce cas est celle du temps.

Avec le Framework .NET, il existe la classe Stopwatch. Cette classe, existante depuis la version 2 du Framework et présente dans l’espace de nom « System.Diagnostics », permet de mesurer l’intervalle de temps effectuée par une ou plusieurs opérations données. Son utilisation est très simple, et sa précision est de l’ordre de la microseconde.

Sa mise en place est très simple, dans l’exemple suivant, on affiche l’intervalle écoulé pour l’exécution du code entre stopWatch.Start() et stopWatch.Stop(), c'est-à-dire l’instanciation de la variable List et l’exécution de la boucle for :

Stopwatch stopWatch = new Stopwatch();  
stopWatch.Start(); // Démarre le chronomètre  
              
List<int> list = new List<int>();  
             
for (int i = 0; i < 100000; i++)  
{  
   list.Add(i);  
}  
              
stopWatch.Stop(); // Arrête le chronomètre  
              
// On affiche le résultat en milliseconds, pour une meilleure lisibilité  
Trace.WriteLine("Temps écoulé (ms) : " + stopWatch.Elapsed.TotalMilliseconds);

Temps écoulé (ms) : 449.0187

Note : nous pouvons aussi le déclarer différemment, avec le mot-clef var par exemple (après ça revient uniquement sur un choix de lecture et de clarté :-))

var stopWatch = Stopwatch.StartNew();

Nous pouvons aussi arrêter le chronomètre, et la reprendre par la suite, si l’on veut calculer un intervalle précis ; bien sûr, même après l’arrêt, le chronomètre garde en mémoire la valeur sur laquelle il s’est arrêté.

Par exemple, nous calculons le temps d’exécution de Method1(), puis on arrête la chronomètre pour exécuter autre chose, puis on le redémarre pour calculer le temps d’exécution de Method2() :

Stopwatch stopWatch = new Stopwatch();  
stopWatch.Start();  
Method1();  
stopWatch.Stop();  
   
List<int> list = new List<int>();  
  
for (int i = 0; i < 100000; i++)  
{  
   list.Add(i);  
}  
   
stopWatch.Start(); // On redémarre le chronomètre  
Method2();  
stopWatch.Stop();  
   
Trace.WriteLine("Temps écoulé (ms) : " + stopWatch.Elapsed.TotalMilliseconds);

Temps écoulé (ms) : 718.0647

Note : nous pouvons aussi calculer en “ticks”. Un tick (qu’on peut traduire par graduation – MSDN) représente une graduation pour X nanosecondes. Pour X, il dépends de votre matériel. Pour le calculer, il existe Stopwatch.Frequency qui nous donne la fréquence correcte.

var watch = Stopwatch.StartNew();

watch.Start();
string str = "1000";
try
{
    int value = int.Parse(str);
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}
watch.Stop();

Console.WriteLine("Frequence : " + Stopwatch.Frequency);
Console.WriteLine((1e6 * watch.ElapsedTicks / (double)Stopwatch.Frequency) 
                   + " Microsecondes");
Console.WriteLine((1000 * watch.ElapsedTicks / (double)Stopwatch.Frequency) 
                   + " Millisecondes");
Console.WriteLine(watch.ElapsedMilliseconds + " Millisecondes (Stopwatch)");

Console.Read();

Malgré le fait que les machines sont aujourd’hui de plus en plus puissantes, il est toujours utile de faire un audit des performances de son code pendant un développement, cela peut nous aider à prendre certaines décisions que l’ont n’aurait pas prises sans mesure de performance.

Plus d’informations : lien vers MSDN

Design Pattern : Singleton

Le 12 août 2009 à 14:29

1) Définition du design pattern Singleton

Le singleton est un design pattern (pour les plus francophone un « patron de conception ») qui consiste à restreindre l'instanciation d'une classe à un seul objet (ou à quelques objets).

Dans la pratique, le singleton peut être utilisé dans le cas d’une classe de connexion à une base de données. Le singleton permet de s’assurer qu’une seule instance de la classe connexion est utilisée.

Par contre, attention à ne pas confondre classe statique et Singleton : les deux sont différents et ne s’appliquent pas dans les mêmes cas. Singleton permet d’utiliser un vrai objet, être hérité (classe « normale »)… etc, la classe statique non (ce qui peut être gênant, dans le cas cité plus haut, dans initialisation de la classe).

Ce design pattern est très pratique, à manipuler selon ses besoins, mais attention à l’utilisation de ce pattern en cas de multithreading : il faut éviter que deux threads accèdent en même temps à la création de l’instance de l’objet. Aussi, certains pensent que c’est un antipattern, du fait qu’on le retrouve « dans tout et n’importe quoi ».

Nous allons donc voir son implémentation avec .NET.

image 
2) Exemples d’implémentation C# (thread-safe)

a. Exemple simple

public sealed class MyClass
{
    private static MyClass _instance = null;
    private static readonly object _lock = new object();

    private MyClass()
    {
       
    }

    public static MyClass Instance
    {
        get
        {
            lock(_lock)
            {
                if (_instance==null)
                {
                    _instance = new MyClass();
                }
                return _instance;
            }
        }
    }
}

Il faut souligner le fait qu’on utilise un constructeur privé, en effet, il n’y aurait aucun intérêt de laisser un constructeur publique car on veut justement éviter de créer plusieurs instances (ce qui est tout de même le principe d’un Singleton dans la plupart des cas).

Le bout de code ci-dessus suffirait à la plupart des cas. Mais dans un contexte multithread, il se peut que nous rencontrerions un problème : les deux threads pourraient arriver au même moment dans la section critique. Dans ce cas, l’instance sera crée deux fois et risque de poser problème.

Pour remédier à ce problème, il existe le Double Checked Locking (verrouillage à double test).

b. Double Checked Locking

Comme dit précédemment, le Double Checked Locking va permettre de rendre notre code plus sécurisé dans un contexte multithread. On va vérifier par deux fois si l’instance n’a pas été crée, pour éviter que deux threads le fasse au « même moment » (comme ça peut arriver dans l’exemple a).

public sealed class MyClass
{
    static MyClass _instance = null;
    static readonly object _lock = new object();
                
    private MyClass()
    {     
    }

    public static MyClass Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new MyClass();
                    }
                }
            }
            return _instance;
        }
    }
}

Le Double Checked Locking est considéré comme un antipattern du fait des erreurs difficiles à déceler et du débogage hasardeux que cela implique. Donc ce n’est pas forcément la meilleure solution à utiliser.

Nous allons donc voir à présent une manière beaucoup plus à simple à mettre en place.

c. Static Readonly

Une autre manière d’implémenter un Singleton est de passer par un readonly statique. Cette solution me paraît la meilleure.

public sealed class MyClass
{
    private static readonly MyClass _instance = new MyClass();
    
    private MyClass()
    {
    }
        
    public static MyClass Instance
    {
        get
        {
            return _instance;
        }
    }
 }

3) Conclusion

Le singleton est un pattern assez simple à mettre en place. Malgré tout il faut prendre ses précautions : il faut peser le pour et le contre entre chaque solution pour choisir une implémentation efficace et spécifique à ses besoins.

Plus d’informations sur MSDN.

A bientôt :)

A propos de l'auteur

Mathieu Perrein est Software Solutions Architect, Microsoft Student Partner de 2010 à 2012.

 

MSP

 

MSP

MSP

 MSPD

MCT

 

Facebook

 

Ce blog est strictement personnel et les opinions exprimées ici n'engagent donc que moi, et pas mon employeur.

Tags

Vous avez désactivé JavaScript ou bien vous possédez une ancienne version d'Adobe Flash Player. Téléchargez la dernière version de Flash Player.