Blog de Julien Dollon (MVP)

Project Manager / Architecte / Formateur

Julien Dollon

Architecte et formateur pour I'FORM/Exakis et Full Professor SUPINFO.

Responsable de la communauté Dotnet-France, Scrum Master pour le projet AHEAD ainsi que nommé Most Valuable Professional, je participe activement à la communauté Microsoft.


 

Mon CV de Consultant/Formateur .NET

Mon Transcript de Formateur .NET

J'interviens en consulting et formation sur les technologies .NET, ALM/TFS, Agilité/Scrum, SharePoint et SQL Server





 
 
 
 
Official INETA Logo
 
IForm


[Silverlight4] Mise à jour du White Paper (Inclus MEF)

Bonjour à tous,

Petit post pour mettre à jour mon livre blanc sur Silverlight 4.

Il ne manque plus que la partie sur WCF RIA Services mais je pense la faire séparément.

J’en profite pour vous annoncer qu’une série d’article sortiront sur ce blog à propos de SharePoint 2010 dans les semaines à venir et vous retrouverez mon article sur Silverlight 4 dans le prochain programmez !

En attendant, voici l’URL du white paper:

Télécharger le livre blanc sur Silverlight 4

Et mon livre aux éditions ENI sur Silverlight 4:

51Ur3M7lR9L._SS500_

Ou bien la version HTML:

1 Introduction

image5

A l’occasion de la PDC 09, Microsoft a mis en ligne le 19 Novembre 2009 la nouvelle version en bêta de Silverlight.

Cette nouvelle version de Silverlight s’appuie sur la version 3 et améliore celle-ci sur plusieurs plans (ajout de composants & fonctionnalités).

Actuellement la version est la Bêta 1 et 45% des ordinateurs dans le monde ont installé au moins Silverlight 2 (contre 98% pour Flash).

1.1 Historique des versions

Notez qu’entre la version 1 et 2 de Silverlight la CLR est différente. Silverlight 4 par exemple peut exécuter du Silverlight 2 et 3 mais pas la version 1.

image6

1.2 Se former à Silverlight 2 et 3

Avant d’attaquer Silverlight 4, il convient de maitriser Silverlight 2 et 3.

Pour cela, Dotnet-France met à disposition des cours gratuits :

Silverlight 2 :

· Introduction à Silverlight

· Les Contrôles

· Customisation

· Gestion d’évènement et Commandes

· Les animations

Pour Silverlight 3 je vous conseille le livre blanc que j’ai écrit disponible ici.

1.3 Télécharger les outils

Avant de commencer ce tutorial il faut vous munir des différents SDK, Framework ou logiciel pour Silverlight 4.

· Silverlight 4 SDK

· WCF RIA Services

· Blend 3 Preview for .NET 4

· Silverlight 4 Documentation

· Silverlight 4 Toolkit

· Visual Studio 2010 Beta 2

· Silverlight 4 Training Course Offline Download

1.4 Les sources utilisées pour ma recherche

Pour écrire ces quelques pages je me suis appuyé avant tout sur les sessions de l’événement PDC de Microsoft.

Ainsi que des articles sur channel 9 et Tim Heuer.

2 Améliorations générales

2.1 Meilleur support des navigateurs & Performances

Microsoft annonce le support du navigateur google Chrome© en résolvant certains bugs d’affichages et améliore les performances de Silverlight :

· Les applications s’ouvrent 30% plus vite qu’en Silverlight 3

· Les applications s’exécutent 100% plus vite qu’en Silverlight 3

· Toujours seulement 10 secondes pour installer le plug in

2.2 Le clic droit de la souris

En Silverlight 2 ou 3, nous utilisions l’injection JavaScript dans notre DOM pour capturer le clic droit de la souris et ouvrir un menu contextuel.

Il est mis à la disposition du développeur des événements MouseRightButtonUp et MouseRightButtonDown que nous pouvons utiliser pour afficher/cacher un conteneur.

private void Button_MouseRightButtonUp(object sender, MouseButtonEventArgs e)

{

}

image7

2.3 Du contenu riche

Un nouveau contrôle s’est ajouté à la toolbar de Visual Studio : RichTextArea.

Ce contrôle peut contenir du contenu riche tel que du texte avec différente police, une image, une vidéo ou tout autre contrôle. On peut copier des éléments riches d’office, de page web…

RichTextArea manquait cruellement aux applications d’entreprise et il fallait souvent contourner le problème en achetant un contrôle payant.

Exemple :

<RichTextArea IsReadOnly="True">
            
            <Paragraph FontFamily="Arial"
                       FontSize="36"
                       FontWeight="Bold"
                       TextAlignment="Center"
                       TextDecorations="Underline">
                Hello Word
                <LineBreak />
                <Hyperlink NavigateUri="http://microsoft.com">Click Here</Hyperlink>
                <LineBreak/>
                <InlineUIContainer>
                    <Button Content="Click Me !" Height="30" />
                </InlineUIContainer>
                <LineBreak />
                
            </Paragraph>
        </RichTextArea>

image8 

2.4 Globalisation

