See Sharp
Is it really just a matter of point of view ?

This silver is kinda light on the bindings : you can't do them with style !

February 2, 2010 14:00 by salfab

Depuis peu, voilà qu'il m'est donné la possibilité de jouer quelque peu avec Silverlight :

Beaucoup de choses disponibles en WPF ne le sont pas en Silverlight. Habituellement, des choses facilement contournables, mais la petite aventure du jour mérite certainement d'être consignée : 

Silverlight en tous cas jusqu'à la version 3 ne supporte pas le databinding dans les style setters.

Voyons un cas dans lequel ceci peut être embêtant :

Imaginons une ListBox dont on voudrait remplacer le pannel par défaut par un Canvas, de façon à y positionner les Items. Leur position serait définie par des coordonnées stockées dans les éléments eux-même, et exposées par une DependencyProperty.

Malheureusement, le contrôle ListBox encapsule ses éléments dans un ListBoxItem. Si l'on modifie le ItemTemplate pour ajouter les propriétés attachées Canvas.Top et Canvas.Left à l'élément racine du DataTemplate, l'effet ne sera pas appliqué.

Ceci s'explique par le fait que l'élément "racine" du DataTemplate ne sera pas directement dans le canvas : il sera contenu dans un ListBoxItem. Il faut donc définir les propriétés attachées Canvas.Left et Canvas.Top dans le ListBoxItem.

Ceci est faisable grâce à la propriété ItemContainerStyle qui contient le style du ListBoxItem.

<ListBox.ItemContainerStyle>
   
<Style>
       
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
        
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
   
</Style>
</ListBox.ItemContainerStyle>

En WPF, ceci ne pose pas de problème, on peut définir avec un Style Setter, les propriétés attachées du Canvas, en leur appliquant un Binding.

En Silverlight, malheureusement, s'il est effectivement possible de donner des valeurs fixes pour les propriétés attachées du Canvas, il n'est pas possible de procéder de la sorte pour récupérer par Binding les coordonnées auxquelles placer l'élément : comme le DataBinding n'est pas supporté dans les style setter, il faudra trouver un moyen de créer ce binding dans le codebehind.

Ceci sera faisable en sous-classant le contrôle ListBox et en créant un override de la méthode PrepareContainerForItemOverride(DependencyObject element, object item), dans laquelle il sera possible de définir le Binding par code :    

        FrameworkElement contentitem = element as FrameworkElement; 
       
Binding leftBinding = new Binding("Left"); // "Left" is the property path that you want to bind the value to. 
        contentitem
.SetBinding(Canvas.LeftProperty, leftBinding); 
 
       
base.PrepareContainerForItemOverride(element, item); 

À noter que ItemsControl encapsule également ses éléments dans un ItemContainer, mais ItemContainerStyle n'est pas exposé par ItemsControl en Silverlight...


Playing around with DirectX

September 10, 2009 14:48 by salfab

Une fonctionnalité que je voulais implémenter dans StopMo.Net était la possibilité d’effectuer des expositions multiples sur la même image afin de créer un effet de flou dans le but de rendre les mouvements plus réalistes.

Si en WPF il est très facile d’afficher à l’écran de multiples images superposées à l’aide de multiples éléments Images empilés dans une Grid, il n’est pas aussi trivial d’exporter le résultat obtenu sous forme d’un fichier sur disque.

Une option séduisante et simplissime de résoudre le problème avec WPF uniquement serait d’utiliser une VisualBrush ayant comme source un empilage d’objets Image, pour peindre ensuite une surface et la sauver dans un fichier. malheureusement, l’image ainsi produite serait alors déjà traitée par WPF, altérant l’image, modifiant sa taille et sa résolution, voire même de lisser l’image.

Le but étant ici de conserver une image ayant le moins de distorsion possible, cette option n’est pas envisageable. Deux options plus pures étaient alors possibles.

La première étant d’utiliser GDI+, la seconde d’utiliser Direct2D en conjonction avec l’API WIC de Microsoft, utilisée en arrière plan par WPF pour la gestion de rendu d’images.

Microsoft ayant sorti très récemment un wrapper (Windows7 API Code Pack) pour DirectX 10/11, Direct2D et le Windows 7 SDK. Ce wrapper inclut également (pour l’instant partiellement) WIC. Direct2D est la solution Microsoft pour la gestion d’affichage en deux dimensions visant à remplacer GDI+, et supportant l’accélération matérielle. J’ai donc choisi d’utiliser Direct2D, histoire également de découvrir cette nouvelle technologie.

Ce qu’il est important de savoir est que pour l’instant, le fameux CodePack n’implémente encore pas toutes les fonctionnalités de DirectX.

Direct3D 11.0, Direct3D 10.1/10.0, DXGI 1.0/1.1, Direct2D 1.0, DirectWrite, Windows Imaging Component (WIC) APIs. (DirectWrite and WIC have partial support)

Elles le seront cependant probablement dans le futur. Mes essais préliminaires m’ont donc mené à écrire quelques fonctionnalités manquantes notamment pour la création d’objets WICBitmap.

Un grand merci d’ailleurs à Florian pour son aide et sa patience lors des longues discussions que nous avons eu sur le sujet, et pour son Hack consistant à récupérer par réflexion les objets WIC utilisés en arrière plan par les classes WPF. Ceci afin d’éviter de devoir réécrire de nombreuses fonctionnalités encore manquantes dans le CodePack.

Le résultat est qu’il m’est à présent possible de superposer avec un niveau de transparence arbitraire plusieurs images, créant ainsi une superposition qui visera à donner une impression de mouvement sur une animation Stop Motion.


Joey doesn't share food, WCF doesn't share Types (unless you ask them nicely ?)

April 23, 2009 09:37 by salfab

Introduction 

Au menu de ce jour, un peu de WCF. Celà faisait longtemps que nous n'avions plus joué avec ce joli jouet... Il est l'heure de se remettre à l'ouvrage !

Scénario

Soit le scénario suivant :

  • un service expose un type "CompositeType" et une opération retournant une instance de CompositeType
  • un second service ayant une serviceReference sur le premier pour connaitre "CompositeType" (CompositeType est alors un ProxyObject dans le second service)
    et exposant une méthode acceptant un paramètre de type "CompositeType" (Proxy object)
  • Un client consommant les deux services, utilisant le premier pour récupérer une instance de CompositeType et invoquant une opération du second acceptant unb CompositeType comme paramètre

Pour mettre les idées au clair, voici un petit exemple de notre situation
WCFTypeSharing.zip (108,57 kb)

CompositeType provient dans tous les cas du DataContract défini dans le premier service, mais comme le second service consomme le premier et expose son propre proxy object, les namespaces ne sont pas les mêmes dans les deux cas : même s'ils seront sérialisés de la même manière, la CLR les considèrera comme deux objets différents.

Résoudre le problème

Solution 1: Forcer les namespaces des deux proxy objects à êtr eles mêmes ( éventuellement supprimer les références à double ) 

  • avec ScvUtil : utiliser la commande /namespace sur chacun des services. example : SvcUtil.exe /namespace:*,BusinessServices.Common *.wsdl *.xsd /out:Reference.cs
  • supprimer à la main les types redondants
    • Il semblerait qu'il soit possible d'utiliser SvcUtil pour générer les références de tous les services d'un seul coup sans doublons.
  • modifier les fichiers app.config en conséquences pour prendre en compte les nouveaux namespaces

Solution 2: créer une dll que nous appellerons "MandatoryModuleHandler" qui contiendra les ServiceReferences sur le service exposant le type partagé. Le second service, qui consommera des instances de ce type, reste dans l'assembly principale.

  • Le client doit dans la configuration de ses propres ServicesReferences cocher la case "reuse types in specified referenced assemblies" et s'assurer que la dll MandatoryModuleHandler soit bien cochée dans la liste !
  • Comme le dit le texte, les types réutilisés sont recherchés uniquement dans les assemblies référencées, c'est pourquoi si le type existe dans l'assembly courante (donc pas de référence) le conflit de types persistera.
    • Il semblerait qu'il y'ait un bug dans la résolution des types appartenant à des assemblies référencées si celles-ci sont déjà compilées (références sur des fichiers dll) Pour palier à ce problème, il est nécessaire d'ajouter à la solution le projet servant à compiler la dll, de cette façon, les types qu'elle contient seront correctement résolus et utilisés pour le service qui voudra consommer ces types. Si les types ont déjà été résolus avec une référence de type projet, le remplacement de celle-ci par une référence sur une dll binaire ne reproduira cependant plus directement le bug précité.
  • Mettre à jour le app.config de l'application principale pour y copier toutes les informations sur les endpoints et bindings qui auront été générés dans le fichier app.config de la librairies MandatoryModuleHandler. Le fichier app.config de MandatoryModuleHandler pourra alors être effacé.

Conclusion 

Ces deux solutions ont chacune leur avantage :

  • La première ne crée pas de fichier .dll supplémentaire et/ou ne force pas à l'ajout du projet de cette dll dans la solution : on poura dès lors l'utiliser si l'on ne possède pas les sources d'une dll référençant un service.
  • La seconde permet de tout effectuer depuis Visual Studio sans avoir à utiliser d'outils en ligne de commande.

it's PART_Ytime, baby !

August 29, 2008 12:23 by salfab

Introduction 

Aujourd'hui, jettons un oeil à ces étranges Named Template Parts que l'on peut parfois voir dans les Templates de certains contrôles, et qui sont facilement reconnaissable au préfixe PART_

Qu'est-ce que ce PART_ ?

De façon à pouvoir rendre un CustomControl hautement Templateable (Anglicisme fait maison qui signifie "un truc qu'on peut lui appliquer un template dessus"), il va nous falloir poser quelques contraintes. En effet : Si l'utilisateur de notre contrôle peut entièrement le re-templater, qui nous assure qu'un certain élément sur lequel nous nous reposons est toujours existant ?

Exemple : SalFab crée une TextBox en 3D. Ce contrôle s'appelle évidemment SalFab3DTextBox, et contient dans son template par défaut, en plus de tout l'attirail nécessaire à la gestion de la 3D, un élément TextBox qui contiendra le texte à entrer - Le nerf de la guerre. Comme SalFab désire ardemment que tout le monde utilise son contrôle, il décide de permettre au monde entier de changer le template de son contrôle. Comment être sûr que l'utilisateur utilise bel et bien un élément TextBox dans son template ? Rappellons que toute la logique du contrôle se repose sur le postulat qu'il existe un tel élément dans son template !

