Avec l’arrivée du Framework 4, une nouvelle brique fait son apparition : MEF (Managed Extensibility Framework).
Or par le passé il existait un framework fourni par Pattern & Practices, le composition UI application block (CAB).
Le CAB(Composite UI Application Block) est un block applicatif pour concevoir des applications modulaires. les liaisons entre modules applicatifs sont faite par injection de dépendances
MEF : Managed Extensibility Framework est un nouveau framework pour concevoir des applications modulaires, fourni avec le framework .Net 4.0. comme pour le CAB, la liaison entre module est aussi par injection de dépendances.
Ces deux frameworks ont la même finalité, mais l’un datant de 2005, et l’ autre 2010 (date de sortie du framework 4 dans sa version définitive)
le but du post est de montrer que l’on peut intégrer dans une application “CAB”, des modules utilisant MEF et le framework 4.0 sans recompiler votre application initiale.
Rappel : une application CAB de base est une “coquille vide”, appelé “shell”. C’est ce shell qui héberge les différents modules de l’application.
voici le shell sans module applicatif (une forme vide)
un fichier (profilecatalog.xml) contenant les différents modules à charger est associé à cette application
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile/2.0">
<Section Name="Services">
<Modules>
<ModuleInfo AssemblyFile="Infrastructure.Module.dll" />
</Modules>
</Section>
<Section Name="Layout">
<Dependencies>
<Dependency Name="Services" />
</Dependencies>
<Modules>
<ModuleInfo AssemblyFile="Infrastructure.Layout.dll" />
</Modules>
</Section>
<Section Name="Core">
<Dependencies>
<Dependency Name="Services" />
<Dependency Name="Layout" />
</Dependencies>
<Modules>
<ModuleInfo AssemblyFile="Core.dll" />
</Modules>
</Section>
<Section Name="Libraries">
<Dependencies>
<Dependency Name="Services" />
<Dependency Name="Layout" />
<Dependency Name="Core" />
</Dependencies>
<Modules>
</Modules>
</Section>
<Section Name="Editor">
<Dependencies>
<Dependency Name="Core" />
<Dependency Name="Libraries" />
</Dependencies>
<Modules>
<ModuleInfo AssemblyFile="Editor.dll" />
<ModuleInfo AssemblyFile="ErlangProject.dll" />
</Modules>
</Section>
</SolutionProfile>
Les différents modules sont maintenant disponible au sein de l’application.
en rouge le visuel des différents modules applicatifs
Nous allons maintenant intégrer MEF dans cette application. Il faut tout d’abord quelle s’execute avec le framework .Net 4.0, pour cela il suffit de modifier le fichier app.config comme suit :
<configuration>
...
<startup useLegacyV2RuntimeActivationPolicy="true">
<requiredRuntime version="4.0.21006"/>
</startup>
</configuration>
l’application maintenant s’execute avec le framework 4.0, et supporte le legacy… ;-), et donc de charger des assemblies .Net 2.0
pour que notre module MEF soit prise en compte par le shell, il faut completer le “profilecatalog.xml”, et y ajouter notre nouveau module “CAB” compilé en 4.0
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile/2.0">
<Modules>
<ModuleInfo AssemblyFile="Editor.dll" />
<ModuleInfo AssemblyFile="ErlangProject.dll" />
<ModuleInfo AssemblyFile="WorkflowIntegration.dll" />
</Modules>
</Section>
</SolutionProfile>
Cette assembly contient le code d’ initialisation du container MEF, mais aussi le code pour être reconnu comme en tant que module CAB.
Pour l’exemple j’ai intégré le nouveau designer de workflow du framework 4.0, il existe plusieurs tutoriel pour cela :
http://msdn.microsoft.com/en-us/library/dd489451(VS.100).aspx
http://msmvps.com/blogs/theproblemsolver/archive/2009/12/23/rehosting-the-workflow-designer-in-wf4.aspx
je me suis basé sur le deuxième exemple, en ajoutant un pincée de “MEF” ;-) cela donne :