30 nouvelles langues sont supportées (l’arabe, le thaï..) ainsi que le support bi-directionnel.

Par exemple ce bouton sera correctement interprété :

<Button Content="قفز الثعلب البني السريع فوق الكلب الكسول."/>

image9

L’utilisation de FlowDirection sur n’importe quel contrôle nous permet d’écrire de gauche à droite ou de droite à gauche (par défaut).

<Button FlowDirection="LeftToRight" Content="قفز الثعلب البني السريع فوق الكلب الكسول."/>

2.5 Les impressions

Silverlight 3 a apporté une classe appelée WriteableBitmap qui aide les développeurs à contourner le problème du non gestion des impressions.

Ce processus est amélioré dans Silverlight 4 en proposant l’accès à Print Document Dialog

Pour vos impressions, deux techniques sont possibles : réaliser un screen d’un composant de votre IHM ou générer un état indépendant du contrôle le représentant.

Exemple avec l’impression de la fenêtre courante :

private PrintDocument print;

public MainPage()

{

// Required to initialize variables

InitializeComponent();

print = new PrintDocument();

print.StartPrint += print_StartPrint;

print.PrintPage += print_PrintPage;

print.EndPrint += print_EndPrint;

}

private void Button_Click(object sender, RoutedEventArgs e)

{

print.Print();

}

void print_EndPrint(object sender, EndPrintEventArgs e)

{

MessageBox.Show("Fin d'impression");

}

void print_PrintPage(object sender, PrintPageEventArgs e)

{

e.PageVisual = this;

e.HasMorePages = false;

}

void print_StartPrint(object sender, StartPrintEventArgs e)

{

MessageBox.Show("Début d'impression");

}

La méthode Print du PrintDocument lance un PrintDialog comme ci-dessous :

image10

Il existe plusieurs événements pour savoir où en est l’impression. StartPrint/EndPrint qui interviennent au début et à la fin de l’impression. PrintPage permet de fournir les données à imprimer (ne pas oublier de mettre e.HasMorePage à faux pour éviter les boucles infinies).

2.6 Drag and drop de l’OS à l’application Silverlight

Que l’on soit en OOB (Out Of Browser) ou pas, Silverlight 4 supporte le drag and drop de l’OS vers nos applications.

Fini les boutons « Parcourir » pour télécharger un fichier ou ouvrir un document, l’expérience utilisateur est accrue et la barrière entre application RIA (Rich Internet Application) et RDA (Rich Desktop Application) s’affine de plus en plus.

Plusieurs événements et une propriété font leurs apparitions :

· Drop : Evénement qui se déclenche lorsqu’on dépose un objet sur le contrôle

· DragEnter : Evénement qui se déclenche lorsque la souris passe sur le contrôle avec un objet à glisser-déposer

· DragLeave : Evénement qui se déclenche lorsque la souris quitte le contrôle sans avoir lâché l’objet

· DragOver : Evénement qui se déclenche lorsque la souris est au-dessus du contrôle avec un objet à déposer. L’événement est soulevé à chaque modification de position de la souris

· AllowDrop : Propriété à mettre à vrai si on souhaite utiliser le Drag and Drop

<Grid x:Name="LayoutRoot" Background="White" AllowDrop="True" Drop="img_Drop">

<Image x:Name="img" />

</Grid>
private void img_Drop(object sender, DragEventArgs e)

{

FileInfo[] fichiers = 

(FileInfo[])e.Data.GetData(DataFormats.FileDrop);

foreach (var item in fichiers)

{

MessageBox.Show(item.Name);

MessageBox.Show(item.Extension);

}

//On affiche le premier fichier

BitmapImage sourceImage = new BitmapImage();

sourceImage.SetSource(fichiers[0].OpenRead());

img.Source = sourceImage;

}

2.7 Validation

En Silverlight 3, nous avions à notre disposition une nouvelle gestion d’erreur venant tout droit du Silverlight Toolkit qui consistait à soulever des exceptions côté classe métier et d’afficher un message d’erreur dans l’IHM.

Silverlight 4 améliore cette gestion d’erreur en proposant deux nouvelles interfaces IDataErrorInfo et INotifyDataErrorInfo.

IDataErrorInfo force le binding à utiliser un accesseur « this[] » pour parcourir les propriétés. Cela permet de faire la gestion d’erreur dans un accesseur à part. La propriété Error doit être utilisée pour par exemple créer un ErrorSummary en fin de formulaire.

Exemple avec une classe Client :

public class Client : IDataErrorInfo, INotifyPropertyChanged

{

private string nom;

public string Nom

{

get { return nom; }

set { nom = value; OnPropertyChanged("Nom"); }

}

#region IDataErrorInfo Members

public string Error

{

get { return ""; }

}

public string this[string columnName]

{

get {

if (columnName.Equals("Nom") && String.IsNullOrEmpty(this.nom))

return "Nom vide";

return null;

}

}

#endregion

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string name)

{

if(this.PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs(name));

}

#endregion

}

Déclaration de la ressource et Binding :

<UserControl.Resources>

<assembly:Client x:Key="client" Nom="Name"/>

</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">