L'idée est de donner un nom prédéfini à cet élément ( grâce à la propriété x:Name du TextBox ), par exemple, "PART_UnderLyingTextBox". Afin de pouvoir travailler avec dans le codebehind, nous aimerions en récupérer une référence. Ceci peut se faire dans la méthode OnApplyTemplate de notre contrôle, grâce à un appel de la méthode GetTemplateChild("PART_UnderLyingTextBox"). Le paramètre de la méthode est bien entendu le nom, arbitraire, de notre élément. Il nous sera alors possible de lui appliquer la logique applicative désirée. Par exemple, enregistrer son évènement TextChanged. On pourra également tester si le retour de GetTemplateChild est null, et adapter le comportement du contrôle en conséquence.

Si le nom à donner à x:Name est bien arbitraire, l'usage veut que pour ce genre d'utilisation, l'on utilise le préfixe PART_.

Notons qu'il ne s'agit pas là d'un nom réservé, mais d'une convention de codage. Par conséquent, il sera judicieux de documenter explicitement les Parts utilisées par notre contrôle, chose qui peut être faite à l'aide de l'attribut TemplatePartAttribute

Par exemple, dans notre cas :

[TemplatePart(Name = "PART_UnderLyingTextBox", Type = typeof(TextBox))]

Notons finalement que l'attribut TemplatePartAttribute n'applique aucun comportement, mais est uniquement présent pour décrire les parts utilisées. Cet attribut ser utilisé par des outils de design pour mettre en évidence leur existence.

 Happy Templating !


Get a grip on the DataGrid - Snoop your way out of your troubles

August 22, 2008 12:15 by salfab

mi-Août 2008, un nouveau contrôle a été mis à disposition sur CodePlex en même temps que le SP1 pour la .Net Framework 3.5 et Visual Studio 2008.

Pour le moment, il s'agit d'un CTP qui est téléchargeable séparément sur CodePlex, mais sera vraissemblablement inclus dans les prochaines versions de la framework. Les sources sont disponibles, ainsi qu'une librairie binaire. .Net 3.5 SP1 est obligatoire pour utiliser ce contrôle.

De nombreux articles proposent des tutoriels pour se familiariser avec ce contrôle, cet article n'a donc pas cette vocation.

Cependant, nous allons voir comment résoudre un problème précis, et en profiter pour découvrir un nouvel outil : Snoop.

DataGrid permet une chose fort sympathique : le style alternatif, histoire de changer une ligne sur deux le style d'une ligne (DataGridRow).

Manque de bol : On s'apperçoit, lorsqu'on définit un Background ou un AlternativeBackground, que les lignes sont colorées de bout en bout d'un contrôle, alors que la surbrillance (Highlighting) pour mettre en évidence les éléments sélectionnés s'arrêtent au niveau de la dernière colonne, provocant ainsi une inconsistence : une ligne avec une couleur de fond qui va jusqu'à la fin de la "colonne de padding" (La dernière colonne vide sans en-tête ni contenu) alors que la sélection s'arrête à la fin de la dernière colonne valide.

Notre but ici est de mettre en surbrillance toute la ligne.

Première tentative :

Ajouter la définition de propriété suivante dans le tag de DataGrid :
SelectionUnit="FullRow"
Malheureusement, ça n'a pas l'effet escompté : On sélectionne effectivement toute la ligne, au lieu d'une seule cellule, mais la sélection ne se propage pas jusque sur la colonne de padding.

Seconde tentative :

Le reflexe suivant que toute personne sensée aurait serait d'utiliser un Trigger pour changer le Background de la DataGridRow lorsqu'elle est sélectionnée. Là encore : chou blanc : en analysant le code de DataGrid on s'apperçoit qu'il y a un CoerceValue sur la couleur de Background appliquée sur notre DataGridRow : il faut donc trouver un auter endroit où changer cette couleur.

C'est ici que nous nous trouvons à cours de "réflexes". Il est l'heure de sortir la grosse artillerie : Snoop. ( ou Mole, pour ceux qui préfèrent. Personnellement, ma préférence va pour Snoop.

Troisième tentative

Snoop nous permet de voir l'arbre visuel (VisualTree) de notre application, et par conséquent, de noter contrôle DataGrid. En se balladant dans l'arborescence on peut voir où se trouve les éléments graphiques qui représentent notre sélection.

Il y a probablement une multitude de façons différentes de règler ce problème. Heureusement, nous n'en avons besoin que d'une seule. L'approche que j'ai choisie ici est de modifier l'élément qui est chargé de présenter les cellules pour une ligne donnée : DataGridCellsPresenter. Comme nous sommes très chanceux, et que le code de notre contrôle DataGrid est disponible sur CodePlex, nous pouvons sans autre visualiser le template défini pour ce type dans le fichier generic.xaml (ou le .xaml relatif au thème sur lequel on veut se baser) du projet de DataGrid. Comme nous sommes vraiment très chanceux : tout se trouve dans generic.xaml : Les templates sont les mêmes pour tous les thèmes, ce qui nous évitera de devoir surdéfinir plusieurs templates pour couvrir tous les thèmes.

Petite parenthèse : Si nous avions voulu faire ce travail sur un contrôle de la framework .Net il est possible de retrouver sur la MSDN ou, plus simple, dans le programme XamlHack les templates utilisés par les widgets créés par Microsoft. Si le contrôle est un contrôle tiers sans les sources : Il sera peut être possible de s'amuser avec Reflector, et de reconstruire le xaml à partir du baml se trouvant dans les resources de l'assembly du contrôle, mais ceci dépasse le cadre de cet article.

Résolution du problème

Maintenant que nous avons identifié le type dont nous voulons changer le Template, il nous suffit de copier coller la définition existante : Elle se trouve sous forme de ressources dans un ResourceDictionary, que nous pouvons incorporer dans notre Windows.Resources ou tout autre dictionnaire de ressources accessible par notre DataGrid... et de la modifier selon nos désirs, évidemment.

Après quelques essais à le tripoter, le template est passé de :

<Style x:Key="{x:Type dg:DataGridCellsPresenter}" TargetType="{x:Type dg:DataGridCellsPresenter}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type dg:DataGridCellsPresenter}">
        <ItemsPresenter />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

à

<Style x:Key="{x:Type toolkit:DataGridCellsPresenter}" TargetType="{x:Type toolkit:DataGridCellsPresenter}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type toolkit:DataGridCellsPresenter}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                <ItemsPresenter />
                <Border Grid.Column="1">
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=toolkit:DataGridRow}, Path=IsSelected}" Value="True">
                                    <DataTrigger.Setters>
                                        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                                    </DataTrigger.Setters>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>
                </Border>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

L'idée est d'avoir un élément qui prendra toute la place disponnible (Grid) , d'y placer tout à gauche ( Première colonne ) L'élément dont la taille est faite pour correspondre aux headers des colonnes (Ce qui nous permet d'avoir une largeur de colonne de Auto pour la première) et de placer dans la seconde colonne, un élément qui coloriera le "reste" de l'espace, ici un Border.

Pour le changement de couleurs, on utilise la même approche que lors de la seconde tentative, mais puisque notre Border se trouve au dessus des DataGridRow, et que son Background n'est pas forcé à l'aide d'un CoercevalueCallback, la ligne apparaîtra comme en surbrillance sur toute la largeur du contrôle.

Mission accomplie, et ce, sans créer un nouveau contrôle ! Merci WPF, Merci les Templates !


Tips for Binding On ToolTips

July 24, 2008 14:41 by salfab

Introduction 

Mon quotidien Allemand est principalement axé sur la technologie WPF, ces temps.

Au programme d'aujourd'hui : Un outil permettant la localisation de ressources :

Charger un fichier XAML contenant un ResourceDictionnary, en extraire toutes les ressources de type sys:String, et les afficher à l'écran. L'idée est de pouvoir éditer lesdites chaines, nous allons donc les charger dans une TextBox.

Et puisqu'il est intéressant de pouvoir se rappeller quelle était la valeur par défaut : Nous voulons afficher dans le ToolTip, la valeur originale.

Implémentation 

En admettant que nous ayons un XmlDataSource déclaré dans le XAML ( ne pas oublier de déclarer aussi les différents namespaces XML !! ) nommé xmlTranslationProvider.

Pour utiliser un contrôle visuel léger, utilisons ItemsControl : Puisque nous n'utilisons pas les mécanismes de sélection d'éléments, nous pouvons nous passer de l'overhead d'une ListBox.

Nous devrons ensuite lier l'ItemSource de ItemsControl à notre XmlDataProvider, afin de définir quels seront les Items à afficher : Les éléments de type sys:String.

<ItemsControl ItemsSource="{Binding Source={StaticResource xmlTranslationProvider}, XPath=sys:String }" >

Pour définir le rendu de chacun de nos Items : Définissons le template de ItemsControl.ItemTemplate, où nous insèrerons la TextBox qui servira à la traduction.

Intuitivement, les Bindings appliqués devraient ressembler à celà :

<TextBox Name="tbTranslationField" Text="{Binding XPath=.}" Grid.Column="0" ToolTip="{Binding XPath=.,Mode=OneTime}" />

Le binding de ItemsControl.ItemsSource définissant quels seront les items, nous définissons ici comment les représenter : La propriété Text affichera la valeur du noeud, de même pour le ToolTip, à l'exception près que nous voulons que le ToolTip garde sa valeur d'origine, d'où le Mode OneTime. OneTime permet de ne recharger les données que lorsque l'application démarre, où que le DataContext est changé.

Les ennuis commencent

Malheureusement, dans les faits, à chaque fois que le ToolTip est affiché, il contient les dernières modifications apportées à la chaîne à traduire.

Pour quelle raison ?

Analysons la démarche :

Créons un nouveau TextBox dont la propriété Text possèdera un Binding identique au ToolTip ci-dessus : Le comportement est celui que nous attendions : son contenu est mis à jour une seule fois, et n'est jamais changé, en dépit du fait que la donnée liée, elle, change : Le mode OneTime fonctionne : Que se passe-t-il ?

Le TextBox est généré au lancement de l'application. il va chercher les données auxquelles il est lié, l'affiche à l'écran, et ne les touche plus.

Explications

Qu'y a-t-il de différent avec un ToolTip ?

Le ToolTip attend que le pointeur de la souris passe au dessus de la zone appropriée, puis à ce moment là, et uniquement à ce moment là, il est construit : Il va donc chercher les données auxquelles il est lié, et ne reçoit plus jamais de notification en cas de modification des données auxquelles il est lié.

Si l'utilisateur déplace la souris, le ToolTip est détruit.

Si l'utilisateur déplace la souris à nouveau au dessus de la zone sensible, le ToolTip est à nouveau reconstruit de A à Z. Il va donc rechercher les informations auxquelles il est lié, les affiche à l'écran, et ne reçoit plus jamais de notification en cas de modification des données liées.

Que se passe-t-il si l'utilisateur, entre la destruction du ToolTip et sa nouvelle création, modifie les données auxquelles le ToolTip est lié ?

Le ToolTip est créé, puis il va rechercher les données auxquelles il est lié. Mais attention, nous avons spécifié le mode OneTime, WPF possède donc un mécanisme pour s'assurer que les données liées ne doivent être chargées qu'au démarrage de l'application ou lors d'un chargement de DataContext....

Mais alors pourquoi diable, mon ToolTip change-t-il tout de même de valeur ??

La réponse est simple : Les données liées n'ont pas changé !!!

Et pourtant le ToolTip, lui, ne possède pas le même contenu ! Pourquoi ?

Tout ceci est dû au fait que nous avons fait une erreur de sémantique dans notre Binding : Nous avons en effet lié un Noeud XML à notre TextBox et à notre ToolTip, et non pas une chaîne de caractère. L'objet XmlNode en question, qui est lié à nos propriétés ToolTip et Text, n'a absolument pas été changé. Il a seulement été altéré !

Les ValueConverters très puissants de WPF ont simplement converti un noeud XML en représentation sous forme de string à notre place.

Ainsi, lorsque le ToolTip est créé après que le Noeud XML auquel il est lié ait été altéré, le mécanisme de WPF s'assure qu'il n'ait pas été changé, et le ToolTip peut sans autre lire le texte se trouvant dans le XmlNode, cependant, celui-ci a été changé.

C'est de par la nature même du ToolTip que l'on peut observer ces différences de comportement entre un TextBox qui est rendu à l'écran une fois pour toutes, et un ToolTip qui est recréé à partir de zéro plusieurs fois au cours du cycle de vie de l'application.

Résoudre le problème :

L'idée est donc d'indiquer au mécanisme du mode OneTime de s'assurer non-pas que l'objet XmlNode reste inchangé, mais bien que le texte qu'il contient reste le même ! Le texte en question est représenté par la propriété InnerText de l'objet XmlNode.

Par conséquent, nous allons modifier les Bindings de notre TextBox comme suit :

<TextBox Name="tbTranslationField" Text="{Binding XPath=., Path=InnerText}" Grid.Column="0" ToolTip="{Binding XPath=.,Mode=OneTime, Path=InnerText}" />

A noter que le même genre de subtilités survient lorsqu'une DependencyProperty de type List<T> (n'implémentant pas INotifyCollectionChanged) est altérée : Si l'on ajoute un élément à une List<T>, la propriété référencant cette liste n'est pas modifiée, car l'adresse mémoire de l'objet pointé par la propriété est resté le même, en dépit du fait que l'objet lui même ait été altéré.