regardons un peu sous capot, comment cela s’architecture.
l’intégration du conteneur MEF dans un module CAB est très simple :
class WorkflowIntegrationModuleController : WorkItemController
{
public override void Run()
{
base.Run();
AddServices();
}
private void AddServices()
{
//initialisation du container MEF
var catalog = new AggregateCatalog();
var thisAssembly =
new AssemblyCatalog(
System.Reflection.Assembly.GetExecutingAssembly());
catalog.Catalogs.Add(thisAssembly);
catalog.Catalogs.Add(new AssemblyCatalog(typeof(IDesignerController).Assembly));
//le sous répertoire nommé MefAddin, est utilisé pour les modules MEF
var extensionDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
extensionDir = System.IO.Path.Combine(extensionDir, "MefAddin");
if (System.IO.Directory.Exists(extensionDir))
catalog.Catalogs.Add(new DirectoryCatalog(extensionDir));
var container = new CompositionContainer(catalog);
//ajout du container en tant que service CAB, le usercontrol hostant le designer WF est une [SmartPart] (CAB)
this.WorkItem.RootWorkItem.Services.Add<CompositionContainer>(container);
}
}
Ce modulecontroller est instancié au chargement de l’assembly, lors de la phase d’initialisation du module.
Coté visuel, l’hébergement du Designer de wortkflow est faite dans un usercontrol windows forms, qui lui même sera hébergé dans le shell en tant que “smartpart” (terme CAB designant une zone visuel dans le shell)
vous noterez au passage que l’intégration de WPF dans du windows forms fonctionne très bien dans l’ide, et cela via la classe “ElementHost”.
Ce usercontrol réalise la liaison WindowsForms<->WPF, mais aussi la liaison entre CAB et MEF.
public partial class WfDocumentDesigner : WfDocumentGenericDesigner
{
public WfDocumentDesigner()
{
InitializeComponent();
}
public WfDocumentDesigner(WfDocument doc)
: base(doc)
{
InitializeComponent();
this.elementHost1.HostContainer.Loaded += new System.Windows.RoutedEventHandler(HostContainer_Loaded);
}
void HostContainer_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
if (DesignerController != null)
{
var documentContent = this.Document.Content;
if (string.IsNullOrEmpty(documentContent))
{
DesignerController.New(new FlowchartKind());
}
else
{
using (System.IO.StringReader sr = new System.IO.StringReader(documentContent))
{
DesignerController.Load(sr);
}
}
}
}
//injection via MEF
[Import(AllowDefault=true)]
public IDesignerController DesignerController { get; set; }
CompositionContainer _Container;
//injection via CAB
[ServiceDependency]
public CompositionContainer CompositionContainer
{
get
{
return _Container;
}
set
{
_Container = value;
if (value != null)
{
//injection du contenu WPF (designer WF)
value.ComposeParts(this.elementHost1.Child);
//injection de this
value.ComposeParts(this);
RegisterDesigners();
}
}
}
//injection via MEF
[ImportMany(typeof(IRegisterMetadata))]
public IEnumerable<IRegisterMetadata> RegisteredMetadata { get; set; }
/// <summary>
/// enregistrement des designers pour les activités du designer de workflow
/// </summary>
private void RegisterDesigners()
{
//designers fournis par le framework
new System.Activities.Core.Presentation.DesignerMetadata().Register();
//designers fournis par composition via MEF
foreach (var item in RegisteredMetadata)
{
item.Register();
}
}
}
on remarque bien ici que les injections CAB et MEF se font par des attributs.
- Import, ImportMany, Export,… pour MEF
- ServiceDepencency, SmartPart,… pour le CAB
En revanche si nous regardons l’implémentation du designer de workflow, il n’utilise que MEF et WPF
public partial class DesignerHost : UserControl, IDesignerController
{
private WorkflowDesigner _workflowDesigner;
private string _fileName;
public DesignerHost()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(DesignerHost_Loaded);
}
/// <summary>
/// interface de conrtôle du designer (chargement, enregistrement,...)
/// </summary>
[Export]
public IDesignerController Controller
{
get
{
return this;
}
}
/// <summary>
/// liste des activités qui seront affichées dans la toolbox
/// </summary>
[ImportMany("Toolbox.Activities", AllowRecomposition=true)]
public IEnumerable<Lazy<IActivityToolboxProvider, IWorkflowCategory>> ToolboxItems { get; set; }
private void LoadToolbox(string categoryName) ...
}
En conclusion, CAB et MEF cohabite très bien, ce qui peut permettre de faire des migrations/évolutions d’applications en douceur, tout en bénéficiant des dernières avancées technologiques.
Effectivement l’exercice ici est d’autant plus facile, que mon application est au départ modulaire.
nota : une fois que l’application utilise le framework 4.0, il n’est plus possible de la debogger avec VS 2008, il vous faut utiliser VS 2010.
Premières lignes et premières stupeurs…
en effet les types Action<T> et Func<T> ont pris du poids… puisque Action<T> passe de 4 paramètres à 16, idem pour Fun<>