<TextBox Text="{Binding Source={StaticResource client},Path=Nom, Mode=TwoWay, ValidatesOnDataErrors=True}" Margin="270,190,191,253" />

</Grid>

Résultat :

image11

2.8 Détection du clavier

L’accès au clavier couplé aux contrôles permettant de faire du texte riche peut être très intéressant. Nous pouvons, par exemple, détecter des tableaux venant d’Excel ou d’un document Word qui seraient stockés dans le presse-papier.

L’utilisation se fait de manière très simple avec les méthodes statiques de la classe Clipboard :

image12

2.9 Compatibilité avec les assemblies .NET

La création d’applications Silverlight nécessite souvent un développement parallèle à celui du développement du backoffice en .NET puisque l’environnement d’exécution n’est pas le même dans les deux technologies.

On peut maintenant rendre compatible des librairies Silverlight avec du code .NET et ainsi réaliser un gain de temps lors du développement/Maintenance des applications.

Cette portabilité est réalisée en compilant l’assembly grâce aux Silverlight Tools et en vérifiant que le projet compilé utilise bien des APIs portables en .NET et Silverlight (System, Mscorlib, System.Core…).

Dans l’exemple qui suit, je vais créer une librairie Silverlight que je vais référencer dans un projet .NET. A noter que le client .NET ne nécessitera pas l’installation du plug in Silverlight sur le poste.

1. Création du client WPF

image13

2. Création de  la librairie Silverlight

image14

3.  Ajout de la référence (en utilisant Browse plutôt que Projects qui provoque une erreur)

image15

 image16

2.10 Amélioration du support des services

Depuis l’arrivée de Silverlight 4, beaucoup se pose la question du choix de la technologie à utiliser pour leurs développements RDA. L’une des nombreuses différences entre WPF est Silverlight est que la CLR Silverlight s’apparente à un « framework.NET allégé » qui a de nombreuses limites.

L’une de ces limites est le support des services. Qui n’a jamais eu de problème avec les FaultExceptions (corrigé avec Silverlight 3) ou l’authentification des ClientsCredentials ? Beaucoup de choses manquent à l’appel pour nos applications Silverlight.

La version 4 corrige certains manques tels que le support d’UDP multicast ou de l’authentification avec la classe ClientHttpWebRequest.

L’utilisation de ce type d’authentification rend compatible Silverlight avec les services sécurisés de type WCF/WCF Data Services voir même des services Live ou Twitter sans passer par un service proxy « maison ».

Voici le code côté client Silverlight pour interroger un service WCF de type webhttpbinding :

public MainPage()

{

InitializeComponent();

WebClient client = new WebClient();

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);

client.UseDefaultCredentials = false;

client.Credentials = new NetworkCredential("julien", "dollon");

client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

client.DownloadStringAsync(new Uri("http://localhost:15980/Service1.svc/DoWork"));

}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

MessageBox.Show(e.Result);

}

Si vous souhaitez vous renseigner sur comment réaliser un service WCF sécurisé avec des clients credentials rendez-vous sur mon blog.

Une astuce à noter également dans les améliorations de communication avec les services : Les ObservableCollection peuvent s’initialiser avec un type IList ou IEnumerable en paramètre.

Ce qui nous évite de réaliser à la main la boucle foreach quand un service nous renvoie un tableau de données.

List<Client> maliste = new List<Client>();

maliste.Add(new Client());

ObservableCollection<Client> collection = new

ObservableCollection<Client>(maliste);

2.11 Les commandes pour le pattern MVVM

Model-View-ViewModel est un pattern qui a pour but d'améliorer la maintenabilité de vos logiciels Silverlight. Le principe est de séparer en 3 parties :

La partie Model contient nos données métiers, proxy WCF ou DomainContext. La partie View contient votre interface graphique XAML avec le moins de code C# possible puisque la logique de votre application est déportée dans la partie ViewModel grâce au Binding, aux Commands et aux notifications.

Voici un exemple de code MVVM réalisé en Silverlight 3 (code).

La nouveauté dans Silverlight 4 réside dans le fait que l’utilisation de l’attribut Command dans un bouton est gérée nativement.

<Button Command="{Binding MyCmd}" CommandParameter="{Binding Path=Value, ElementName=slider}"/>

2.12 Amélioration de la navigation de page

Dans mon white paper sur la version 3 de Silverlight, je vous exposais l’une des nouveautés qui était : la navigation entre les pages.

Cette fonctionnalité permettant une meilleure construction de l’IHM ainsi que la possibilité pour le client d’avoir un historique de navigation et une URL de type « permalink ».

Je faisais déjà allusion d’un futur proche ou j’imaginais toutes les possibilités que cela ouvre pour Silverlight (pattern MVC, application Restfull…).

La version 4 propose une nouvelle propriété appelée ContentLoader de l’objet Frame qui a pour rôle d’afficher les pages xaml.

Cette propriété va nous permettre de créer notre propre classe héritant de l’interface INavigationContentLoader afin de pouvoir gérer le chargement des pages nous-même.

public class MyContentLoader : INavigationContentLoader

{

#region INavigationContentLoader Members

public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri, 

AsyncCallback userCallback, object asyncState)