En eséprant que cet article puisse aider quelques personnes à mieux comprendre les subtilités du binding.

TechDays '08 - Genève

March 17, 2008 13:55 by salfab

Un PocketPC en main, Un Portable dans le sac ( et qui y est resté tout au long des deux jours ), un bloc note et un stylo, c'est vers les TechDays'08 que je me dirigeais pour le compte de mon entreprise.

Petit compte rendu avec une partie du rapport que j'ai du rédiger pour le feedback de ces deux jours à mon retour au Labo R&D.

1.                Introduction

Les TechDays '08 se sont déroulés du 12 au 13 mars 2008. A cette occasion, trois Tracks étaient disponible, trois présentations étaient alors données simultanément, chacune sur un thème différent, en mettant en avant un des trois produits lancés simultanément par Microsoft en ce début d'année. Les thèmes des trois Tracks étaient :
  1. Développement (Visual Studio 2008)
  2. IT (Windows Server 2008)
  3. Bases de données (SQL Server 2008)

Un choix a donc dû être fait quant aux sessions auxquelles assister. Mon choix s'est porté, en accord avec les besoins de Swiss Timing et mes intérêts personnels sur les thèmes de développement et de bases de données.Les sujets suivis étaient les suivants :    

Mercredi, 12.03.2008

09:00-10:00 Session code: K100

L’édition 2008 des TechDays est une édition spéciale lancement. Pas n’importe quel lancement : peut-être le lancement le plus important de toute l’histoire de Microsoft, puisqu’il s’agit des trois composants fondamentaux de tout système informatique : Windows Server 2008, SQL Server 2008, et Visual Studio 2008. Une plateforme et des outils qui vous permettent de vous surpasser, d’où le thème « Heroes Happen {Here} ». Une infrastructure solide et fortement sécurisée, une base performante pour transformer les données en informations pertinentes, et des outils pour fournir ces informations à vos utilisateurs quand il le faut, et juste ce qu’il faut. Un grand pas vers la réalisation de notre vision : l’informatique dynamique. Une informatique robuste mais agile, prompte à fournir des solutions aux utilisateurs, et capable de s’adapter à n’importe quelle situation.

Referent:Launch
Level: All
Session plénière : toutes les nouveautés de Windows Server­, SQL Server­ et Visual Studio cuvée 2008 !
10:15-11:15 Session code: D101

Visual Studio 2008 amène des nombreuses nouveautés dans les langages C# and VB.NET, telles que l’inférence de type et les méthodes d'extension. Toutes ces améliorations constituent la fondation de LINQ. Vous verrez toutes les nouveautés du C# 3.0, puis, lors de la deuxième, vous découvrirez de LINQ. On vous montrera comme le « Language Integrated Query » vous permet d’accéder et traiter de manière unifié les différents types de données : objets, documents XML ou tables relationnelles.

Referent:Ken Casada
Level: 300
Visual Studio 2008 : les nouveautés dans les langage­s et LINQ
Session code: B101

Dans cette session nous passerons en revue les principales améliorations de SQL Server 2008 destinées à faciliter l'administration et la gestion de données de l'entreprise. Seront notamment démontrées : l'administration par règles et performance studio.

Referent:Patrick Guimonet
Level: 100
SQL Server­ 2008 : Plateforme de données d’entreprise
Session code: I101

La virtualisation de part les bénéfices économiques et techniques que sa mise en œuvre apporte est certainement la technologie les plus regardées par les exploitants et les responsables de production. Windows Server 2008 apporte en standard les différents services nécessaire à la mise en œuvre d’une infrastructure virtualisée. Cette session sera l’occasion de présenter les principales évolutions au niveau de la virtualisation de serveurs (architecture de type hyperviseur, machines virtuelles 32 et 64 bits multi-cœurs, services de haute disponibilité) et de la virtualisation de présentation au travers des nombreuses évolutions fonctionnelles concernant Terminal Services (Remote App, TS Gateway, TS Web Access, TS Session Broker et Easy Print). Si vous souhaitez en apprendre un peu plus sur Windows Server 2008 et la virtualisation cette session doit faire partie de votre agenda.

Referent:Fabrice Meillon
Level: 200
Windows Server­ 2008 et les technologies de virtualisation : Hyper-V et Terminal­ Server­
           
11:30-12:30 Session code: D102

Microsoft Silverlight est un plug-in multiplateforme et multi-navigateur orienté multimédia. Il permet la création d’applications Web riches et interactives de la nouvelle génération. Comme le WPF, Silverlight 2.0 propose un modèle de développement flexible à base de XAML et de .NET, et il s’intègre facilement avec les applications Web existantes. Les applications Silverlight fonctionnent avec la plupart des browsers sous Windows ou Mac OS. Apprenez à utiliser Microsoft Visual Studio et Blend pour créer les applications Web de la prochaine génération, à créer des interfaces avec du markup XAML et du code, à utiliser tous les nouveaux contrôles, à accéder aux données à partir d’un service Web, et à manipuler les données avec le LINQ to XML.

Referent:Ronnie Saurenmann
Level: 200
Silver­light 2.0
Session code: B102

Moins de 10% des données et documents utiles sont stockés dans des bases de données. Le reste est stocké sous forme de fichiers. SQL Server 2008 peut exploiter n’importe quel type de données: le XML mais aussi tout type de document (permet de réconciler donnés structurées et déstructurées). Enfin, il sera possible de développer des applications incorporant des fonctionnalités de géo-localisation.

Referent:Christophe Codourey
Level: 200
SQL Server­ 2008 : Au delà du relationnel
Session code: I102

La sécurité est l’un des trois piliers de Windows Server 2008. Et la listes des nouvelle fonctionnalités est longue : intégrité du code, contrôle de l’usage des périphériques, protection de l’accès réseau (NAP), contrôle du compte utilisateur (UAC), BitLocker, Crypto Next Generation, Active Directory Right Management Services, etc…

Referent:Pietro di Gregorio
Level: 200
Windows Server­ 2008 : Securité et conformité
           
13:30-14:30 Session code: D103

This session gives an overview of the Windows Live Services and explores how they can be integrated into your websites or applications to provide a powerful and differentiated experience for your users. In particular, we discuss how Live ID can be used for authentication, Virtual Earth for location-based visualization, the IM control and library for Instant Messenger functionality, the Contacts API to integrate Hotmail/Messenger contacts into your website, the Event API to create and manage your own events, the Windows Live SDK to build Quick Apps,… Windows Live represents a huge opportunity for web developers: Not only do you get access to services with hundreds of millions of active users, but you are also able to take advantage of a swathe of rich services that add instant value and differentiation to your website. Coupled with some of the most generous and clear terms of service in the business, Windows Live has the capability to turbo-charge your web development capability. If you can wait this session to gather information, dev.live.com is the perfect place to start.

Referent:Stefano Mallè
Level: 200
Windows Live Services: How to provide a powerful and differentiated experience for your users (e)
Session code: B103

SQL Server 2008, couplé au framework .NET 3.5 permet la réalisation d'applications de nouvelle génération innovantes. Pour plus de productivité, les développeurs pourront travailler avec la notion d’entité métier (au sens Entité Relation) au lieu d’utiliser celle de tables et colonnes. Ils pourront créer plus facilement des applications partiellement connectées.

Referent:Fabrice Romelard
Level: 200
SQL Server­ 2008 : Le dévelopement dynamique
Session code: I103

A nouvelle version de Windows Server nouveaux outils d’administration et de déploiement - de l’installation à l’exploitation vous découvrirez au sein de cette session les apports de Windows Server 2008.

Referent:Fabrice Meillon
Level: 200
Windows Server­ 2008 : Administration et déploiement
           
14:45-15:45 Session code: D104