Je pense que pour de la génération de code cela doit être utile, mais à écrire c’est un peu long ;-)
j’ai fait l’acquisition d’une machine en dual boot SnowLeopard/Windows 7 x64.
j’ai donc décidé d’installer Visual studio 2010 béta 2 sur la partition Windows 7, non sans mal….
c’est parti !


Le framework 4, ne s’ installe pas. voyons le log …
pas très parlant mise à part, qu’il y a un problème d’accès (à je ne sais pas quoi). Vérification faite, je suis bien Administrateur de la machine.
voyons le “log file” qui est plus détaillé :
c’est donc bien ça, l’installation n’arrive pas à acceder au fichier d’installation du framework
mais pourquoi ?
Antivirus ???…qu’a cela ne tienne, je desactive l’antivirus (ce serait un comble si c’était lui, puisque c’est celui de Microsoft)
nouvelle tentative,… même résultat…
l’iso télécharger depuis msdn, serait-il corrompu ?
j’ai donc télécharger le “web installer” du framework 4 uniquement, pour effectuer une nouvelle tentative

oui… encore moins parlant comme erreur.
à ce stade, l’absence d’idée total sur les causes eventuelles…il faut donc se résoudre à appeler mes amis Bing et Google :-)
ce que je craignais arriva, je n’ai rien trouvé sur la toile (peut-être que je n’ai pas chercher au bon endroit..)
LA solution
dans un éclair de génie, oui parfois ça arrive ;-)
le message ci-dessus m’indique que c’est clairement un problème au système de fichier. Voyons la liste des sytèmes de fichiers présent :
C : Windows
E: Snow Leopard
F: Visual studio 2010 béta 2
les seuls en lecture sont E: (système HFS) et F:
la solution à ce problème est bien de désactiver la lettre E
nouvelle tentative… cette fois ci c’est la bonne !
pour quelles raisons l’installation tente d’écrire sur un autre disque, de plus en lecture seul….mistère
en esperant que ce post pourra en aider d’autres !
L’ excellente série d’articles sur la programmation par messages en F#, de Luca Bolognese, s’est enrichie d’un article.
Pour ceux qui n’ont pas suivi, ça commence ici. Luca a commencé un framework, pour “faciliter” la programmation par messages avec F#. Celui-ci est basé sur les “MailboxProcessors”. Ce qui intéressant c’est son approche, qui est calquée sur le principe des processus Erlang.
En effet son framework est basé sur deux primitives : “spawnWorker” et “spawnParallelWorker”,…tiens tiens tiens, en Erlang c’est “spawn”. La notion de thread est encore un peu présente (voir dans le premier article, en Erlang cette notion n’existe pas), mais du point de vue du consommateur celle-ci peut être “oubliée”. Dans son dernier article il explique qu’il a “ré-architecturé” son framework, afin que les agents (i.e “récepteurs de messages”) ne traitent que des messages fortement typés (ce qui pour moi est une très bonne chose, il y a plus de vérifications lors de la compilation).
Bref une série d’article à lire…, et pour le tester c’est par là.
Il y a quelque temps (un peu plus de 2 ans 1/2), je testais WPF, WCF, WF et à cette occasion j’avais réalisé un jeu, une forme de “Tetris” mais multi-joueurs