{

throw new NotImplementedException();

}

public bool CanLoad(Uri targetUri, Uri currentUri)

{

throw new NotImplementedException();

}

public void CancelLoad(IAsyncResult asyncResult)

{

throw new NotImplementedException();

}

public LoadResult EndLoad(IAsyncResult asyncResult)

{

throw new NotImplementedException();

}

#endregion

}

Schéma du parcours d’une requête de navigation :

image17

Pour une démonstration d’implémentation je vous recommande le blog de David Poll.

3 Amélioration de l’OOB

3.1 Les applications « Sandboxed »

3.1.1 Introduction

Les applications dîtes Sandboxed sont des applications téléchargées sur le poste client.

On appelle ces applications des applications OOB qui peuvent être exécutées avec ou sans connexion internet à travers un launcher (sllaunch.exe).

Pour plus d’informations, il suffit de lire le White Paper sur Silverlight 3 chapitre « Application Offline » et se documenter sur mon blog à cette adresse. Il est important pour la suite de ce chapitre de connaître comment déployer une application en mode offline.

Les nouveautés de ces applications avec des droits très limités (autant que si l’application était hébergée dans un navigateur) sont les suivantes :

· Contrôle de la position/taille/style (chrome) de la fenêtre qui affiche le site Silverlight en offline

· Hébergement de contenu HTML

· Notifications « outlook like »

· Offline DRM

· Une augmentation de la taille maximum de l’isolated storage (25Mo)

3.1.2 Gérer la taille, position et aspect de vos fenêtre Silverlight 4

La taille et la position de la fenêtre hébergeant l’application Silverlight est modifiable dès la configuration du fichier manifest :

image18

La modification d e l’apparence de la fenêtre également appelée « Window Chrome » n’est pas encore disponible dans la béta 1 de cette nouvelle version.

A noter qu’il est aussi possible de gérer la position en Z de la fenêtre par rapport aux autres fenêtres du bureau ainsi que l’état de celle-ci (minimisée ou maximisée).

3.1.3 Les notifications

Les applications OOB Sandboxed ou trusted permettent l’utilisation de notification (toast) un peu comme Outlook le fait lors de la réception de mail.

NotificationWindow notify = new NotificationWindow()

{

Width = 300,

Height = 50,

Content = new TextBlock() { Text = "Hello Word" }

};

notify.Closed += delegate { MessageBox.Show("Closed"); };

notify.Show(3000);

On peut customiser l’apparence 

très facilement en proposant au content un UserControl personnalisé.

image19

3.1.4 Héberger du contenu HTML

Vos applications Silverlight, en mode OOB seulement, peuvent embarquer un nouveau contrôle appelé WebBrowser.

L’utilisation de ce contrôle ne fonctionne pas lorsque l’application s’exécute dans un navigateur :

image20

Si votre application est de type « sandboxed » alors vous ne pouvez pas utiliser la méthode Navigate du contrôle pour visiter un site. Certainement par sécurité.

string html = "<h1>test</h1>";

Browser.NavigateToString(html);

Browser étant le contrôle WebBrowser. Si vous souhaitez malgré tout afficher un site web dans une application Sandboxed, vous pouvez utiliser une IFRAME HTML :

string html = "<IFRAME width='100%' style='overflow: hidden;' height='100%' src='http://www.bing.com' />";

Browser.NavigateToString(html);

Si votre application est de type « de confiance » (voir chapitre suivant), vous pouvez afficher une page web.

Exemple :

<StackPanel x:Name="LayoutRoot" Background="White">

<TextBox x:Name="URL"/>

<Button Content="GO" Click="Button_Click"/>

<WebBrowser Width="500" Height="500" x:Name="Browser"/>

</StackPanel>

private void Button_Click(object sender, RoutedEventArgs e)

{

Browser.Navigate(new Uri(URL.Text, UriKind.Absolute));

}

A noter que le flash s’exécute :).

image21

Si vous souhaitez utiliser un brush HTML en fond d’un contrôle (sur la propriété Fill d’un rectangle par exemple), vous avez à votre disposition la classe HtmlBrush.

Le contrôle WebBrowser n’est pas encore capable d’être utilisé avec des transformations type rotation/effets/opacité.

3.2 Les applications de confiances

3.2.1 Introduction

Il faut faire une distinction entre une application installée sur le poste client de façon « Sandboxed » c’est-à-dire avec des droits très restreints et les applications dites « de confiance » qui sont une des nouveautés de la version 4 de Silverlight.

Une application de confiance affiche un message « warning » dès l’installation pour prévenir l’utilisateur :

image22

On passe d’une application « Sandboxée » à une application de confiance en modifiant le fichier manifest avec l’assistant de Visual Studio :

image23

Ces applications de confiance sont aussi exécutées par SLLaunch.exe mais ont la possibilité de :

· Lire/Ecrire sur le système de fichier

· Ouvrir un autre programme (par exemple Office©)

· Utiliser l’interopérabilité COM

· Intégration totale du clavier en mode plein écran

· Détection du matériel

· Plus besoin de clientaccesspolicy.xml côté serveur lors de communication avec WCF