Partie intégrante du nouveau Framework 3.5, LINQ to SQL va changer votre façon d'accéder aux données. Cette session a pour bût de vous montrer les bons côtés de cette première version, mais aussi les côtés qui sont moins bons, et les côtés qui sont carrément mauvais. Vous verrez les pièges courants et la façon de les éviter. Vous verrez la manière d’utiliser LINQ to SQL dans des applications ASP .NET au travers de démos, en codant et en utilisant le nouveau contrôle LINQ to SQL. Finalement, vous découvrirez comment intégrer cette technologie dans un environnement multi-tiers avec du WPF, WCP, des Smart Clients et Office.

Referent:Ronnie Saurenmann
Level: 300
Linq to SQL: the good, the bad and the ugly
Session code: B104

Dans cette session nous passerons en revue les principales fonctionnalités de SQL Server 2008 destinées la sécurisation de la plateforme, tant en termes de haute disponibilité (technologies "Always ON") qu'en terme de sécurité d'accès aux données (cryptage ...).

Referent:Patrick Guimonet
Level: 200
SQL Server­ 2008 - Secure, trusted platform
Session code: I104

Internet Information Server 7.0 (IIS 7), le nouveau serveur Web de Windows Server 2008, permet une montée en puissance des infrastructures Web pour internet ou pour les intranets. Il permet aussi de reprendre l’existant – ASP, ASP.NET et PHP – avec un minimum de modifications. Fortement intégré à Windows Server 2008, il tire pleinement parti des fonctions de celui-ci pour la sécurité, l’administration, la haute disponibilité et la montée en charge. Cette session technique est destinée aux IT professionnels, développeurs ou hébergeurs de sites Web à la recherche d’une plateforme de développement de services Web sécurisée, fiable, facile à utiliser et paramétrables pour tous les frameworks même autre que .NET.

Referent:Lionel Cau
Level: 200
Windows Server­ 2008 : La plateforme Web de la prochaine génération
           
16:00-17:00 Session code: D105

Visual Studio 2008 intègre nativement le développement d'application .NET pour Office : Visual Studio Tools for Office 2008. Le support des nouveautés d'Office 2007 et une meilleure intégration à Office 2003 est au menu. Durant cette session Nicolas CLERC mettra en oeuvre ces fonctionnalités et présentera quelques applications.

Referent:Nicolas Clerc
Level: 300
Visual Studio 2008 et le développement Office
Session code: B105

De nos jours la performance est un sujet très sensible autant pour les administrateurs que les end-users. Les compagnies doivent maintenir une performance optimal face à des volumes de données qui ne cessent de s'accroître. Pour ce faire SqlServer 2008 vous offre des nouvelles solutions tel que High Performance Query Processing Engine, Performance Optimization Tools, Resource Governor etc ... et ce pour suivre les activités des bases et serveur, pour l'amélioration des temps réponses, pour répartir et prioriser la charge des workloads et d'autres encore.

Referent:Christophe Codourey
Level: 300
SQL Server­ 2008 : Les performances
Session code: I105

Jusqu’à présent, les « Failover Clusters » offraient une solution de haute disponibilité à un prix…élevé. Avec Windows Server 2008, leur utilisation n'est plus réservée aux seules applications critiques. Venez découvrir toutes les améliorations de la cuvée 2008 : l’assistant de validation, la simplification du déploiement et de la gestion, l’élimination d’un point de défaillance unique avec le nouveau modèle de quorum, des nouveaux scénarios d'usage lorsqu'un cluster est géographiquement dispersé, l’amélioration de la sécurité et de l’évolutivité, etc. Une session à ne pas manquer!

Referent:Sébastien Pittet
Level: 200
Windows Server­ 2008 : RAS (Reliability, Availability, Serviceability)
           
17:15-18:15 Session code: D106

Le développement et l’implémentation de solutions basées sur Windows Workflow Foundation (WF) nécessitent couramment l’extension des librairies livrées afin d’implémenter des spécifications particulières clients. Cette session, qui s’adresses aux éditeurs de logiciels et au développeurs, se propose d’explorer la façon d’implémenter dynamiquement des extensions d’activités personnalisées, pour adapter à l’exécution (et non pas à la compilation) des comportements spécifiques d’une application standard. La puissance du C#3 et des requêtes LINQ est fortement utilisée. Le domaine d’application est la modélisation de processus financiers.

Referent:Christine Dubois & Bernard Fedotoff
Level: 300
Développement d'extender d'activités avec C# 3 et Linq
Session code: B106

Nous passerons en revue toutes les fonctionnalités ETL, depuis le moteur jusqu'aux services d'intégration et d'analyse. Nous verrons les Change Data Capture, Data Profiling, Lookup, Merge (Upsert) Ceci permettra de mettre en avant les nouvelles fonctionnalités et leur utilisation pratique dans des projets d'intégration des données et de datawarehouse.

Referent:Gaétan Hervé
Level: 300
SQL Server­ 2008 : ETL de bout en bout
Session code: I106

This session will describe the new Windows 2008 Active Directory roles: Active Directory Certificate Services (AD CS) Active Directory Domain Services (AD DS) Active Directory Federation Services (AD FS) Active Directory Lightweight Directory Services (AD LDS) Active Directory Rights Management Services (AD RMS) The new Read-Only Domain Controller (RODC) is focused on security and ease of deployment in a branch office scenario. We will describe how to create and administer them, its functionalities and applications. Active Directory works as a dedicated service now. We will show how to perform maintenance tasks in the Active Directory database without having to reboot the server. Now you can deploy granular password policies within your domain. We will show you how to do it. Active Directory auditing got better. Now you will have detailed records of changes in the database.

Referent:José Luis Auricchio
Level: 300
Active Directory Domain Services avec Windows Server­ 2008
           
Jeudi, 13.03.2008
09:00-10:00 Session code: D107

Cette session “break-out” vous présentera les nouvelles fonctions de Visual Studio 2008 pour les développeurs Web. Parmi celles-ci figurent les nouvelles caractéristiques de l’environnement de développement, les améliorations du framework .NET 3.5 pour ASP.NET, l’intégration d’ASP.NET AJAX à Visual Studio 2008, les essais et le débogage d’ASP.NET, les projets AJAX et JavaScript ainsi que le support amélioré des projets Silverlight. La présentation de “Microsoft ASP.NET 3.5 Extensions Preview” esquissera les perspectives futures. Ce discours sera accompagné de nombreuses démonstrations en direct.

Referent:Sascha P. Corti
Level: 200
Visual Studio 2008 for Web Applications
Session code: B107

Avec la venue de SQL-Server 2008, Microsoft apporte une nouvelle plateforme de Business Intelligence encore plus optimale et performante avec pour principaux objectifs: ** de faciliter l'intégration de données toujours plus riches et plus complexes ** de rendre les analyses de donnes et le Reporting encore plus faciles et accessibles à tous. A travers une plus grande intégration avec Microsoft Office, la plateforme SQL-server 2008 offre à tous les secteurs de l'entreprise les outils qu'il faut pour mieux comprendre ses données, et par conséquent mieux développer son business dans l'aide à la décision idoine permettant d'influencer positivement les performances de l'entreprise. L'objectif de cette session sera de présenter un tour d'horizon de l'ensemble des technologies BI de Microsoft centrées dans et autour de SQL-server 2008. Elle donnera aussi une vue d'ensemble des nouveautés de la plateforme Busniess Intelligence de SQL-Server 2008.

Referent:Abdourahmane Faye
Level: 200
SQL Server­ 2008 : La Business Intelligence pour tous
Session code: I107

An introduction to synchronisation and provisioning in ILM 2007 - where it fits into a typical environment, the types of skills you need to get the full benefit from this powerful and extensible product, some obvious and some not-so obvious uses you can put it to. Also a look forward to Microsoft's plans for ILM r2.

Referent:Carol Wapshere
Level: 300
Identity Lifecycle Manage­ment : Au jourd'hui et demain (e)
           
10:15-11:15 Session code: D108

L’objectif de cette session est d’illustrer l’utilisation de Windows Workflow Foundation (WF) et de Windows Communication Foundation (WCF) dans le cadre du développement d’une application de modélisation de processus de calcul et de consolidation dans la domaine de la finance. Comme quoi, WF va bien au-delà du simple processus de gestion documentaire ! C’est une technologie qui sera demain au cœur de la programmation par modélisation des processus.

Referent:Christine Dubois & Bernard Fedotoff
Level: 300
Applications "branchées" avec les Windows Communi­cation Foundation et Workflow Foundation
Session code: B108

Découvrez toutes les nouveautés et les améliorations qu'apporte SQL Server 2008 au data warehousing : jointure en étoile, parallélisme des tables partitionnées, GROUPING SETS, MERGE, la compression des données, etc.

Referent:Francis Incourt
Level: 300
Le Data Warehousing avec SQL Server­ 2008
Session code: I108

Présentation de System Center COnfiguration Manager 2007, la nouvelle version de plateforme de gestion de parc de Micrsoft (ex-SMSv4). La plateforme se voit complétée de nouvelles fonctionnalité et de meilleures intégrations. (OSD)

Referent:Conrad Zimmermann
Level: 300
System Center : Intégra­tion de Configuration Manage­r et Operations Manage­r 2007
           
11:30-12:30 Session code: D109

Cette session “break-out” vous présentera les améliorations que le framework .NET 3.5 compact offre aux développeurs d’applications pour la plate-forme Windows mobile. Vous découvrirez les nouveaux outils et les nouvelles caractéristiques de Visual Studio 2008, la meilleure fonctionnalité du framework .NET 3.5 compact et les toutes dernières améliorations de Windows Mobile 6. Ce discours sera accompagné de nombreuses démonstrations en direct.

Referent:Sascha P. Corti
Level: 200
Visual Studio 2008 et la mobilité
Session code: B109

Passez à l'analyse prévisionnelle avec le data mining : découvrez les méthodologies, les traitements de données ainsi que les outils de présentation.

Referent:Amaryllis Guillot-Plasse & Pierre-Louis Usselmann
Level: 300
Le Data Mining avec SQL Server­ 2008
Session code: I109

Composé d’une partie client et une partie serveur, ForeFront Security se charge de la protection de l’ensemble de votre parc informatique. Sa couverture va des postes de travail aux serveurs, dont les serveurs Exchange 2007 et SharePoint 2007. De plus, il offre une intégration forte avec les outils de gestion et on peut le déployer avec les outils habituels comme WSUS et SMS.

Referent:Pietro di Gregorio
Level: 200
Forefront Security : une protection de bout en bout
           
13:30-14:30 Session code: D110

L’objectif de cette session est de donner un ensemble d’informations pour les responsables de projets, les architectes technologiques, les développeurs et les équipes de tests afin de comprendre les avantages d’une approche ALM (Application Lifecycle Management) et comment Visual Studio Team System 2008 (VSTS 2008) fourni les outils pour supporter une telle approche. L’ALM va bien plus loin que le développement : c’est une démarche pour concevoir, piloter et délivrer des solutions de qualité.

