Web forms to MVC (First step)

Bonjour ce post a pour but d’exposer une stratégie de passage d’une application Webform vers une architecture MVC, en limitant les perturbation sur votre conteneur Webform.

Rappelons que le traitement classique MVC intercepte une requeête Http, celle ci est décortiqué suivant les pattersn enregistrés grace au UrlRoutingModule (HttpModule), ensuite sollicite un gestionnaire http, notament le MvcHandler, celui ci utilise la classe factoryHandler, qui instancie un controleur (IOC) et invoque l’action correspondante.

Dans notre cadre de figure, nous devons penser a invoquer une action d’un controlleur (Correspondant à un refactoring d’une page Web form).

Ci-dessous une portion de code permettant de simuler un contexte dédié.

 
    /// <summary>
    /// Class permit to get http request, simulate creating of route data, create controller instance et calculate render
    /// </summary>
    public static class RoutingWebFormSimulator
    {
         /// <summary>
        /// Enumeration permit to define type of view
        /// </summary>
        public enum TypeView
        {
            /// <summary>
            /// The normal.
            /// </summary>
            Normal, 
 
            /// <summary>
            /// The partial.
            /// </summary>
            Partial
        }
 
        /// <summary>
        /// Method permit to define render of partial view
        /// </summary>
        /// <param name="name">permit to define partial name</param>
        /// <param name="model">permit to define model</param>
        /// <param name="type">permit to define type</param>
        /// <remarks>Get a wrapper for the legacy WebForm context</remarks>
        /// <remarks>Create a mock route that points to the empty controller</remarks>
        /// <remarks>Create a controller context for the route and http context</remarks>
        /// <remarks>Find the partial view using the viewengine</remarks>
        /// <remarks>Create a view context and assign the model</remarks>
        /// <remarks>Render the partial view</remarks>
        public static void Render(string name, object model, TypeView type = TypeView.Normal)
        {
            const string NameController = "WebFormController";
            IView view;
 
            var httpContextWrapper = new HttpContextWrapper(HttpContext.Current);
            var controller = new WebFormController();
            controller.ViewData.Model = model;
            var routeData = new RouteData();
            routeData.Values.Add("controller", NameController);
            var controllerContext = new ControllerContext(new RequestContext(httpContextWrapper, routeData), controller);
            if (type == TypeView.Partial)
            {
                view = ViewEngines.Engines.FindPartialView(controllerContext, name).View;
            }
            else
            {
                view = ViewEngines.Engines.FindView(controllerContext, name, string.Empty).View;
            }
            var viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary { Model = model }, new TempDataDictionary(), new StreamWriter(Stream.Null));
            view.Render(viewContext, HttpContext.Current.Response.Output);
        }
    }

Donc au sein de votre Webforms, vous faites juste appel a ce routeur specifique, qui lira du code MVC.

RoutingWebFormSimulator.Render("Sample", null, RoutingWebFormSimulator.TypeView.Partial);

Sample représente une vue compatible MVC.

GC.Collect

Poster un commentaire

Classé dans Uncategorized

Multithreading Favorite patterns

Le multithreading comporte un ensemble de dérives sur lesquelles il est important de se pencher, les étudier et proposer des solutions permettant de les contourner, parmi les problématiques rencontrées auxquelles on  fait face sont un inter blocage et une synchronisation oubliée, une granularité incorrecte et trop large, une inversion des priorités générant le blocage d’un thread important et l’exécution d’un thread non signifiant, l’immutabilité ou l’absence de pureté etc.

Pour faire face a ces différents problèmes il est necessaire de mettre en place un ensemble de bonnes pratiques de développement , ci-dessous un listing des qualités aue j’affectionne particulièrement.

  • Favoriser l’utilisation de la TPL
  • Favoriser  l’utilisation du Async Result Pattern
  • Favoriser l’utilisation du Background Work Pattern

Ci-dessous un descriptif plus détaillé de trois principes mis en place qui sont les : le pattern Boss Worker, le patern Pipeline et le Producer/Consumer (Une démonstration sera réalisée en utilisant des notions telle Task et BlockingCollection).

Boss/Workers pattern :

Chaque requête soumise à une classe Boss se transforme en une tache à exécuter sur un thread définit par la classe Boss, les threads sont gérés au niveau de la classe Boss, les taches sont encapsulées dans des classes Worker, il présente l’avantage de simplicité de lecture et une isolation bien définie.