Celui-ci était réalisé avec le framework 3.0.
Un framework et un servicepack plus tard j’ai donc décidé de le faire évoluer, et d’utiliser Windows Azure.
Architecture d’origine
Chaque joueur pouvant être “serveur”, toutes connexions entre les joueurs passe par le serveur.
Le serveur doit être connu de tout les participants. Le serveur est un service WCF basé sur le protocole “net.p2p”. J’ai pour cela dérivé la classe “System.ServiceModel.PeerResolver”.
Inconvénients
- Le joueur serveur reçoit toute les connexions, si il “tombe” le jeu est terminé pour l’ensemble des joueurs
- autre inconvénient majeur de cette solution est l’ouverture d’un port sur toute les machines.
- Le joueur serveur est aussi avantagé, sa connexion avec le “serveur” est locale.
- Cette architecture était plutôt orientée LAN
Le but au départ était de montrer un exemple utilisant les nouvelles briques du framework 3.0.
Ce qu’apporte Windows Azure et le ServiceBus
Pour ce jeu, j’ai tout simplement remplacer toute la partie qui gère le p2p entre les joueurs, c’est le rôle de la plateforme Azure. Si vous ne connaissez pas cette plateforme vous trouverez pas mal d’informations ici.
Le service utilisé dans ce jeu est le ServiceBus, et plus particulièrement la publication/souscription en multicast.
Tous les participants sont connectés sur un même point central (défini par une uri), et ainsi peuvent envoyer/recevoir sans avoir besoin de se connaitre mutuellement.
ainsi la nouvelle architecture est :
ceci est l’état du système lors d’une phase de jeu. Mais que ce passe-t-il avant….au commencement du jeu…
- Le joueur qui désire être serveur, envoi un message “SendRequest” avec l’uri pour répondre (ici : sb://…/Guid/Acceptor)
- les joueurs souhaitant participer se connectent au service d’acceptation pour obtenir une autre Uri, cette fois celle du service multicast pour la nouvelle partie. celle-ci est générée dynamiquement à chaque nouvelle partie.
- les joueurs ayant accepter l’invitation du serveur se retrouvent connectés ensemble sur un point qu’il sont seuls à connaitre.
ainsi plusieurs parties peuvent avoir lieu au sein de la même “solution“ Windows Azure
Les différentes interfaces des différents services
La gestion de la connexion (service représenté en orange ci-dessus), ce service permet au joueurs de se voir mutuellement
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface IPeerConnexionService
{
#region connection managment
/// <summary>
/// used to join, others player should respond with hello
/// </summary>
[OperationContract(IsOneWay = true)]
void Join(PeerPlayer player);
/// <summary>
/// used to leave the room
/// </summary>
[OperationContract(IsOneWay = true)]
void Leave(PeerPlayer player);
/// <summary>
/// the new player receive one "Hello" from all other players
/// </summary>
[OperationContract(IsOneWay = true)]
void Hello(PeerPlayer player);
/// <summary>
/// used to send a ping to a specific player
/// </summary>
[OperationContract(IsOneWay = true)]
void Ping(PeerPlayer from, PeerPlayer to);
/// <summary>
/// used to respond from ping
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
[OperationContract(IsOneWay = true)]
void Pong(PeerPlayer from, PeerPlayer to);
/// <summary>
///
/// </summary>
/// <param name="player"></param>
/// <param name="acceptor">uri of the acceptor service</param>
[OperationContract(IsOneWay = true)]
void SendGameRequest(PeerPlayer player, Uri acceptor);
#endregion
}
Le service que chaque joueur publie pour accepter les autres joueur dans son espace de jeu. ce service à la particularité d’être un service “wcf” standard, contrairement aux autres qui sont “multicast”
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface IAcceptorService
{
[OperationContract]
Uri IWouldLikeToplay(PeerPlayer player);
}
service utiliser pendant la phase de jeu (en vert sur le schéma ci-dessus)
[ServiceContract(Namespace = Constants.ContractNamespace)]
public interface ITetrisGameService
{
[OperationContract(IsOneWay = true)]
void SendBoard(Guid idplayer, byte[] board, int lengthDimension0, int lengthDimension1);
[OperationContract(IsOneWay = true)]
void SetTimerInterval(Guid idplayer, double newValue);
[OperationContract(IsOneWay = true)]
void GameOver(Guid idplayer);
[OperationContract(IsOneWay = true)]
void SendOption(Guid from, Guid to, byte option);
[OperationContract(IsOneWay = true)]
void SendScore(Guid idplayer, int score);
[OperationContract(IsOneWay = true)]
void HideBoard(Guid idplayer, bool value);
[OperationContract(IsOneWay = true)]
void GameStarting(Guid idCoordinator, int nbPlayer);
[OperationContract(IsOneWay = true)]
void PlayerReady(Guid idplayer);
[OperationContract(IsOneWay = true)]
void ImIn(Guid idplayer);
}
Premières impressions
- extrêmement simple de publier un service mondialement ! ;-)
- c’est du WCF, donc la configuration est identique à ce que l’on connais déjà
- la publication des services sur le cloud reste assez lente (plusieurs secondes par service)
- il ne faut pas oublier que le framework Windows Azure est en CTP
- par contre ensuite (dans le cadre du tetris) une fois la connexion établie, les échanges sont fluides.
- vous le remarquerez en cliquant sur “connect to mesh” dans le menu “game”
Utiliser ce jeu
Téléchargez l’installation depuis codeplex : http://geniustetris.codeplex.com/
une fois installer il faut modifier le fichier de configuration de l’application “geniustetris.exe.config”, plus précisément les “credentials” pour se connecter à windows azure
<behaviors>
<endpointBehaviors>
<behavior name="password">
<transportClientEndpointBehavior credentialType="UserNamePassword">
<clientCredentials>
<userNamePassword userName="GeniusTetris" password="****" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
Remplacer “GeniusTetris” par le nom votre solution Windows Azure, et le mot de passe par le votre. n’oubliez pas de modifier dans le jeu les options “réseaux” et de fournir le nom de la solution à utiliser.
il est possible d’utiliser d’autres moyens d’authentification comme “CardSpace”, cela fonctionne aussi.
vous voulez jouer ? alors rendez vous sur http://geniustetris.codeplex.com/
bon amusement !
un nouveau projet à vu le jour sur dev labs, il s’agit d’un langage Axum
Curieux.., j’ai installer le msi, qui me donne dans visual studio 2008, un type de projet supplémentaire :
curieux de connaitre ce qui avait derrière… j’ai suivi le webcast présent sur devlabs, et réalisé ma librairie mathématiques….
using System;
using System.Collections.Generic;
using System.Text;
namespace AxumMath
{
public channel IntOperator
{
input int X;
input int Y;
output int Z;
}
public agent AdderAgent : channel IntOperator
{
public AdderAgent()
{
while(true)
{
Z <-- (receive(X) + receive(Y));
}
}
}
}
qui fait une addition….
mes premiers sentiments au sujet de ce langage sont :
- effectivement on commence par décrire le message que l’on souhaite traiter, ensuite l’agent qui traite le message. mais je trouve cette description encore un peu trop verbeuse...
je pense qu’il est possible d’être un peu plus succinct.
public message IntOperator
{
input int X;
input int Y;
output int Z;
}
public agent AdderAgent
{
receive<IntOperator>
{
Z <-- X + Y;
}
}
évidemment on peut imaginer une multitude d’écriture…
- ce sucre syntaxique génère beaucoup de code(voir plus bas), mais en revanche cela simplifie l’écriture des applications
- ce langage s’approche du domaine fonctionnel mais sans l’être.
- le type du message est très “parlant”, on sait immédiatement ce qui est en entrée(input) et en sortie(ouput).
Revenons à notre agent et channel d’origine, et voyons ce que devient le code une fois compilé :
en réalité le mot clé channel, génère une classe avec les données qui dérive d’un classe “Channel”, mais pas seulement...
les données X,Y, Z, ne sont pas membres de la classe sous forme d’entier, mais sous forme d’objet complexe. Et oui fournir un langage pour concevoir des applications parallèles n’est pas simple…, surtout si le langage doit être accessible aux plus grands nombre,tout en rendant abstrait la distribution/parallélisme de “calculs utilisateur”.
en creusant un peu plus, cette implémentation de Axum utilise WCF pour faire transiter les données “input” :
il est clair que pour faire une addition, c’est peu être un peu trop…
La programmation parallèle est de plus en plus présente, tout les acteurs proposent des frameworks, langages, outils pour développer plus facilement des applications parallèles.
- Outils
- intel parallel studio
- visual sutdio 2010
- Framework
- Parallel Fx (.Net)
- PLINQ (.Net)
- JPPF (java)
- Langages
- Arche (successeur de Polygoth)
- Erlang
- Axum
cette liste n’est pas exhaustive, mais la tendance est là !
Microsoft Research nous présente leur travaux sur l’interface homme machine dans le domaine de la programmation. Ce projet à pour but de visualiser votre code sous un autre angle...
Aujourd’hui dans Visual studio nous avons plusieurs manière de “voir” notre code:
- l’éditeur de code (et oui parfois c’est pratique pour tapez du code…)
- l’explorateur de classes
- l’explorateur de solution
- l’explorateur d’objet
- les differents designers (windows forms, WPF, WF,…)
- ...
et bien il y a un petit nouveau qui pointe son nez !
en fonction du zoom on voit les dépendances
- entre les assemblies
- entre les fichiers sources
- entre les classes
- entre les propriétés des classes
une superbe application du “deep zoom”, à voir absolument !
un autre exemple issue du webcast sur le CCI (Common Compiler Infrastructure)
un conseil : regarder ce webcast !
les liens :
un projet à suivre asbolument !
ccimetadata est un projet disponible sur codeplex qui permet d’écrire des lecteurs /ecrivains pour MSIL et les fichiers de symboles.
mais à quoi cela peut-il bien servir ?
FxCop, ILMerge sont des applications cible de ce framework. Mais si je vous dit “programmation orienté aspect”… ça vous parle ?
Effectivement ce type de framewrk peut être utilisé pour faire du tissage d’aspect.
et devinez qui participe à ce projet ??
-> jonathan de halleux, acteur sur les projets Pex, QuickGraph, cci, codecontracts, Chess et le créateur de MBUnit
encore un projet MsResearch à suivre !
un petit nouveau est apparu sur DevLabs. il s'agit de CodeContracts, un framework de vérification. Il vous suffit de spécifier sur vos API, des pré-conditions, post-conditions, et invariants sous forme de contrats. Ces contrats peuvent ensuite utilisés pour une vérification statique (à la compilation), pour une vérification au runtime (à l'éxécution), mais ces contrats peuvent être utilisés aussi pour les tests, et bien sur pour la documentation. En effet je pense que ce dernier point permet de garder toujours une documentation en adéquation avec le code (puisqu'elle en est issue..).
un projet à suivre tout comme Pex....
il existe un bon tutoriel pour installer Windows 7 dans un fichier .vhd, c'est ici : http://blogs.msdn.com/editeurs_de_logiciels/pages/installer-windows-7-beta-sans-casser-votre-machine.aspx
cependant si comme pour moi cette procédure ne fonctionne pas correctement (i.e le chargement du driver disk.sys, provoque un reboot au démarrage du sytème, et donc la machine reboot indéfiniment).
voici une solution qui fonctionne dans mon cas.
Modifier l'étape 7 :
| 7. Nous allons ensuite créer un disque virtuel (*.vhd), pour ensuite installer Windows 7, en utilisant l’utilitaire diskpart.exe, suivi des commandes suivantes pour créer un disque virtuel. create vdisk file=c:\win7beta.vhd maximum=32000 select vdisk file=c:\win7beta.vhd attach vdisk exit La commande create vdisk file=”xxx” maximum=yyy permet de fixer la taille de votre disque virtuel. Prévoyez suffisamment d’espace pour vos applications. Dans l’exemple, j’ai choisi de créer un disque virtuel représenté par c:\win7beta.vhd de taille 32 Go. |
le but est de placer le fichier .vhd dans un sous répertoire et non à la racine (ne me demandez pas pourquoi...mystère).
donc avant d'executer dispkart, il faut d'abord créer un répertoire
md c:\vhd
ensuite le reste identique au répertoire près
7. Nous allons ensuite créer un disque virtuel (*.vhd), pour ensuite installer Windows 7, en utilisant l’utilitaire diskpart.exe, suivi des commandes suivantes pour créer un disque virtuel.
create vdisk file=c:\vhd\win7beta.vhd maximum=32000
select vdisk file=c:\vhd\win7beta.vhd
attach vdisk
exit
La commande create vdisk file=”xxx” maximum=yyy permet de fixer la taille de votre disque virtuel. Prévoyez suffisamment d’espace pour vos applications. Dans l’exemple, j’ai choisi de créer un disque virtuel représenté par c:\vhd\win7beta.vhd de taille 32 Go.
Cette méthode possède l' avantage de ne pas toucher au système hôte.
Les sociétés RunAtServer Consulting et Octo Technology organisent une halte à Paris du Silverlight Tour le 19, 20, 21 Janvier 2009.
c' est Laurent Duveau (MVP canadien) qui donne cette formation à Paris. Si vous êtes intéressé c' est ici.
Connaissez vous ce projet : small basic ?
c' est un projet hébergé sur msdn devLabs, dont le but est d' apprendre la programmation aux débutants (faq).
l' interface est bluffante (en WPF évidement), Mais le coté intéressant de ce projet est l' approche utilisateur :
- un langage avec 14 mots clés (donc simple)
- Approche très contextuel
- Une aide au fil de l' eau
- Le clic droit dans l' éditeur est absent, mais dans ce cadre inutile
- Intellisense limité à 7 élements visible, mais la liste est circulaire
- Ici l' utilisateur ne fait que consommer des objets, il n' a pas la possibilité d' en définir.
Conclusion :
il possible de faire un IDE avec une dizaine de "commandes".
Dans bien des cas on désire offrir à une catégorie de personnes, un éditeur de script orienté "métier". Je pense que ce projet est une bonne source d' inspiration.
Une autre question me chatouille quelques neurones...
Il existe un éditeur de code en WPF ?
- oui
Ce projet est basé sur une partie d' un framework qui à fait son apparition à la PDC "Olso SDK". Tiens, tiens... serait-ce un avant goût du prochain Intellipad ?
au hazard des mes lectures..., j'ai découvert via ce blog, et qu'il était possible de télécharger le training kit pour Visual Studio 2010.
et oui on en oublierai presque que le Framework 3.5 sp1 viens de sortir il y a 3 mois...
je n'avais pas encore eu le temps de migrer ce petit jeu pour la version RTW de Silverlight 2.0. C'est dorénavant chose faite :
Amusez vous bien !
pour ceux qui ont encore le client Silverlight Béta 2, l'ancien fonctionne toujours mais à cette adresse : ici
Un autre langage utilise lui aussi le pattern matching pour la reception des "messages" dans la communication inter-process, c'est Erlang. En effet en Erlang pour recevoir des messages on utilise ce type de syntaxe :
receive
Pattern1 ->
Expressions1;
Pattern2 ->
Expressions2;
end
un exemple :
receive
{rectangle, Width, Ht} ->
io:format("Aera of rectangle is ~p~n", [Width * Ht]);
{circle, R} ->
io:format("Aera of circle is ~p~n", [3.14159 * R * R]);
end
On remarque aisément que cela ressemble à un switch. tiens, tiens, ... ni aurait-il pas une ressemblance avec ce post(comment faire un pattern matching en C# comme celui de F#) ?
Mais comme on parle de messages, on peut imaginer un système de "publish-subscribe" basé sur le Type du message.
on pourrait ainsi écrire en C# :
class Program
{
class MyRectangle
{
public int Width { get; set; }
public int Ht { get; set; }
}
class MyCircle
{
public int R { get; set; }
}
static void Main(string[] args)
{
PubSub.Subscribe<MyRectangle>(r =>
{
Console.WriteLine("Area of Rectangle is {0}", r.Width * r.Ht);
});
PubSub.Subscribe<MyCircle>(c =>
{
Console.WriteLine("Area of Circle is {0}", c.R * c.R * 3.14159);
});
//publication
new MyRectangle() { Width = 6, Ht = 10 }.Publish();
new MyCircle() { R = 23 }.Publish();
Console.ReadLine();
return;
}
}
à l' exécution
Le principe ?
Associer un Type (i.e MyRectangle) avec une déléguée (i.e r => ...).
public static Guid Subscribe<T>(Action<T> caseAction)
{
return Subscribe(string.Empty, caseAction);
}
public static Guid Subscribe<T>(string topic, Action<T> onMessageReceived)
{
Guid result = Guid.NewGuid();
lock ((_subscriptions.Keys as ICollection).SyncRoot)
{
Action<object> current;
if (_subscriptions.TryGetValue(topic, out current))
{
//add the new delegate to current subscribers list
var currentCase = current.Target as CaseActionHolder<object>;
var newCase = current.Case(result, onMessageReceived);
currentCase.PreviousID = result;
((CaseActionHolder<object>)newCase.Target).NextAction = current;
_subscriptions[topic] = newCase;
}
else
{
//creates case
current = current.Case(result, onMessageReceived);
_subscriptions.Add(topic, current);
}
_subscriptionsById.Add(result, topic);
}
return result;
}
Dans mon implémentation, j'ai ajouté une notion (topic), le sujet qui permet d'avoir à l'utilisation un découpage logique des abonnements. De plus il est possible de se désabonner grâçe au guid renvoyé lors de l'abonnement.
Le "switch-case" pour dispatcher le message ressemble beaucoup à celui de mon post sur le pattern matching F#:
static Action<object> Case<TArg>(this Action<object> fn, Guid id, Action<TArg> caseAction)
{
var thisCase = new CaseActionHolder<object> { ID = id };
thisCase.Action = (arg) =>
{
if (typeof(TArg).IsAssignableFrom(arg.GetType()))
{
var convertedArg = (TArg)arg;
caseAction(convertedArg);
}
thisCase.NextAction(arg);
};
//no exception by default
thisCase.NextAction = (arg) => { };
return new Action<object>(thisCase.DoAction);
}
une souscription tel que "Subscribe<MyRectangle>(r => ...), reçoit les messages de Type MyRectangle, mais aussi pour tous les types qui dérivent de MyRectangle.
ainsi si on dérive de MySquare : MyRectangle
class MySquare : MyRectangle
{
}
...
new MySquare() { Width = 4, Ht = 4 }.Publish();
...
donne comme résultat :
avec cette technique il possible de faire des récepteur à messages fortement "typées", certainement moins puissante qu'avec Erlang, mais l'idée est là.
vous pouvez télécharger le code source ici :
Le ton est donné ! les prochaines années seront résolument "services" !
un mot à retenir "Azure", un mot oui, mais aussi une plateforme, et un système d'exploitation
à l'occasion du keynote, Microsoft à annoncé sa nouvelle plateforme "Windows Azure", cette plateforme est un système d'exploitation permettant de hoster des applications comme des services, mais en fournissant un abstraction complète vis à vis du système sous-jacent.
Cette plateforme simplifie le déploiement, l'administration et même le développement de vos applications (as services), en s' intégrant dans vos outils tel que Visual Studio.
Au niveau du développement, une nouvelle brique fait son apparition ".NET services". c'est le coeur du système qui permet de connecter les applications entre elles.

au passage on remarque, les nouveaux logos associés à cette plateforme
pour en savoir plus rendez vous sur http://www.microsoft.com/azure/whatisazure.mspx#Whatis
bon je vais suivre la suite sur : "Dublin" and .Net Services
PS : Ray Ozzie à annoncé qu' une première CTP du SDK devrait être bientôt disponible (quelques semaines)
c' est fait, je me suis inscrit, afin d' éviter la bousculade de demain :
et vu le temps, un petite balade s' imposait...

plage de santa monica, début de "Venice beach"

demain devrait-être un peu plus climatisé...
Mots clés Technorati :
PDC
Don Syme vient d'annoncer la sortie d' une nouvelle CTP de F#. C'est en réalité une mise à jour, corrections sur les unités de mesure. Cette version est téléchargeable ici.
Le détails des corrections sont décrites ici.
Les 10 derniers blogs postés
-
TechDays Paris 2010 : La BI dans SharePoint 2010 par
Blog Technique de Romelard Fabrice le il y a 1 heure et 20 minutes
-
TechDays Paris 2010 : Déploiement de nouvelles technologies – Retour d’expérience par l’informatique de Microsoft par
Blog Technique de Romelard Fabrice le il y a 2 heures et 47 minutes
-
TechDays Paris 2010 : Plan de migration vers SharePoint 2010 par
Blog Technique de Romelard Fabrice le il y a 6 heures et 29 minutes
-
TechDays Paris 2010 : La pleinière du second jour par
Blog Technique de Romelard Fabrice le il y a 7 heures et 34 minutes
-
Visual Studio 2010 and .NET Framework 4 Release Candidate now available par
Matthieu MEZIL le il y a 10 heures et 40 minutes
-
Création d’une base de donnée sous SQL Azure par
Le Blog (Vert) d'Arnaud JUND le il y a 11 heures et 37 minutes
-
TechDays Paris 2010 : Les Services d’applications dans SharePoint 2010 par
Blog Technique de Romelard Fabrice le il y a 21 heures et 36 minutes
-
TechDays Paris 2010 : La GED et SharePoint 2010 par
Blog Technique de Romelard Fabrice le 02-08-2010, 16:54
-
TechDays Paris 2010 : SharePoint 2010 et Les réseaux sociaux par
Blog Technique de Romelard Fabrice le 02-08-2010, 15:40
-
TechDays Paris 2010 : SharePoint 2010 – Description et nouveautés par
Blog Technique de Romelard Fabrice le 02-08-2010, 14:33