Referent:Christine Dubois & Bernard Fedotoff
Level: 200
ALM ou Gestion du cycle de vie des applications avec Visual Studio Team System 2008
Session code: B110

Etape ultime de l’informatique décisionnelle : après la collection de données avec le data warehousing, leur analyse avec le data mining, les données sont transformées en information. Il s’agit maintenant de présenter ces informations de manière claire, concise, et, surtout, compréhensible aux utilisateurs. Le rôle de PerformancePoint/ProClarity, c’est d’expliquer « pourquoi c’est arrivé » et « qu’est ce qu’on peut faire pour l’améliorer ».

Referent:Fabrice Romelard
Level: 100
De l'analyse à la compréhension avec PerformancePoint/ ProClarity
Session code: I110

Question: Qui ne connaît pas SoftGrid ? Réponse: plus grand monde aujourd'hui... Question: Qui utilise SoftGrid ? Réponse: Avec 2 millions de licences MDOP vendues en 2007, nul doute que cette technologie a fait ses preuves en termes d'adoption Question: Qui n'utilise pas SoftGrid ? Réponse: Les sociétés qui s'interrogent encore sur la solution elle-même et ses éventuels coûts cachés. Car, en réalité, le problème avec SoftGrid, c'est que c'est ""trop beau pour être vrai!"". Cette session, accessible à tous, a pour objectif d'analyser les fonctionnalités de la dernière version de SoftGrid et de regarder ensemble leurs avantages, leurs inconvénients et leurs alternatives éventuelles. Car ce qui est sur aujourd'hui, c'est que toutes les sociétés chercheront à bénéficier des avantages de la virtualisation d'applications comme elles le font aujourd'hui avec la virtualisation de machines.

Referent:Lionel Cau
Level: 100
Microsoft Desktop Opti­mization Pack, Softgrid & Application Compatibility
           
14:45-15:45 Session code: D111

Une bonne collaboration entre les designers et les dévellopeurs est primordiale dans les projets WPF ! Durant cette session, Nicolas CLERC mettra en oeuvre les différents techniques de développement permettant a ces 2 profils de travailler ensemble de manière optimale.

Referent:Nicolas Clerc
Level: 200
Développez des applications avec le Windows Presentation Foundation et Expression Blend
Session code: B111

Quand vous avez à faire à des masses de données gigantesques, il est vital de les rendre compréhensibles et exploitables. Découvrez comment incorporer des vues dynamiques dans vos applications avec la nouvelle fonctionnalité de visionnement de données de Visio 2007. Vous verrez les connexions vers les sources de données, les affectations de données aux formes, et la mise en évidence des informations-clés avec les API.

Referent:Tony Behnam & Francis Incourt
Level: 300
Visio Professional 2007 enriche la visualisation des données des solutions BI
Session code: I111

Au cours de cette session, nous présenterons et démontrerons les nouveaux outils de déploiement de Windows Vista et l'accélérateur de solution Microsoft Deployment (évolution de BDD 2007). Nous couvrirons également les spécificités du Service Pack 1 de Windows Vista, dont les améliorations liées à la stabilité, aux performances locales et réseau, aux performance liées à la gestion d'énergie...

Referent:Christiane Soumahoro
Level: 200
Déployez Windows Vista avec les outils du SP1
           
16:00-17:00 Session code: D112

Malgré l'aisance de MOSS 2007 à la mise en place rapide et efficace d'application intranet et/ou Internet, ce dernier est bien loin de la mouvance Web 2.0. Reposant sur le Framework .NET 2.0, nous verrons au cours de cette session comment profiter des dernières technologies du monde du développeur Web : ASP.NET, ASP.NET Ajax et Silverlight. Nous traiterons, au travers de cette session, de l'intégration d'ASP.NET AJAX au sein de SharePoint, et surtout des nombreux outils mis à notre disposition comme la Librairie JavaScript, les Web Services JSON, les ControlToolkit, les UpdatePanels ... Nous en profiterons pour aborder certains ""best practices"" afin d'utiliser correctement ASP.NET AJAX dans SharePoint.

Referent:Aurélien Verla
Level: 300
Intégra­tion de Silver­light et d'AJAX dans vos applications MOSS 2007
Session code: B112

Microsoft, lors du Keynote du TechEd Europe 2007, a annoncé la mise à disposition d’un nouveau Framework de développement ainsi que d’un « Runtime » baptisé « Sync Framework » (MSF) afin de simplifier le développement de solution de synchronisation, de roaming et d’applications online ayant la capacité intuitive de fonctionner en mode hors ligne. Ce nouveau Framework vous permettra de développer des scénarios de peer-to-peer, de synchronisation entre tout type de terminaux et services ainsi que le fonctionnement avec des systèmes hétérogènes tant sur les types de Base de Données, protocoles ou stockage en tout genre.

Referent:Grégory Renard
Level: 300
Microsoft Sync Framework : synchronisez tout partout !
Session code: I112

Au travers d’une série de démos, découvrez les nouvelles fonctionnalités et améliorations de Group Policy dans Windows Vista et Windows Server 2008. Vous verrez le nouveau format de fichiers d’administration ADMX, l’interopérabilité avec les anciens fichiers ADM et la bibliothèque centrale ADMX. Vous pourrez découvrir l’utilisation de GPO locales multiples et l’intégration de GPMC (Group Policy Management Console) dans le système d’exploitation. Finalement, vous aurez droit à un tour d’horizon des technologies acquises de DesktopStandard : gestion avancée de Group Policy (GPOVault) et PolicyMaker.

Referent:Valérie Alonso
Level: 300
Nouveautés dans le Group Policy de Windows Vista et Windows Server­ 2008
           
 

 Un sujet récurrent qui est intervenu dans une majorité, sinon toutes les présentations est la technologie LINQ, le fer de lance de Visual Studio 2008, une technologie qui semble très prometteuse.

2.                Présentations

2.1.            Visual Studio 2008 : les nouveautés dans les langages et LINQ

2.1.1.     Nouveautés dans les langages

La première nouveauté mise en avant dans cette présentation concerne la migration de 2005 vers 2008. Une raison pouvant être un frein à l'adoption de la nouvelle version d'un produit est la peur de se trouver face à des problèmes de compatibilité ascendante : Un projet fonctionnant parfaitement avec une ancienne version d'un programme qui ne serait pas supporté par la nouvelle version. Microsoft supporte officiellement le Multi-Targetting. Il s'agit d'une fonctionnalité supportée, et aucunement d'un truc, ou d'une astuce. De cette façon, il est possible avec VS2008 d'utiliser un projet ayant été créé à l'aide de Visual Studio 2005 en C# 2.0 et de l'utiliser tel quel, ou si nécessaire, de le migrer instantanément vers un projet C# 3.5 pour profiter des dernières nouveautés du langage, et des nouvelles assemblies de la framework. A noter que pour le développement mobile, la conversion peut s'effectuer de la compact framework 2.0 vers 3.5, mais pas inversement, contrairement aux projets desktop. Le passage de 2005 vers 2008 se fait donc de manière tout à fait transparente pour les différents sports, et il n'est pas nécessaire d'adapter le code pour l'utiliser dans Visual Studio 2008. Il sera cependant par la suite possible de changer la framework cible pour utiliser les nouvelles fonctionnalités du langage C# 3.0.Quelques améliorations de C# 3.0
  • Propriétés automatiques : les variables sous-jascentes n'ont plus besoin d'être déclarées, le compilateur s'en charge, il n'y a plus qu'à déclarer la propriété, et définir son accessibilité ( get / set, private ou non)
  • Initialisation de propriétés de classes lors de la déclaration : on peut entre accolades {} attribuer une valeur a une propriété : new MyClass {Prop1=val1, Prop2=Val2}; Idem pour les collections { new myListItem(1), new myListItem(2)};
  • Méthodes d'extension : Permet d'attacher des méthodes à un objet sans pour autant modifier la classe qui a servi à l'instancier.
  • Inférence de type : Ce raccourci syntaxique permet d'omettre le type d'une variable qui prendra alors le type var. Il est cependant nécessaire d'instancier la variable sur la même ligne que la déclaration : Il n'y a rien de magique ici, la variable reste fortement typée. l'inférence de type nous permet seulement de ne pas avoir à taper deux fois le type ( une fois à la déclaration, et une autre fois à l'instanciation ) : Ce mécanisme est indispensable pour instancier des types anonymes pour lesquels aucune classe n'existe (dans les faits, elle existe, mais est générée par le compilateur et n'est pas du tout visible dans le code source) et qu'on ne saurait par conséquents pas quoi taper comme type à la déclaration.
  • Expressions Lambda : Le concept avait déjà été approché en C# 2.0 avec les méthodes anonymes. Les expressions lambda permettent d'en simplifier la syntaxe : la première chose à faire est de déclarer un delegate qui donnera la signature de l'expression lambda. Ensuite, on pourra déclarer une variable dont le type sera le delegate précédemment déclaré et lui attribuer comme valeur une expression lambda telle que : (x, y) => x + y Dans cet exemple, x et y ont un typage implicite (inférence de type). Le type est défini par la signature du delegate que l'on vient de créer. L'expression se trouvant après => représente la valeur de retour de l'expression lambda. On peut également avoir des expressions lambda contenant une ou plusieurs instructions avant de retourner une valeur en utilisant les accolades {} et le mot clef return. Les expressions lambda sont, encore une fois, particulièrement utiles au sein d'une requête Linq.

2.1.2.     LINQ

Linq permet d'interroger toutes sortes de données provenant de différentes sources à la façon dont on interrogerait une base de données SQL. Il existe plusieurs déclinaisons de Linq, dont Linq to objects, pour utiliser des objets .Net comme source de données, Linq to XML pour utiliser des fichiers XML comme source de données, Linq to entities pour interroger des sources données hétéroclites et Linq to SQL, de façon à pouvoir interroger une base de données MS-SQL avec une syntaxe proche du SQL, mais dont la rédaction sera bien plus aisée, car nous profiterons de l'IntelliSense et de l'analyse syntaxique / sémantique du compilateur pour faire remonter certaines erreurs au moment de la compilation et non pas au moment de l'exécution.

3.                Silverlight 2