· Intégration des applications installées dans le panneau de configuration (Add/Remove Programs) :

image24

3.2.2 Accès au système de fichiers

Lors de l’utilisation d’une application de confiance, nous pouvons lire et écrire dans des dossiers prédéfinis tels que le bureau ou le dossier MyDocuments.

Une liste des dossiers accessibles est disponible ici.

Pour illustrer ceci, voici un petit exemple qui énumère, crée et lit des fichiers.

<StackPanel x:Name="LayoutRoot" Background="White">

<Button Content="Enumérer le bureau" x:Name="BtnEnumerate" Click="BtnEnumerate_Click"/>

<Button Content="Ecrire un fichier" x:Name="BtnWrite" Click="BtnWrite_Click"/>

<Button Content="Lire un fichier" x:Name="BtnRead" Click="BtnRead_Click"/>

</StackPanel>

 

image25

private void BtnEnumerate_Click(object sender, RoutedEventArgs e)

{

foreach (var item in Directory.EnumerateFiles(

Environment.GetFolderPath(

Environment.SpecialFolder.MyDocuments)))

MessageBox.Show(item);

}

private void BtnWrite_Click(object sender, RoutedEventArgs e)

{

File.Create(

System.IO.Path.Combine(

Environment.GetFolderPath(

Environment.SpecialFolder.MyDocuments), "Hello.txt"));

}

private void BtnRead_Click(object sender, RoutedEventArgs e)

{

string path = System.IO.Path.Combine(

Environment.GetFolderPath(

Environment.SpecialFolder.MyDocuments), "Hello.txt");

StreamReader reader = File.OpenText(path);

MessageBox.Show(reader.ReadToEnd());

reader.Close();

}

3.2.3 Interopérabilité COM

L’interopérabilité COM permet à nos applications de confiance d’accéder à la suite Office ou encore l’API Windows.

Si on reprend le même exemple que Scott G. lors de la PDC, une application est capable :

· De créer un élément dans Outlook Calendar

· De créer un fichier Excel

· D’utiliser l’API Windows

· …

Pour utiliser la démonstration suivante, pensez à ajouter la référence à Microsoft.CSharp.

image26

Pour l’utilisation de composant COM, nous allons nous appuyer sur une nouveauté du C #4 : La DLR et le type dynamic.

La création d’un document Excel :

private void btnExcel_Click(object sender, RoutedEventArgs e)

{

dynamic excelFile = 

ComAutomationFactory.CreateObject("Excel.Application");

//On cache Excel le temps de la création

excelFile.Visible = false;

//Création d'un workbook

excelFile.workbooks.Add();

//Récupération de l'élement actif

dynamic active = excelFile.ActiveSheet;

//Modification de la première cellule

active.Cells[1, 1].Value = "plop";

//On affiche le document excel

excelFile.Visible = true;

}

4 Le multimédia

4.1 Support de la webcam et du micro

Nous l’attendions et il est dommage de ne l’avoir qu’à partir de la version 4 : le support de la webcam et du micro.

Son utilisation est très simple, nous déclarons un type CaptureSource que nous initialisons avec les périphériques de capture audio/vidéo :

CaptureSource capture = new CaptureSource();

capture.VideoCaptureDevice = (VideoCaptureDevice) CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices()[0];

capture.AudioCaptureDevice = (AudioCaptureDevice) CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices()[0];

Une fois l’instance capture initialisée, nous pouvons convertir le flux vidéo en brush que nous appliquons en fond d’un border par exemple :

VideoBrush brush = new VideoBrush();

brush.SetSource(capture);

webcamBorder.Background = brush;

Le démarrage de la webcam se déclenche grâce à l’appel Start de l’instance capture. Une invite de commande proposera à l’utilisateur d’accepter, ou non, que l’application Silverlight utilise ses périphériques.

if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())

capture.Start();

image27

Invite de commande

Pour prendre une photo «instantanée » nous utilisons la méthode AsyncCaptureImage. Cette méthode est couplée dans mon exemple avec une ChildWindow pour montrer le résultat :

capture.AsyncCaptureImage((image) => {

AffichageImage win = new AffichageImage();

win.ImgSource = image;

win.Show();

});

Pour l’application de test que j’ai réalisé pour ce livre blanc (disponible ici), j’ai combiné les pixels shaders (généré avec l’outil Shazzam) avec l’utilisation de la webcam. Voici le résultat :

image28

Application de test (Avec ou Sans Pixel Shader le résultat est pas terribleJ)

4.2 Mise en place du SmoothStreaming

Le smoothstreaming est la capacité d’afficher un flux vidéo (HD ou non) en streaming à travers le protocole HTTP par rapport au taux d’occupation du processeur et de la bande passante.

C’est-à-dire que le client recevra une vidéo de moins bonne qualité pour éviter qu’elle ne s’arrête.

Cette technologie est apparue avec Silverlight 3 mais comme je n’en avais pas encore parlé je me rattrape ici.

Exemple de Microsoft© :

image29

La première étape de mise en place du smoothstreaming est l’encodage de la vidéo. Il faudra encoder la vidéo en la compressant de plusieurs manières pour avoir tous types de qualités.