Boss : 
foreach {					
	//get a request
	switch(request)
	{
   case X: new Thread(taskX);
     	   case Y: new Thread(taskY);
                 …
              }}

Worker :
taskX();

Pour affaiblir le couplage on pourrait imaginer l’existence de classes requêtes implémentant une interface IRequest et de même pour les classes Worker.
Souvent ce pattern est associé à l’utilisation de la classe ThreadPool.

Pipeline pattern :
Le principe consiste à faire exécuter par un thread une portion d’une tache et passer le résultat au prochain thread.
Ci-dessous un exemple de code de pipeline

class Pipeline
{
Main()	
{	
 createThread( ... stage1 )	
 createThread ( ... stage2 )	
 ...
 wait for all pipeline threads to finish	
 do any clean up	

}	

Stage1()	
{	
  foreach {	
         get next input for the program	
         do stage 1 processing of the input	
         pass result to next thread in pipeline	
  }	
}	
Stage2()	
{	
  foreach {	
         get input from previous thread in pipeline	
         do stage 2 processing of the input	
         pass result to next thread in pipeline	
  }	
}	
..
StageN()	
{	
  foreach {	
         get input from previous thread in pipeline	
         do stage N processing to the input	
         pass result to program output	
  }	
}
}

Ci-dessous un lien décrivant de manière plus détaillée l’aspect implémentation http://msdn.microsoft.com/en-us/library/ff963548.aspx

Producer/Consumer pattern :

Le principe consiste à utiliser un flux de données pour faire communiquer un thread producteur et un un thread consommateur.
Ci-dessous une implémentation réalisée en utilisant des classes telles Task et BlockingCollection qui représente la structure tampon.

// Declarer la structure tampon
var blockingCollection = new BlockingCollection();
// Lancer le premier consomateur qui attend que la données soit disponible sur le tampon
var consumer1 = Task.Factory.StartNew(() =>
{
	foreach (int data in blockingCollection.GetConsumingEnumerable())
   	{
	Console.Write(string.Concat("consumer1= ", data, ","));
	}
});

// Lancer le second consomateur qui attend que la données soit disponible sur le tampon
var consumer2 = Task.Factory.StartNew(() =>
{
	foreach (int data in blockingCollection.GetConsumingEnumerable())
	{
	Console.Write(string.Concat("consumer2= ", data, ","));
	}
});

// Le thread producteur produit les données sur la structure tampon
var producer = Task.Factory.StartNew(() =>
{
	for (int i = 0; i < 100; i++)
	{
	blockingCollection.Add(i);
	}
	blockingCollection.CompleteAdding();
});
producer.Wait();
// Attendre que tous les consomateurs finissent de consommer et relance le traitement
Task.WaitAll(consumer1, consumer2);
Console.WriteLine();

Vous avez des principes supplémentaires tels le up-calls, qui consiste à faire communiquer les couches dans un sens ascendant en utilisant une ThreadPool au sein de chaque couche etc.

GC.Collect

Poster un commentaire

Classé dans C# Multithreading

TPL is nice