Silverlight version 1 est à peine sortie que déjà, des beta de Silverlight 2 sont disponibles. Silverlight 1 se concentrait principalement sur des applications multimedia, faisant de la diffusion vidéo son fer de lance, et permettait le pilotage de l'interface visuelle de silverlight grâce à Javascript/Ajax dont le code était situé dans un fichier .js séparé de l'application Silverlight. Silverlight 2 change radicalement la donne en donnant la possibilité d'utiliser le langage C# pour piloter Silverlight, en gardant le code à l'intérieur de l'application. De plus, une des grandes critiques de Silverlight était le manque de support de contrôles, de templates, de styles, de positionnement relatif à la taille de l'écran, du Binding, du RSS, et d'autres mécanismes qui étaient disponibles dans WPF pour les applications de bureau. C'est une critique qui a été entendue et à laquelle l'équipe de développement de Silverlight 2 a répondu en portant sur Silverlight la quasi-totalité de ces mécanismes. Quelques absents tout de même, par exemple, les triggers n'existent pas en Silverlight, même dans sa version 2.La bêta 1 de Silverlight 2 est déjà disponible en téléchargement, alors que la bêta 2 sera disponible au cours du second trimestre 2008. Les bêta de Silverlight sont à disponsition avec une licence GoLive pour permettre l'utilisation en production pour les early adopters.Silverlight est également adopté sur un nombre de plateformes de plus en plus vaste : un partenariat entre Nokia et Microsoft assure que Silverlight sera supporté sur Symbian, sans oublier le partenariat avec Novell pour le support de Silverlight sous linux sous le nom de  Moonlight.

4.                Pièges avec la technologie LINQ

Cette séance avait pour but de chercher quels pouvaient  être les points négatifs de la technologie LINQ. Il s'agit là des hautes sphères de C# 3.5 et de sujets très pointus. Bien que cette séance ait été extrêmement intéressante, je ne m'attarderai pas en détails sur les aspects très techniques.Il s'agit des problèmes pouvant être inclus lors de l'utilisation d'applications Multi-Tiers déconnectées accédant à la même base de données, et du fait qu'il n'y ait pas de suivi des changements de la base à attaquer. Si le problème est abordé de façon trop naïve, LINQ exécutera de façon transparente sans que le programmeur ne s'en aperçoive, une multitude de requêtes SQL. Il est alors important avec des applications dans cette configuration de toujours vérifier avec le log de MS SQL les requêtes ayant été exécutées, afin de s'assurer que LINQ n'effectue pas des dizaines de requêtes SQL à l'insu du programmeur. Pour plus de détails, se référer à la présentation des techdays qui se trouvera sur le site officiel quelques jours après la fin de l'évènement.

5.                Développement Web avec ASP.Net 3.5

Au cours de cette séance, Sascha P. Corti nous a présenté les nouveautés apportées par Visual Studio 2008 et la Framework .Net 3.5 en matière de développement web. Tout d'abord, d'une manière générale, une nette amélioration concernant les performances, notamment lors du basculement de l'affichage entre design et markup ASP.Net, mais surtout, une réelle intégration du JavaScript dans Visual Studio 2008. Jusqu'à présent, il était très difficile d'incorporer du JavaScript, et pratiquement impossible de le débugger à l'aide de Visual Studio. La version 2008 change la donne et permet notamment, d'ajouter des évènements client-side en javascript, en étant intégrés à Visual Studio et à WebForms de la même façon que les postback étaient gérés dans Visual Studio 2005, à ceci près que le javascript gère cette fois les évènements client-side. Pour continuer le support de JavaScript dans Visual Studio, on notera à présent la présence d'un IntelliSense complet pour JavaScript, prenant également en compte les méthodes se trouvant dans les fichiers.js faits maison. Mais la perle au niveau du JavaScript revient certainement au debugger JS au sein de Visual Studio : Il est à présent de débugger un script JavaScript en posant des breakpoints et en exécutant pas à pas un script au travers du debugger de Visual Studio 2008.Ajax n'est pas en reste non plus puisque grâce aux ScriptManagers, il est possible de travailler avec cette technologie. Par défaut, seul un set réduit de contrôles est fourni avec Visual Studio 2008 pour développer en Ajax, cependant, un package à télécharger séparément, Ajax Asp.Net, propose une multitude d'extensions pour les contrôles ASP.Net existants. Ceux-ci sont extrêmement bien intégrés à Visual Studio. Le package intègre également des contrôles pour Silverlight.Une fonctionnalité encore en cours de développement est la notion d'Ajax History, afin de pouvoir revenir avec le bouton précédent du navigateur, non pas à la dernière adresse tapée dans la barre de titre, mais à la dernière opération effectuée sur l'interface web, même si celle-ci n'a pas rechargé toute la page, mais n'a rechargé qu'une petite partie de l'interface web grâce à Ajax.

6.                Développement d'applications mobiles avec la Compact Framework .Net 3.5

La Compact Framework apporte un gros de nouveautés pour le développement sur plateformes mobiles. Notamment, grâce à l'intégration de LINQ et de WCF, deux technologies qui, pour la première fois dans l'histoire de .Net, sont portées en même temps sur les deux versions de la framework, standard et compact. Le support de WCF comporte tout de même un bémol, puisque pour alléger la framework compact, (10% de la taille de sa grande sœur) certains providers de transports, d'encodage, et de sécurité ont été supprimés. Il est toujours possible cependant de palier à ce problème en codant ses propres providers basés sur le provider Custom. Une couche de transport qu in'existe que dans la version Compact de WCF est le transport Exchange qui ne vise que les plateformes mobiles, et qui permet d'avoir une connexion en Keep-Alive (long-lived connection) avec ActiveSync pour recevoir en entrée des informations du serveur. La compact framework annonce également un support plus riche du multimédia, notamment pour une prise en charge plus simple de l'audio avec le namespace System.Media.Une intégration en code managé de l'API système WindowsMobile pour permettre leurs utilisation depuis du code .Net, par exemple, choisir un contact, choisir une date, écrire un SMS, etc. le tout est représenté de façon 100% managée. Il est alors possible de crocher des eventhandlers sur des évènements système, et ces fonctionnalités sont exposées par le namespace System.WindowsMobile.Une nouveauté, le NotificationBroker permet même de répondre à un évènement, même si une application n'est pas chargée en mémoire : le NotificationBoker lancera l'application abonnée à un évènement système, et lèvera l'évènement approprié lorsque l'application sera chargée !L'émulateur de périphériques permet également d'effectuer des tests unitaires sur les applications développées pour la Compact Framework. Les fonctionnalités de tests unitaires sont directement intégrées dans Visual Studio 2008, et permet donc de visualiser directement au sein de l'IDE le résultat des tests, le code-coverage, etc. Grande nouvelle, les tests unitaires sont disponibles dans la version Pro de Visual Studio 2008, et plus dans la version Team System comme c'était le cas auparavant. A noter qu'il est également possible à présent de contrôler le comportement de l'émulateur depuis une autre application grâce à une API. Ceci permettra de tester le programme en cours de développement dans des cas spéciaux, par exemple, à tester son comportement en cas de batterie faible. Tout comme pour les projets standards, il est possible de faire du multitargetting avec Visual Studio 2008, à la différence près qu'avec la CompactFramework, la migration de framework cible ne peut se faire que dans un sens : S'il est possible de migrer un projet vers la compact framework 3.5, il n'est en revanche pas possible de reconvertir le projet pour la compact framework 2.0 après sa création.
SqlCompact 3.5 a également été amélioré pour offrir de meilleures performances sur les bases de données embarquées sur des périphériques mobiles.
Divers outils ont été ajoutés dans cette nouvelle mouture de la compact framework, comme par exemple la prise en charge de compression de données.

7.                Synchronisation Framework

Cette présentation donnait une vue d'ensemble de la nouvelle framework de synchronisation actuellement en cours de développement. Les champs d'application d'une telle framework sont très large, cependant, une partie de cette présentation présentait les possibilités de synchronisation entre une base de donnée satellite contenant un set réduit de données visant à être modifiées, puis resynchronisées avec la base de données mère. La Synchronisation Framework va donc bien au-delà de la simple synchronisation de fichiers et ouvre de nouvelles perspectives dans le domaine des applications déconnectées.

Your code is running even though the program is stopped (And the truth is out there)

February 14, 2008 09:15 by salfab

Récemment, je me suis trouvé face au cas fort étrange d'une application WPF donc l'interprétation du XAML par le designer générait une erreur alors que l'exécution du programme compilé se déroulait sans encombre. Phénomène normal ou paranormal ? La vérité est ici !

Tout d'abord, situons un peu le cadre du problème. Afin d'avoir un exemple simple pour illustrer le problème, j'ai créé un exemple de toute pièce.

Il s'agit d'une application WPF, et comme toute bonne application WPF, elle contient des Binding : Une TextBox qui est liée à une DependencyProperty (DP) de type int. La valeur de cet int sera située entre 1 et 7, et indiquera le nom du jour à afficher dans la textbox. malheureusement, comme nous sommes liés à un entier, WPF n'a aucun moyen de savoir que nous voulons afficher un nom de jour de la semaine.

Afin de directement couper cours aux NitPickers, je tiens à préciser qu'il s'agit ici d'un exemple un peu tiré par les cheveux mais qui a le mérite d'illustrer des problèmes du même acabit qui pourraient être rencontrés dans des contextes bien plus complexes. Dans un cas d'application réel, nous aurions utilisé l'enum DayOfWeek. Maintenant que ceci est clarifié, revenons-en au coeur du problème.

Si l'on se contente de faire un Binding entre une textbox et un entier, la représentation donnée par la méthode ToString apparaitra dans la textbox. Pour nous permettre de convertir notre entier en nom de jour de la semaine, nous allons utiliser un Value Converter.

les value converters permettent d'ajouter la tuyauterie manquante pour adapter la valeur de la source à celle que la cible attend.

Si par malheur, dans notre ValueConverter, nous utilisons un objet qui n'a pas de valeur par défaut, ou n'a pas été instancié par le constructeur d'une ressource déclarée dans le XAML - Les ressources déclarées dans le XAML sont également instanciées, et ce, même en mode design - la compilation du projet en cours se passera sans encombres, l'exécution également, mais le designer ne pourra pas afficher la fenêtre du programme à l'écran et ajoutera une erreur dans la fenêtre ErrorList. L'erreur qui sera mentionnée peut prendre plusieurs formes. Il s'agit généralement d'une erreur de référence nulle sur un objet, mais il arrive parfois d'avoir quelques surprises. Nous verrons en détails pourquoi. Si nous naviguons jusqu'à a portion de code concernée, nous verrons qu'elle se trouvera dans le XAML, sur l'élément auquel nous avons appliqué un Binding.

Pourquoi donc notre code fonctionne-t-il au runtime, et pas en mode design ? 