Deux manières de l’encoder : l’utilisation d’Expression Encoder 3 ou de son SDK pour le faire en code.

Pour le déploiement, il vous faut installez IIS Media Services 3.0 (en plus de IIS7) téléchargeable ici.

Après l’installation d’IIS Media Services, rendez-vous dans la console d’administration d’IIS pour voir apparaître de nouveaux icones :

image30

De retour dans Expression Encoder, il faut configurer le format de sortie à IIS Smooth Streaming :

image31

Puis dans Output, choisir le déploiement WebDav sur le serveur IIS :

image32

Puis finir par encoder :

image33

Si vous souhaitez réaliser cette manipulation, direction le blog de Pierrick Martos qui a créé un post sur le sujet en référençant les DLL du SDK Encoder.

image34

4.3 Silverlight Media Framework

SMF (Silverlight Media Framework) est un projet opensource (codeplex) qui fait son apparition avec la version 3 de Silverlight.

Le but de SMF est d’aider à la création d’un player Silverlight de haut niveau en fournissant plusieurs helpers.

Plus d’informations en vidéo sur le site Silverlight.net.

4.4 WMS Multicast

Jusqu’à présent, seul l’unicast fonctionnait en termes de streaming (c’est d’ailleurs toujours la seule solution si votre réseau n’est pas compatible multicast).

Silverlight 4 fonctionne avec le multicast, c’est-à-dire qu’on passe à du Single-to-many.

Plus d’information sur ce PowerPoint© de 110 slides créé par Microsoft©.

5 MEF (Managed Extensibility Framework)

Le but de MEF est de créer une application dite “composite” (un peu comme Prism v2). On va pouvoir ajouter des fonctionnalités à notre logiciel avec le simple ajout de dll dans un dossier spécifique.

Chaque module est indépendant et peux être architecturé de la façon que vous souhaitez (n-tiers, MVVM, MVC…).

MEF est supporté dans le framework 4.0 et désormais avec Silverlight 3 et 4.

Pour illustrer ce chapitre, j’utiliserai un cas concret pour lequel j’ai été confronté. Je développe actuellement un viewer offline en Silverlight 4 pour Dotnet-France dont l’un des principes est de proposer des widgets.

Ces widgets peuvent être téléchargés et installés dans l’application.

image35

Version non fonctionnel, d esign très moche

Pour cela il faut mettre en place une architecture permettant d’ajouter à la volé ces widgets (représentés par des .XAP), le choix se porte donc sur MEF.

Je vous passe pour le moment les détails sur le téléchargement des .XAP à partir d’un magasin de widgets, allons directement au vif du sujet en imaginant que le client référence la dll contenant le widget.

Nous créons quatre projets :

· Le site hôte

· L’application Shell qui héberge tous les widgets (PrincipalShell)

· L’application MyWidget représentant un widget

· La librairie MEFContract qui représente les entités échangées grâce à MEF

image36

Nous ajoutons trois références permettant d’utiliser MEF aux deux applications Silverlight:

C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ComponentModel.Composition.dll, System.ComponentModel.Composition.Initialization.dll et MEFContract.

L’application PrincipalShell dans ce cas de figure doit aussi referencer MyWidget.

Le code IContract :

public interface IContract

{

string Nom { get; set; }

}

Le code behind du widget :

[Export(typeof(IContract))]

public partial class MainPage : UserControl, IContract

{

public MainPage()

{

InitializeComponent();

}

#region IContract Members

public string Nom

{

get

{

return "Bing widget";

}

set

{

}

}

#endregion

}

Et le code du shell principal :

public partial class MainPage : UserControl

{

public MainPage()

{

InitializeComponent();

PartInitializer.SatisfyImports(this);

foreach (var widget in widgets)

LayoutRoot.Children.Add((UserControl)widget);

}

[ImportMany]

public IEnumerable<IContract> widgets { get; set; }

}

Résultat, le widget est bien chargé à l’exécution. Ceci sera le cas pour tous les widgets qui seront référencés par le shell principal.

image37

Cependant, si on reprend la problématique de début, les DLL ne doivent pas être référencées de base.

La solution est d’isoler chaque widget dans un fichier .xap séparés et de les charger à l’exécution.

Pour cela il nous faut utiliser une classe appelée PackageCatalog qui est disponible dans le Silverlight Toolkit.

Après l’avoir téléchargé il faut référencer cette DLL au projet PrincipalShell :

C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Nov09\Bin\System.ComponentModel.Composition.Packaging.Toolkit.dll

Et ne pas oublier de casser la référence à MyWidget.

Au niveau du widget, il faut juste modifier le paramètre de l’attribut Export :

[Export(typeof(UserControl))]

Puis au niveau du PrincipalShell, il faut utiliser la classe PackageCatalog et la fonction DownloadPackageAsync pour télécharger le .xap :

public partial class MainPage : UserControl