Une des façons les plus élégantes de faire de la programmation asynchrone est l’utilisation de la TPL (Task Parallel Library : http://msdn.microsoft.com/en-us/library/dd460717.aspx) en utilisant des notions rudimentaires telle le DataFlow.

La première étape à réaliser est tout d’abord de récupérer la bibliothèque Nuget associée.

NugetTPL

Saisir DataFlow dans le moteur de recherche des extensions et sélectionner TPL Dataflow.

 ExtensionTPL

Vous noterez l’ajout de référence fait dans votre projet

ReferenceTPL

Au cours de l’exercice on utilise deux classes principales qui sont ActionBlock et TransformBlock.

La classe ActionBlock vous permet de definer une fonctionnalité asynchrone.

ActionBlock action = new ActionBlock(
 	(p) => {
	        for(int indexThread = 0 ; indexThread < 5; indexThread++)
	        {
		Thread.Sleep(1000);
		Console.WriteLine(p);
	        }});
action.Post("Nice");
while(true)
{
 Thread.Sleep(300);
 Console.WriteLine("Good");
}

Vous remarquerez que le Dataflow s’exécute en même temps que la boucle faite.

TPLTP

Nous utiliserons au niveau de cette deuxième étape la classe TransformBlock, qui a cette particularité d’appliquer une transformation à un flux d’entrée et produire un flux de sortie.

Ci-dessous une desciption des auters blocs :

  • BatchBlock : Aggrèger un flux en un flux de sortie agissant comme une mémoire tampon.
  • BroadCastBlock : Transfèrer un flux à un ensemble de blocs traitant parallèlement ce flux entant
  • BufferBlock : Fournir à un ensemble de blocs de sortie un même flux.
 
TransformBlock transformBlock = new TransformBlock(
(p) =>
   {
      return string.Concat("We transform this flow", p);
   });

GC.Collect

Poster un commentaire

Classé dans Dataflow, TPL, Uncategorized

Organize solution WAF

Pendant la mise en place de votre solution il est important de structure vos projets en se basant sur des bonnes pratiques, l’un des concepts les plus utilisés est le WAF, Il aide à organiser les types et les espaces de noms dans une structure à grande échelle, les couches «inférieures» sont des services de bas niveau et générale, et les couches «supérieures» sont plus spécifiques de l’application, les couches «supérieures» référencient les types de couches «inférieures» et non l’inverse.
Ci-dessous un diagramme de package exemple à partir duquel on peut s’en inspirer, le préfixe peut correspondre au nom de votre organisation.

Package

Les packages cités ci-dessous peuvent aussi correspondre au nom de répertoires de la solution pour faciliter la lecture de la solution, ou imaginer des scénarios plus compliqués ou figure plusieurs point d’entrées au sein de la couche Presentation, ou cette voir cette nécessité de séparer les classes de collection de données  et les services de traçage au sein de la couche Foundation, d’où le fait de réaliser deux projets distincts Foundation Prefix.Foundation.Util et Prefix.Foundation.Data au sein du répertoire Prefix.Foundation.

Ci-dessous un descriptif exhaustif  des différentes couches : 

  • La couche Presentation contient les vues de l’application, les fichiers XAML, cela peut être des pages ou des contrôles utilisateurs, ces fichiers sont faiblement couplées à la mécanique de transformation de données, voir le cas ou on utilise un pattern MVVM pour tuner notre application cliente WPF (Voir PRISM ou Light Toolkit).
  • La couche Application contient les ViewModels, les interfaces des vues, les commandes etc.
  • La couche Domain contient des façades, des services métier et les objets métier propre à notre scope fonctionnel.
  • La couche Business Infrastructure contient les services métier réutilisés, la particularité des classes existantes ici par rapport à celles existantes au sein de la couche Domain, est cette possibilité d’être réutilisée sur d’autres solutions sans référencer les aspects métier, souvent on y retrouve des classes utilisant des types primitifs, dans un cas concret d’une application WPF on y retrouve des Converters, il peut aussi s’agir de classes Helpers techniques intervenant dans l’application. 
  • La couche Technical Services contient tous les services permettant de répondre à des besoins techniques, notez que l’accès aux données est considéré comme une fonctionnalité technique permettant d’interagir avec la structure de stockage, donc on peut aisément avoir un projet  ORM Entity Framework. On peut aussi retrouver la mise en place d’une sonde de sécurité (Identity, Principal) ou un socle de validation tel celui basé sur System.ComponentModel.DataAnnotation.

          Remarque : L’ajout d’un service WCF trouverait sa place aussi au sein de cette couche technique.

  • La couche Foundation contient tous les services techniques tels le traçage de l’applicatif (Best Practise : Entreprise Library Framework), les collections de classes.

Ci-dessous un exemple d’une solution mise en place respectant les artefacts cités ci-dessus :

 SampleSolution

GC.Collect

Poster un commentaire

Classé dans Architecture WAF

Easy Performance 2013

La brique technique Performance Visual Studio 2013 est très pertinente suite à une phase de refonte d’application pour prouver qu’il n’est pas juste question d’augmenter la qualité du code source mais que les performances suivent, pour générer des rapports de performances sur un applicatif vous pouvez suivre les étapes suivantes :
> Dans le menu Analyser, cliquez sur Lancer l’Assistant Performance.
> Accepter le réglage par défaut du CPU échantillonnage (recommandé) et cliquez sur Suivant.
> Sélectionner le projet cible, puis cliquez sur Suivant.
> Assurez vous que l’assistant est coché, puis cliquez sur Terminer.
Votre application démarre et le profileur commence à collecter les données.

Capture

Le plus important après avoir lancer votre analyse est de pouvoir décortiquer les données et prendre des décisions adéquates permettant d’éviter des problématiques de fuite mémoire ou goulet d’étranglement.
Vous disposez de deux données significatives qui sont l’inclusif et l’exclusif.

Perf

On observe une maximum de 12% de la mémoire ce qui est très intéressant en terme de temps de réponse, le facteur Inclusif indique les fonctions les plus consommatrices et couteuses, on cible le travail réalisé dans le Body et les fonctions appelées, nous dans notre cas les taches sont réalisées dans la méthode Run à hauteur de 40% et au sein des méthodes d’initialisation du constructeur à hauteur de 60%.

Le facteur exclusif cible le travail réalisé juste dans le Body, donc il peut indiquer un goulet d’étranglement si celui-ci est trop élevé, en ce qui nous concerne on observe un exclusif à 40% ce qui favorise d’autant plus l’absence d’un goulet d’étranglement,  un facteur de 100% assure un goulet d’étranglement.

GC.Collect

Poster un commentaire

Classé dans Performance, Visual Studio 2013

Easy Code Metric 2013

L’outil Code Metric permet de calculer quelques métriques importantes indiquant le niveau de maintenance du code source, la complexité cyclomatique, le niveau d’héritage, le couplage des classes ou le nombre de lignes de code.
Rien de plus facile pour lancer l’analyse code métrique, celà se fait en cliquant sur le lien Code Metric de la section Analyse, cependant le plus important est la manière d’interprêter ces données et les décisions à prendre pour réduire certaines données afin d’optimiser votre qualité.

Ci-dessous un lien décrivant exaustivement les Code métriques :

http://msdn.microsoft.com/en-us/library/bb385914.aspx

Ci-dessous un imprime écran décrivant l’exécution de Code Metric sur un de mes projets.

CM

On peut décrypter les informations avec ces indicateurs de bonne pratique :

  • Maintainability Index : Bon rating (20-100) / Moyen (10-19) / Mauvais (0-9)
  • Cyclomatic Complexity : réduire la complexité cyclomatique du code afin de faciliter sa compréhension sur le projet 2, 6 et 10, et afin de faciliter la couverture de code. (L’indice correspond a son emplacement au sein de la pile de resultats, en allant du haut vers le bas)

            Solution : Veillez à sélectionner la règle Code Analysis 1502.

  • Depth of Inheritance : il est nécessaire de réduire le niveau d’héritage à une valeur moyenne de 4

           Solution : Veillez à sélectionner la règle Code Analysis 1501.

  • Class Coupling : il est nécessaire de réduire la valeur du couplage entre les classes pour faciliter la réutilisation, le nombre magique à ne pas dépasser par classe est 9.  

          Solution : Veillez à sélectionner la règle Code Analysis 1506. 

              LineCode

  • Lines of code : On peut envisager de ne pas dépasser les 200 lignes de code par classe, cela reste un bon ratio.

Other

Aprés effectivement le fait d’implémenter des patterns de développement tels SOLID, GOF, Entreprise peut forcément vous aider à améliorer ces ratios, la mise en de tests unitaires aussi est un facteur important pour augmenter la qualité de votre code.

GC.Collect

 

Poster un commentaire

Classé dans Code Analysis, Code Metric, Tools Visual Studio

GhostDoc

Si vous souhaitez générer une documentation cohérente assez rapidement au sein de vos classes C# vous pouvez utiliser l’outil GhostDoc, la cohérence des cartouches de documentation est assurée par un fichier ".gdc".
Note : Ne pas confondre avec la génération de documentation projet, cette dernière est assurée par des composants tels SandCastle, DoxyGen etc. (Lien : http://aghilasyakoub.wordpress.com/2013/03/13/doxygen-gui-frontend/)

Elle est basée sur une bonne génération de documentation de code de dernière génération en utilisant des notions telles summary,remark, author, param etc.

Le fichier ".gdc" peut être exporté sur votre machine locale d’administration et le partager au sein du gestionnaire de code source.
Les autres postes de développeur doivent importer ce fichier et configurer GhostDoc localement.

GhostDoc est téléchargeable sur le lien suivant : http://submain.com/products/ghostdoc.aspx

Ci-dessous des écrans décrivant les étapes de configuration :

1. Accéder à la console de configuration sous la section Option.

GDOption

2. Sélectionner la section Rules pour définir vos règles

GDRules

3. Créer une règle sur une classe

GDCreateRule

4. Une fois les règles définies vous pouvez exporter votre fichier de règle gdc.

GDExport

5. Si vous souhaitez importer un fichier de règles sélectionner le lien importer.

Poster un commentaire

Classé dans C#, GhostDoc