Dans le projet d'exemple attaché, nous avons initialisé un tableau de chaînes de caractères dans le constructeur de App. Ce constructeur, n'a aucune raison d'être exécuté par le designer puisqu'aucune application n'a été instanciée, jusqu'ici, rien de surprenant. Un comportement que les développeurs de contrôles utilisateurs sous winforms auront certainement déjà rencontré est le fait que lors du design d'une application utilisant un contrôle utilisateur, le contrôle vit. Il possède son propre comportement en mode design, et d'une certaine façon, il est, lui, déjà en cours d'exécution.

En ce qui concerne le Binding en WPF, il s'agit du même phénomène : Le fait de permettre l'affichage à l'écran en live des modifications de notre interface graphique implique qu'une certaine logique applicative décrive la façon dont ces modifications seront reflètées. Dans la plupart des cas, cette logique applicative est incluse dans la framework .Net et est tout à fait transparente pour le développeur, cependant, dans noter cas, nous utilisons une fonctionnalité avancée pour nous permettre de crocher notre propre logique applicative dans le processus de rendu.

Afin de pouvoir continuer à reflèter les changements lors du design de façon cohérente, le designer va prendre en compte notre ValueConverter, et l'exécuter. Si celui-ci contient un bug, une exception sera générée. Généralement, il s'agit d'une erreur de type Object reference not set to an instance of an object, mais dans certains cas, l'erreur mentionnée peut être d'un autre type, par exemple, une erreur de casting. Ceci s'explique par le fait qu'au lieu d'être levée et affichée dans une fenêtre d'exception comme au runtime, elle sera affichée dans la fenêtre ErrorList. Celle-ci ne permettant pas de naviguer dans les InnerExceptions, elle affiche uniquement l'exception de niveau le plus élevé. Le choix de représenter ces erreurs dans la fenêtre ErrorList n'est pas anodin. En utilisant cette représentation, il est possible de signaler plusieurs erreurs simultanément, chose qui ne serait pas possible avec l'affichage séquentiel de plusieurs fenêtres d'exceptions, et qui pourrait être réellement handicapant dans le cas où un nombre important d'erreurs serait commis.

Il existe diverses manières de résoudre ce problème :

  • La première, qu'il est recommandé d'adopter, est de revoir le design de l'application : Les cibles de Binding sont généralement des DependencyProperties. Il est également possible d'utiliser des collections ou des propriétés qui implémentent INotifyPropertyChanged ou INotifyCollectionChanged. Dans ce cas, il est recommandé d'opter plutôt pour une DependencyProperty, qui permettent, elles, de définir une valeur par défaut. Il conviendra de ne pas choisir la valeur null comme valeur par défaut, bien évidemment.
  • Il n'est malheureusement pas toujours possible de changer le design de son application sans remettre en cause une grande partie du code de l'application. Il existe donc une autre façon de procéder, moins élégante, mais qui peut parfois sauver des vies : De la même façon qu'en WinForms il existe la propriété DesignerMode, WPF tient à jour une DependencyProperty IsInDesignMode, accessible par la méthode GetIsInDesignMode. Cette méthode fait partie de la classe DesignerProperties.

En attachement, un petit projet Visual Studio 2008 dont certaines portions de code sont en commentaires, N'hésitez pas à vous amuser à commenter / décommenter les différentes portions du code pour mettre en action les différents comportements.

XFiles.zip (12,58 kb)


WPF 3D - With your feet in the air, your head on the ground

February 12, 2008 13:20 by salfab

Avec WPF, il n'a jamais été aussi facile d'incorporer de la 3D dans une interface utilisateur. Il s'agit là d'un réel rendu 3D géré en DirectX, et très bien intégré aux composants d'interface utilisateur. Il est par exemple possible de rendre l'aspect d'un bouton en tant que cube 3D, le tout accéléré matériellement. L'intégration est même tellement simple en comparaison d'une utilisation traditionnelle en DirectX, que les novices seront tentés de se plonger rapidement dans la création de scènes 3D sans s'attarder sur les bases du rendu 3D. Pourtant, certains concepts ne devraient pas passer à la trappe. c'est notamment le cas des rotations de caméras.

En jouant avec la propriété LookDirection d'une caméra, il peut arriver que la scène disparaisse brusquement de l'écran. Généralement, ce phénomène se produit lorsque la LookDirection pointe sur un vecteur 100% vertical (0,1,0) ou (0,-1,0). Si l'on poursuit la rotation, la scène réapparaitra, mais inversée, comme au travers d'un miroir.

 À première vue, ceci a tout l'air d'un bug.

Premier réflexe : Il y'a un bug dans WPF
Second Réflexe : Il y'a quelque chose dans WPF que je n'utilise pas correctement.

Il existe une seconde propriété qu'il est nécessaire de gérer lors d'une rotation d'une caméra.

LookDirection ne permet que d'indiquer quel est la direction dans laquelle la caméra pointe, mais rien n'indique où se trouve le haut et où se trouve le bas.

UpDirection permet de spécifier un vecteur qui indiquera le haut.

Explications :

Par défaut, le haut se trouve être un vecteur vertical. Pour comprendre ce compoertement, il va nous falloir faire appel à nos vagues souvenirs de mathématiques.

UpDirection et LookDirection n'ont pas nécessairement besoin d'être perpendiculaires. WPF va automatiquement calculer le produit cross entre le vecteur LookDirection et le vecteur UpDirection.

Si, par un jeu de rotations, le vecteur de la direction à regarder et le vecteur indiquant le haut sont confondus, le produit Cross sera nul et on ne pourra déterminer aucune composante perpendiculaire au vecteur LookDirection. Pour cette raison, le résultat du rendu est indéfini, et la scène n'est pas affichable.  LookDirection passera de l'autre côté du vecteur, et le

En poursuivant la rotation, si le vecteur UpDirection n'est pas mis à jour, il aura pour effet d'indiquer la direction précédemment considérée comme le bas en tant que nouvelle direction du haut.

Il n'y a donc pas de bug à ce niveau là dans WPF, juste un manque de connaissance en ce qui concerne le positionnement des caméras.

 Source : WPF Unleashed,Nathan Adler, p.427


Tags: , ,
Categories: Techie Thingies
Actions: E-mail | Permalink | Comments (60) | Comment RSSRSS comment feed

Self-Hosted WCF Architecture

January 30, 2008 17:49 by salfab

Introduction

Jouons un peu avec WCF. 

Aujourd'hui, but de la manoeuvre : Piloter depuis une application (cliente) l'interface graphique d'une autre application (serveur).

 Tout d'abord, il est important de comprendre les concepts de base:

Un service WCF sera composé d'une interface. Cette interface établira le contrat que le service doit absolument respecter. Puis vient le service lui-même qui implémentera l'interface et ainsi, respecter son contrat.

Jusque là, rien de bien compliqué. Visual Studio 2008 permet même de créer un projet de type "Service WCF".

Par défaut, lors de la création d'un service WCF, l'interface et la classe d'implémentation sont créés dans le même projet. Ceci n'est pas toujours la configuration idéale, nous verrons pourquoi par la suite.