{

PackageCatalog catalog = new PackageCatalog();

public MainPage()

{

InitializeComponent();

catalog.AddPackage(Package.Current);

var container = new CompositionContainer(catalog);

container.ComposeParts(this);

Package.DownloadPackageAsync(new Uri("http://localhost:8094/ClientBin/MyWidget.xap", UriKind.Absolute), DownloadCompleted);

}

private void DownloadCompleted(AsyncCompletedEventArgs e, Package p)

{

Thread.Sleep(1000);

if (!e.Cancelled && e.Error == null)

catalog.AddPackage(p);

foreach (var widget in widgets)

LayoutRoot.Children.Add((UserControl)widget);

}

[ImportMany(AllowRecomposition = true)]

public IEnumerable<UserControl> widgets { get; set; }

}

Les sources sont téléchargeables ici.

A noter que cette solution fonctionne en mode « Out Of Browser ».

6 WCF RIA Services

Cours disponible dans la version 1.3 de ce document

7 Annexe

7.1 SDK Facebook

Cours disponible dans la version 1.3 de ce document

7.2 BigMap

Cours disponible dans la version 1.3 de ce document

7.3 Silverlight Toolkit

Cours disponible dans la version 1.3 de ce document

Posted: Dec 27 2009, 20:15 by juliend | Comments (18) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .NET | WPF/Silverlight | Général

Comments

Nk54 said:

Cool le rajout de mef. J'ai pas l'impression que cela change beaucoup de SL3.

Vivement le livre blanc version 1.3 ;)

# December 29 2009, 18:01

Nk54 said:

Autre chose :

Sais tu s'il sera toujours obligatoire de choisir entre library caching et OOB ? :/ pour moi, le OOB devrait télécharger les .zip et se débrouiller tout seul Smile.

Parce que choisir entre rapidité de chargement en ligne et OOB avec tout ce que cela apporte en plus avec sl4, le choix va vraiment être difficile Frown

# December 29 2009, 18:11

julien said:

Sans aucun doute.
Le OOB au moins en mode confiance devrait pouvoir télécharger les DLL manquantes.
Pourquoi pas dans la beta 2 ?

# December 29 2009, 18:50

Nk54 said:

Oui au moins en mode confiance confiance. Ce serait super.

Nous verrons bien ! Au pire, cela peut être une suggestion à soumettre à microsoft Smile

# December 30 2009, 17:25

Nk54 France said:

(au fait je ne reçois plus les notifications pour les nouveaux commentaires. Est-ce parce que j'ai changé l'adresse email dans le champ E-mail "ctl00$cphBody$CommentView1$txtEmail" ou parce que cette fonctionnalité est en pause ? merci)

# December 30 2009, 17:28

julien said:

Non bizarre.. !

# December 30 2009, 21:33

JulienG France said:

Je reviens sur la partie MEF, que j'avais jusqu'à présent ignoré, priorisant le MVVM dans ma formation.

Je dois dire que je suis bluffé, par la simplicité. C'était possible en 2.0 mais fallait jouer à fond avec les interfaces, la réflexion, bref assez complexe au final.

Là, il y a moyen de faire des choses vraiment sympa en associant MVVM et MEF, pour ajouter son "plugin" dans un onglet ...

Bref, à adopter au plus vite, je pense que c'est presque à utiliser dans n'importe quel projet.

# January 27 2010, 22:36

Nk54 France said:

Salut je voulais savoir si tu avais galéré à combiner MEF et MVVM ?

C'est pas trop long et ca ne devient pas trop complexe ? Parce que à trop rajouter de complexité, je me demande si on s'y perd.

Est-ce plus difficile de débuger, trouver où se situe un problème dans un prog avec cette architecture ?

Cela ne rend pas la maintenance élitiste ? En effet, admettons que mon équipe de dev augmente, ne sera t il pas trop long et difficile pour une personne sans connaissance particulière de MEF et MVVM de prendre en main le projet et travailler de concert avec l'équipe ?

Je n'ai pas trouvé de correspondance à MEF et MVVM chez les concurrents de silverlight. Vous en connaissez ?

Merci de m'éclaircir parce que dans ma tête, il y a beaucoup de cloud :p

# February 20 2010, 22:05

Julien Dollon France said:

Salut NK Smile
Ce n'est pas complèxe, au contraire.
Imagine tu proposes à ton client un shell principal et ensuite plein de petites applis composites possèdant leurs propres pattern MVVM.
Premièrement tu granularises ton projet (donc moins de bug, plus de clarté) mais surtout cela va te permettre au fur et à mesure de l'avancement de ne pas revenir toucher aux précédents livrables (car tout est indépendant).
Je ne me mouille pas en te disant de suivre cette best practice ;)

# February 26 2010, 10:17

Nk54 France said:

Ok ! Tu m'a convaincus ! Y a t il des framework pour MEF ? Pour MVVM, j'utilise (enfin j'essaye :p) GalaSoft - MVVM Light Toolkit.

Si tu as un lien, webcast (quoi j'ai dit fr ? Smile sur l'un de ces deux sujets je suis preneur ! Car le template du framework galasoft est super bien commenté, je galère un peu Smile

Et pas mal ton message posté le 26 février à 18h17 qu'il est 10h45 ;)

Et pour finir, tu avais annoncé la version 1.3 de ton livre blanc. Je suis toujours aux aguets Smile

Bon weekend JD ;)

# February 26 2010, 12:12

Nk54 France said:

C'est bon pour le framework MVVM. J'ai trouvé SIMPLE MVVM sur codeplex et plus simple et bien je vois pas comment on peut faire Laughing

Me reste MEF à bien implémenter et je pourrai migrer entièrement mon projet !

Et il y a des architectures spécial pour bien organiser son service WCF ? Est-ce possible par exemple de faire des classes partielles pour diviser le fichier svc.cs ? Parce que le mien fait plus de 700 lignes de codes (et je n'utilise que des return resultatDuneProcedureStockee.

Après ça je serai équipé pour faire vivre mon projet sur le long terme et à moi la maintenance facilité Smile

# February 26 2010, 18:22

julien said:

Pour le service WCF tu dois avoir 4 projets:
Interfaces
DataContracts
Implementation
Hosting

Voilà un exemple:
blogs.dotnet-france.com/.../...ype-de-clients.aspx

# February 27 2010, 11:59

Nk54 France said:

Ok merci. Pour l'instant mon service est un projet dans ma solution où je me contente juste du IService et Service. Est-ce que cela est-il utile et apporte un plus en dehors de l'organisation et de la "propreté" de faire comme tu dis ?

Par ailleurs, j'ai noté qu'on pouvait facilement débuguer un service s'il est intégré au projet web hébergeant l'appli (sans modification du code (enfin mettre une valeur à true et coché une case, je n'appel pas ça du code :p)

Merci pour toute tes réponses ! ;)

# March 11 2010, 12:04

julien said:

Si tu veux vraiment faire les choses bien, il faut granulariser tes services (un service pour l'authentification, un service pour l'envoi de "clients", etc...).
Segmenter est important pour:
1/ une meilleure maintenance
2/ imagine tu crées un soft demain qui a besoin juste de quelques fonctions du service, tu veux pas forcément qu'il ai accès à TOUT

# March 11 2010, 15:43

Coder212 Morocco said:

On attend toujours la version 1.3 Smile

# March 12 2010, 12:38

Nk54 France said:

lol +1 Coder212 ! ;)

j'ai finit de "granulariser" mes services. J'ai encore une question : y a t il un moyen de garder localhost en référence de service à la place du véritable domaine lors du déploiement si le service et l'appli son sur le même serveur, même port ?

En effet, mon application est déployé sur 3 port différents (pour attaquer 3 bases de données différentes) et c'est un peu long de reconfigurer le service à chaque fois :/

# March 16 2010, 10:12

Nk54 France said:

(pardon pour les fautes d'ortho ...)

Je tiens à préciser 2, 3 choses : actuellement je suis repassé à un service hébergeant l'intégralité des services. En effet, quand je déploie, il faut que je rechange l'adresse de référence pour chaque service. Puis je pointer l'adresse de référence des services vers une variables du fichier de config ?

Concernant ta solution mef :
Package.DownloadPackageAsync(new Uri("http://localhost:8094/ClientBin/MyWidget.xap", UriKind.Absolute), DownloadCompleted);

Cela implique que l'on doit connaître l'adresse où sont placé les xap. Il n'est pas possible de charger dynamiquement tout les xap présent dans un dossier ? Comme ça une fois que j'ai déployé le shell principal je n'ai qu'a uploader le xap dans le dossier contenant les xap à charger dynamiquement.

Et ma dernière question concerne la référence à MEFcontract :

Admettons que le projet MyWidget soit développé indépendament du shell principal. J'ajoute la référence à MEFcontract en faisant browse ... Puis je compile, je copie le xap que je place à l'emplacement indiqué dans le shell principal. Est-ce que MyWidget prendra MEFcontract du shell principal ?

Je me pose ces questions car par exemple : je développe un widget. Tu mets à disposition un accès FTP où l'on peut uploader nos xap. (c'est à titre d'exemple bien sur).
Ton shell principal charge automatiquement tout les xap du dossier en question. Tu vois le principe ? Pour des projet communautaire ca serait tip top.

Voilà ! Encore désolé de te couvrir de question Embarassed et merci de toujours répondre. C'est vraiment gentil de ta part (tu vas finir par verrouiller tes posts lol)

# March 16 2010, 10:55

dpa France said:

Bonjour,
J'essaye de faire du dragdrop dans une childwindow, cela ne semble pas fonctionner ?
Quand pensez vous ?
Cordialement.


Code joint

<controls:ChildWindow x:Class="xxxx.ctlDoc"
           xmlns="schemas.microsoft.com/.../presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
           Title="" HasCloseButton="False">

    <Grid x:Name="LayoutRoot" Width="580" Height="400">

        <dataLaughingataGrid AllowDrop="True">
            <dataLaughingataGrid.Columns>
                <dataLaughingataGridTextColumn Binding="{Binding FileName}" SortMemberPath="FileName" />
            </dataLaughingataGrid.Columns>
        </dataLaughingataGrid>

    </Grid>
</controls:ChildWindow>

# May 20 2010, 23:13

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading

captcha

*