Pour notre exemple, nous allons avoir besoin de deux projets de type application: L'un affichant une interface graphique, et la seconde, en ligne de commande, permettant d'intéragir avec la première. Les interactions se feront au moyen d'un service WCF qui sera défini par un troisième projet de type Class Library, et qui pourra êter créé à partir du Wizard de nouveaux projets en choisissant un projet de type WCF Service. Nous considèrerons l'application graphique comme étant le serveur WCF, l'application en ligne de commande comme le client WCF, et le troisième projet comme étant le Contrat définissant le comportement du service. Remarquez que le serveur WCF opèrera au sein d'une application tout à fait standard, et non pas sur IIS. (D'où le Self-Hosted du titre de ce post)

Il est impératif que les deux parties aient connaissance de la nature du service qui leur permettront de communiquer. Comme nous utilisons WCF, il existe plusieurs approches pour obtenir le même résultat. Concernant le serveur, il n'y a qu'une seule façon de faire les choses correctement : Il s'agit de référencer le projet de Contrat, puis d'y implémenter l'interface qu'il contient. Concernant le client, voici les deux façons que nous avons retenues : La première consiste à référencer une assembly compilée. La seconde se résume à n'ajouter dans le projet client qu'une référence sur le fichier source de l'interface se trouvant dans le projet de Contrat, grâce au menu Add Existing Item, puis en choisissant Add as Link dans la boîte de dialogue qui apparaît.

Pour ce qui est des avantages et des inconvénients de chacune de ces solutions, nous aborderons le sujet en détails à la fin de cet article.

Le Contrat

La première chose à faire est de spécifier le comportement du contrat qui définira le service WCF. Implémentons alors l'interface de notre service. Par défaut, dans un nouveau projet de type service WCF ce fichier se nomme IService1. Bien sûr tout le monde a ses petites habitudes. Pour ma part, ma convention de nommage est la suivante : Concernant l'interface - la définition proprement dite du contrat - il s'agira de IxxxContract. Pour ce qui est de l'implémentation de cette interface, elle se trouvera dans une classe nommée XxxContract, les xxx représentant bien évidemment un libellé distinctif.

Il existe une multitude d'options concernant la façon dont se comportera un service WCF face à des connexions simultannées, la possibilité de gérer des requêtes statefull, ou encore la gestion du multithreading. Nous ne nous attarderons pas sur ces comportements. nous utiliserons donc la plupart des options par défaut. La MSDN présente un complément d'information complet à ce sujet.

IxxxContract

Cette interface se présente comme une interface C# tout à fait standard. Il s'agit donc de définir les méthodes et les propriétés à respecter pour toutes ses implémentations. WCF nécessite tout de même certaines informations supplémentaires pour connaître quelles seront les méthodes que le serveur pourra exposer au client, et pour identifier le contrat du service. Ceci s'effectue au moyen d'attributs (ServiceContractAttribute et OperationContractAttribute) Le premier identifiera une interface comme étant un contrat de service, alors que le second permettra d'indiquer à WCF quelles méthodes doivent être considérées comme Opérations du service. Les opérations ne sont ni plus ni moins que les méthodes d'un service qui seront consommables par un client. Il est dès lors possible de forcer une implémentation du service à contenir une méthode sans qu'elle ne soit exposée au client en ommettant simplement l'attribut OperationContractAttribute.

[ServiceContract]
public interface IxxxContract
{ 
        // TODO: Add your service operations here
        [
OperationContract]
        void MyFirstOperation(MyCompositeObject myObject);
}

Nous pouvons remarquer que nous utilisons ici un objet composite comme paramètre d'entrée de l'opération MyFirstOperation. Cet objet doit également être connu par le client ainsi que le serveur. Il est donc nécessaire de définir le contrat qui régit cet objet. Ajoutons donc la classe suivante :

[DataContract]
public class MyCompositeObject
{ 
        [DataMember]
        public string Foo{ get; set; }

        [
DataMember]
        public DateTime Bar{ get; set; }
}

DataContractAttribute Définit un contrat de donnée : Il permet d'identifier la classe en question comme un objet, qui devra être sérialisable, afin d'être utilisable dans un service WCF. Cet objet contiendra donc un ou plusieurs champs qui seront exposés ou non par le service. Afin de définir quels champs devront être exposés, il convient de les marquer à l'aide de l'attribut DataMemberAttribute.

Notre contrat est à présent clairement défini. Passons à présent à l'implémentation du corps des opérations.

XxxContract

Cette classe représente l'implémentation du service lui-même. Elle se trouve par défaut dans le même projet que l'interface IxxxContract, mais peut très bien se trouver dans un autre projet, du moment que l'interface qu'elle implémente peut être résolue en ajoutant les références adéquates. Une raison pour séparer la classe de son interface pourrait d'imaginer plusieurs implémentations différentes. Par exemple, une version Self-Hosted et une auter implémentation pour une utilisation Web-based du service WCF. L'implémentation serait alors différente, et il incomberait à chaque hôte du service d'implémenter sa propre logique métier en respectant le contrat établi. Il peut également être plus agréable, pour des raisons moins nobles, de préférer implémenter le service dans le projet Serveur pour éviter des problèmes de références circulaires. Dans notre exemple, le projet serveur référence le projet de Contrat qui, s'il veut pouvoir modifier un élément de l'interface graphique du serveur, doit en posséder une référence. Ceci n'est malheureusement pas possible, car nous nous trouverions face à une référence circulaire.

Afin de palier à ce problème, il existe deux possibilités. La première, la moins élégante, serait de déplacer la classe d'implémentation du service dans le projet Serveur. La seconde, celle que nous utiliserons ici, consiste à créer un évènement dans la classe d'implémentation. De cette façon, dès qu'une opération devant manipuler un élément du projet serveur est appelée, elle lèvera un évènement en fournissant les éventuelles informations nécessaires via un objet dérivé de la classe EventArgs.

Nous voyons donc que cette solution nous impose de créer un delegate, un event, et une nouvelle classe représentant les arguments à passer à l'évènement en question. L'avantage est que le code est mieux découplé, plus flexible, et permet d'accrocher plusieurs delegates en réponse à un seul évènement. Il faudra bien évidemment veiller à s'abonner à l'évènement du côté serveur, et ce, dès l'hébergement du service WCF.

Une note à ce propos est que si le service est exécuté en mode Singleton, il sera possible de récupérer l'instance du service grâce à la propriété SingletonInstance de la classe ServiceHost. Dans le cas contraire, notre évènement devra être statique, afin de pouvoir être le même pour toutes les instances du service hébergé.

Le Client

Nous allons poursuivre à présent avec l'implémentation du client WCF. Un client WCF est généralement composé de deux parties fondamentales. La consommation du service, et sa configuration.

Si la consommation d'un service WCF se présente comme une application C# habituelle, la configuration du service introduit un concept jusqu'alors relativement marginal. Il s'agit d'un fichier xml accompagnant l'exécutable, et qui se chargera de fournir à l'application les données relatives à l'adresse de l'hôte WCF, la manière dont la couche de transport est gérée, et le contrat à utiliser pour le service WCF à consommer. Il est à noter qu'un tel fichier de configuration est également présent du côté serveur, mais avec un contenu légèrement différent, pour définir les besoins spécifiques à l'hébergement du service WCF.

Consommation

La consommation d'un service WPF se fait relativement facilement. Le concept est de créer un canal menant au service hébergé. Pour ce faire, nous utiliserons une usine à cannaux -ChannelFactory<T>. La première étape est de créer une ChannelFactory. Il s'agit là d'une classe générique, nous pourrons donc choisir sur quel contrat seront créés les cannaux fabriqués par l'usine.

ChannelFactory<IxxxContract> factory = new ChannelFactory<IxxxContract>("xxxEndpoint");
IxxxContract client = factory.CreateChannel();

Remarquons le paramètre du constructeur de ChannelFactory<IxxxContract> : Cette chaîne de texte identifie un endpoint. L'usine ainsi créée fabriquera des cannaux visant le endpoint spécifié. La définition du endpoint en question sera détaillée dans le prochain paragraphe, Configuration.

Après avoir appellé la méthode CreateChannel() de notre usine, nous obtenons une instance de IxxxContract, ou plus précisément, une instance de la classe d'implémentation du service hébergé sur l'adresse désignée par le endpoint.

cette instance peut alors être utilisée pour appeller les opérations du service WCF, comme l'on appellerait de simples méthodes sur un objet local.

MyCompositeObject myObject= new MyCompositeObject ();
client.MyFirstOperation(myObject);

Voyons à présent comment se présente ce fameux endpoint.

Configuration

Il s'agit là d'un simple fichier XML, généralement nommé App.config pour des applications Windows, ou Web.config pour des applications web. Il peut être composé de diverses sections, en particulier pour le cas des applications web, qui utilisent ce système depuis les débuts d'ASP.Net pour une multitude de paramètres, comme des connectionstrings de base de données par exemple.

Pour notre application client, le fichier App.config sera relativement succint. Les points important sont concentrés dans le tag endpoint.

<system.serviceModel>
     <
client>
          <
endpoint name="xxxEndpoint" address="http://localhost:2008/ArbitraryUserFriendlyName" binding="wsHttpBinding" contract="IxxxContract" />
     </
client>
</system.serviceModel>

La propriété name permet de nommer notre endpoint afin de pouvoir le référencer lors de la création d'une ChannelFactory. Nous retrouvons donc ici le même libellé que celui fourni au constructeur de notre usine à cannaux.
la propriété address identifie l'adresse du serveur chargé d'héberger le service.
la propriété binding indique la façon dont sera gérée la couche de transport. Dans noter cas, nous allons communiquer avec le serveur à la façon d'un WebService en passant par le protocole HTTP.
et finalement, la propriété contract indiquera à la framework quel est le contrat à utiliser pour ce service.

Notons qu'il est possible d'implémenter et de tester le client avant le serveur, car Visual Studio permet d'héberger temporairement le service WCF, s'il est référencé en tant que tel par le projet Client.

Le Serveur 

Tout comme le projet client, le projet serveur est composé de deux parties fondamentales qui sont cette fois-ci l'hébergement et la configuration du service.

Hébergement

L'hébergement s'effectue de façon très simple. La classe ServiceHost permet d'encapsuler un service, et de l'héberger grâce à sa méthode Open() en étant totalement transparent quant à la gestion des connexions et les instances concurrentes du service.

ServiceHost sh = new ServiceHost(typeof(XxxContract));
sh.Open();

Configuration

Comme pour le client, il s'agit d'un fichier au format XML. les informations importantes se trouvent cette fois-ci dans les tags service et endpoint.

<?xml version="1.0" encoding="utf-8" ?>
  <
configuration
>
    <
system.serviceModel
>
      <
services
>
        <
service name="XxxContract"
>
          <
endpoint address="http://localhost:2008/ArbitraryUserFriendlyName" binding="wsHttpBinding" contract="xxxNameSpacexxx.IxxxContract"
/>
        </
service
>
      </
services
>
    </
system.serviceModel
>
  </
configuration>

Par le biais du tag service et de sa propriété name, il nous est possible de définir la classe d'implémentation du service à utiliser.
Concernant le tag endpoint, ils ont la même vocation que pour leur homologue du côté client.
Notons tout de même qu'il est possible de définir un chemin complet en spécifiant le namespace en plus du nom d'une classe ou d'une interface, comme ici, dans la propriété contract du endpoint.

Assemblies or Linked Items - Pros & Cons

Nous avons vu qu'il existe deux façons pour un client WCF de référencer le contrat d'un service. L'une référence une assembly compilée, l'autre référence un code source. Les conséquences qui en découlent sont les suivantes :

Maintenance

Pour ce qui est de la maintenance, il est préférable d'utiliser une référence sur une assembly binaire. En effet, si le projet venait à être séparé et développé par deux personnes différentes, les fichiers ajoutés en tant que liens pointeraient sur un lien brisé. Il serait alors nécessaire d'utiliser un logiciel de versionning, mais surtout, de maintenir à jour non seulement le projet Client, mais également le projet Contrat.

Références Additionnelles

Si comme dans notre cas, le projet Client ne contient pas toutes les assemblies permettant la sérialisation d'un contrat WCF, il sera nécessaire de les ajouter dans le cas de figure d'une référence sur la source de l'interface. Au contraire, dans le cas d'une référence sur l'assembly du projet Contrat, celle-ci étant déjà compilée, elle contient déjà tout ce qui est nécessaire à la sérialisation des messages du service.

Dès lors, pourquoi opter pour la solution d'une référence sur la source de l'interface, si elle apporte tous ces inconvénients ?

Nombre d'assemblies réduit

En référençant l'interface du service dans le client sous forme de lien sur sa source, il devient alors possible de s'affranchir du projet Contrat, et d'intégrer directement l'interface dans le projet Serveur, éliminant ainsi la nécessité t'avoir une dll supplémentaire tant du côté client que du côté serveur. Cependant, comme toute librairie compilée de façon statique (car c'est bien de celà qu'il s'agit) la maintenance est moins flexible dans le sens où si une modification intervient sur le contrat, il sera alors nécessaire de recompiler les deux applications alors que dans une configuration avec trois projets, le client n'aura pas à être recompilé. Seule sa librairie de Contrat devra être remplacée.

Il est donc fortement conseillé d'opter pour une référence sur l'assembly de Contrat.

Conclusion

C'est ici que s'achève mon premier post technique. J'ai essayé de retranscrire ici mes premiers pas en WCF. Cette technologie semble très prommetteuse, notamment concernant la possibilité de configurer le mode de transport simplement en modifiant un fichier de configuration xml. Il devient alors possible d'imaginer des applications ayant le même code mais optimisées pour différentes applications, par exemple, on pourrait imaginer dans notre cas, faire une application amenée à n'être exécutée qu'en local et éviter tout l'overhead des connexions TCP/IP et du protocole HTTP en utilisant des named pipes, sans recompiler nos applications, simplement en changeant le binding des endpoints définis dans les deux fichiers XML.


Tags:
Categories: Techie Thingies
Actions: E-mail | Permalink | Comments (182) | Comment RSSRSS comment feed