Entity framework V2, vite un successeur!!!#

A chaque fois que j’arrive sur un nouveau projet et que la question d’accès aux données se pose, les différents participants à ce projet pensent tout de suite à Entity Framework et quand on pose la question pourquoi la réponse est toujours la même : d’un côté il y a le designer et de l’autre côté ça génère les classes et hop!!! doucement doucement, on inspire, on expire, … il faut arrêter de regarder le bout de son nez, je vais vous démontrer qu’en regardant un peu plus loin le choix n’est plus aussi évident.

Tout d’abord ce qu’il faut savoir c’est que lorsqu’on fait appel à entity framework pour accéder aux données il nous renvoie des classes qui héritent de EntityObject appartenant à l'espace de nom "System.Data.Objects.DataClasses" communément appelés entités. Ces entités ont été générés par EF et sont la traduction objet du modèle de données, ici deux remarques s’imposent : La première c’est qu’ Entity Framework ne supporte pas les POCO. Et la deuxième c’est que si on prétend autant soit peu faire de la Programmation Orientée Objet, les classes générées par EF ne peuvent pas faire office de classes métiers, dans la POO on ne part pas du modèle de données pour en déduire le métier c’est plutôt le contraire.

Ensuite, si on travaille sur un vrai projet (architecture en couche …) on ne peut utiliser les classes générées par EF dans la couche métier puisque :

- On avait dit plus haut que ce n’est pas des classes métiers.

- Il ne faut pas oublier que les entités appartiennent à un contexte EF et par conséquent elles sont mappées directement sur des tables en base de données, un exemple : supposons qu’on veuille introduire du traitement métier on va commencer à manipuler nos entités EF or si on fait un new sur une entité ça crée une nouvelle ligne dans le contexte et dès qu’on va faire un AcceptAllChanges sur le contexte cette ligne vide va être créée en BDD alors qu’on voulait juste créer un objet temporaire!!! pareil pour les modifications sur des entités. Donc si on manipule les entités on manipule forcément les tables de la BDD.

- On crée une corrélation forte de toutes les couches avec l’ORM

- On crée une corrélation forte des couches entre elles, un changement au sein d’une couche signifie un changement dans toute l’application, …  bref ça remet en cause la fiabilité de l’application, sa maintenabilité, …

Ce qu’on va faire pour éviter tout ça, on va écrire les classes métiers et on va devoir transformer à l’aide de requêtes linq nos objets EF en objets métiers. Donc au final, on a fait le mapping entre les entités EF et nos classes métier.

Enfin, la généricité n’est pas le point fort d’EF. Je m’explique : en général on se lasse très vite d’écrire une classe par table surtout si c’est pour faire du CRUD (Create, Read, Update, Delete). Donc on essaye d’écrire une classe générique à la quelle on passe le type en paramètre. Malheureusement avec la version actuelle (V2) d’EF ce n’est pas possible, et là tout ceux qui l’ont déjà fait vont se lever et dire “mais si je l’ai fait”. Prenons un exemple, pour insérer dans une table Personne dans la base de données, il faut faire :

DataContext context = new DataContext();

Personne p = new Personne(“Dupond”, “Pierre”);

context.AddToPersonne(p);

context.AcceptAllChanges();

Vous l’avez bien compris le problème se pose au niveau de l’instruction context.AddToPersonne(p); elle n’est pas du tout générique. Les développeurs d’EF y ont pensé et nous mettent à disposition la méthode context.AddToObject(string entitySetName, object entity); Mais malheureusement je n’ai jamais jusqu’à présent trouvé un moyen de récupérer l’entitySetName parce que la subtilité est là!!! l’entitySetName n’est pas le nom du type de l’entité et peut être différent de ce dernier, vous trouverez la notion d’entitySet dans les fichiers SSDL, CSDL et C-S mapping. Donc écrire quelque chose comme context.AddToObject(typeof(T).Name, monObjetAInserer) n’est pas une solution. Donc au final, comme on ne peut pas écrire une classe générique permettant de faire les accès aux données CRUD pour toutes les tables, on va être obligé d’écrire une classe par table et le supposé temps qu’on a gagné en générant les classes avec EF on va le perdre dans cette phase.

Néanmoins, il existe plusieurs manières de contourner ce problème comme générer ces classes à l’aide du “Domain class Service” de .NET RIA Services ou bien utiliser tout simplement un générateur de code pour générer des classes qui font du CRUD sur toutes nos entités. Mais, à mon avis, en faisant ça on contourne le problème on ne le résout pas.

Conclusion :

Pour résumer, la génération de classes d’Entity Framework ne nous avance pas plus que ça puisque :

- Entity Framework ne supporte pas les POCO.

- On va écrire les classes métiers et on va devoir transformer à l’aide de requêtes linq nos objets EF en objets métiers

- Comme on ne peut pas écrire une classe générique permettant de faire les accès aux données CRUD pour toutes les tables, on va être obligé d’écrire une classe par table.

Pour toutes ces raisons j’ai abandonné les développements avec Entity Framework en attendant la prochaine version qui devrait répondre à toutes ces problématiques. En attendant je ne peux que vous recommander l’utilisation d’NHibernate qui est un ORM qui se base sur des fichiers XML pour décrire le mapping entre la base de données et les classes métiers, donc il y a un petit investissement en temps au début pour écrire les fichiers XML mais au final on a gain de productivité énorme puisqu’il résout toutes les problématiques énoncées ci-dessus. Pour ceux qui n’ont pas envie d’écrire les fichiers XML, vous pouvez utiliser fluent NHibernate qui vous permet de définir le mapping en code c#.

Thursday, September 17, 2009 9:24:03 AM (Romance Standard Time, UTC+01:00) #    Comments [1]  | 

 

Windows mobile 6.5#

ça y est, la date officielle de la sortie du tant attendu Windows mobile 6.5 est prévue pour le 06/10/2009.

Je vous rappelle que le DTK Windows Mobile 6.5 Developer Toolkit est disponible en téléchargement depuis début juin. Il contient les émulateurs, la gesture API et des samples assez utiles. Pour fonctionner, le DTK a besoin du Windows Mobile 6 Professional SDK or Windows Mobile 6 Standard SDK.

La documentation de la gesture API est disponible sur msdn depuis début juillet.

Il ne reste plus qu’un Windows phone et tout le monde est content :)

Tuesday, September 08, 2009 9:38:06 AM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Silverlight : introduction à l’Isolated Storage#

L’isolated storage est une fonctionnalité assez intéressante puisque c’est un espace disque isolé (comme son nom l’indique) côté client auquel on a accès à partir de notre application Silverlight, sa taille initiale est de 1Mo et peut augmenter avec son contenu. On peut alors librement créer des répertoire, des fichiers, les supprimer, …

A quoi ça peut servir?

On peut l’utiliser pour stocker des cookies, ou stocker des données que j’aurais stocké en session, ou encore stocker des fichiers propres à l’utilisateur (sa photo).

Pour utiliser l’Isolated storage, rien de plus simple :

using System.IO.IsolatedStorage;
Ensuite on a besoin d’un objet de type IsolatedStorageFile
IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();

Puis il ne rester plus qu’à appeler la bonne méthode pour ce que l’on veut faire.

isolatedStorage.CreateDirectory(path);

isolatedStorage.CreateFile(path);

isolatedStorage.DirectoryExists(path);

isolatedStorage.OpenFile(path, FileMode.Append, FileAccess.Write);

Voici un petit code qui permet de créer 2 répertoires et un fichier dans le premier répertoire :

isolatedStorage.CreateDirectory("rep1");
isolatedStorage.CreateDirectory("rep2");
isolatedStorage.CreateFile("rep1/fichier1");

Attention :

- vu qu’on utilise l’espace disque de la machine cliente il se peut qu’on en demande à un certain moment et qu’il n’en reste plus, ou encore que l’administrateur limite l’espace disque utilisateur.

- Il est possible moyennant quelques efforts de trouver les répertoires de l’isolated storage, donc la solution n’est pas complètement sûre, il ne faut donc pas y mettre de données sensibles.

On verra dans un prochain post comment utiliser l’Isolated Storage avec Silverlight 3 pour faire une application qui fonctionne en mode déconnecté.

a+ ;)

Monday, September 07, 2009 4:58:59 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Silverlight 3 (SLOOB) : Silverlight Out Of Browser#

Une des grandes nouveautés de Silverlight 3 c’est de pouvoir télécharger l’application sur son poste et pouvoir l’exécuter hors navigateur en mode déconnecté.

Si vous n’en avez jamais créé de projet Silverlight, rendez-vous à ce post qui vous propose de créer votre permier projet Silverlight.

Pour rendre votre application Silverlight OOB enabled, click droit sur votre projet Silverlight –> Propiétés. Séléctionner l’onglet “Silverlight” à gauche puis cocher la case à cocher “Enable running application out of browser”.

image

C’est tout ce que vous avez à faire!!! Lancez maintenant votre application et faites un click droit vous allez voir apparaître une ligne de plus dans votre menu contextuel une entrée “Install SilverlightApplication onto this computer”

image

cliquer sur cette entrée, vous allez voir la fenêtre qui va vous permettre d’installer votre application en local.

image

Cocher les cases à cocher pour avoir les raccourcis sur le bureau et dans le menu démarrer, puis cliquer sur OK. L’application sera installée en local, et lancée, vous devriez voir apparaître cette fenêtre hors du navigateur.

image

Si vous avez coché “Desktop”, vous trouverez sur le bureau un raccourci qui permettra de lancer votre application Silverlight en local et en mode déconnecté.

image

Si vous relancez votre application et vous faîtes un click-droit, vous allez voir une entrée dans le menu contextuel qui vous permet de désinstaller l’application.

image

Si vous voulez contrôler l’installation de l’application Silverlight par code vous pouvez le faire avec ces quelques lignes de code :

if (Application.Current.InstallState == InstallState.NotInstalled)
{     Application.Current.Install();
}

Cette fonctionnalité est très intéressante et surtout très facile à mettre en œuvre. Mais comme vous l’avez compris on ne télécharge en local avec cette fonctionnalité que l’application, donc il faut que cette application soit autonome et qu’elle n’ait pas besoin de données.  Ce qui serait aussi très intéressant c’est de pouvoir stocker des données en local et de pouvoir travailler avec ces données en mode déconnecté jusqu’à la prochaine reconnexion où on va procéder à une synchronisation de ces données avec la base de données consolidée. On verra dans un prochain post comment utiliser l’isolated staorage de Silverlight pour enregistrer des données en local et les utiliser en déconnecté.

Monday, September 07, 2009 10:37:51 AM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Silverlight 3, mon premier projet (Hello world)#

Ce post est destiné à ceux qui veulent se lancer dans des développements Silverlight et qui se posent plein de questions, voici un petit tuto du classique “Hello world” :)

 

Pour commencer il faut déjà installer les pré requis :

- Visual Studio 2008 Service Pack 1

- Silverlight™ 3 Tools for Visual Studio 2008 SP1 (Contient le runtime)

Après avoir installé tout ça, lancer Visual Studio –> Nouveau  –> projet. Choisir l’élément “Silverlight” dans l’arbre à gauche et choisi le type de projet “Silverlight Application”.

ProjectChoice

Si vous n’avez pas installé les .NET RIA Services (Ce qui n’est pas un pré requis pour ce post) vous ne devriez pas voir les 2 derniers types de projets à savoir “.NET RIA Services Class Library” et “Silverlight Business Application”

Cliquer sur OK, Le wizard vous donne alors le choix de créer en même temps que votre application Silverlight, le site web qui va héberger cette dernière. Vérifier que la case à cocher “Host the Silverlight application in a Web site” est bien active et cliquer sur OK.

AttachToWebSite 

et c’est finit, vous avez créé votre premier projet Silverlight!!! Regardons maintenant la solution Visual Studio.

Solution

Le Wizard nous a bien créé 2 projets :

- Notre application Silverlight

- L’application web qui héberge l’application Silverlight

L’application web contient 2 pages web de test qui permettent de tester notre application silverlight, le plus important à ce stade c’est de savoir que ces pages utilisent le plugin Silverlight installé sur le navigateur qui va exécuter le binaire résultant de la compilation de notre projet Silverlight qui est ClientBin/SilverlightApplication3.xap

Bien évidemment, si on lance l’application web à ce stade on tombe sur une page vide (Génial!!! :))

Si in regarde un peu plus en détail notre application Silverlight on trouve App.xaml et MainPage.xaml. Le xaml est du xml qui va nous permettre de définir notre interface utilisateur de manière déclarative au sein d’une application Silverlight ou WPF

- App.xaml permet de déclarer les ressources. Dans son code Behind, on peut réagir aux évènements au niveau de l’application, et c’est là aussi qu’on définit l’écran / User Control qu’on veut lancer au démarrage de l’application, par défaut c’est MainPage.xaml.

- MainPage.xaml : C’est le User control par défaut, on peut y rajouter des contrôles pour construire notre première IHM en Silverlight

Et c’est ce que nous allons faire … Ouvrez votre MainPage.xaml, trouvez la balise <Grid> et insérer dedans ce bout de code :

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="110"/>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="110"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="60"/>
        </Grid.RowDefinitions>
        <Button Name="btnTryMe" Content="Show Hello" Grid.Row="1" Grid.Column="1" Click="Button_Click"></Button>

 

Ouvrez ensuite le code behind de MainPage.xaml et y insérer le code suivant :

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello World");
        }

Et voila, notre application Hello World est finie, si vous lancez votre application maintenant, vous trouverez un bouton et si vous cliquez dessus vous devriez avoir quelque chose comme ça :

image

Ce qu’il faut toujours garder en tête c’est que lorsqu’on fait du Silverlight on fait du code qui s’exécute côté client, on n’a donc pas accès à la base de données directement, il faut faire attention au cross-domain …

Pour aller plus loin mais toujours dans le Hello World Spirit, cliquer sur Fichier –>Nouveau –> Projet. Choisir l’élément “Silverlight” dans l’arbre à gauche et choisi le type de projet “Silverlight Navigation Application”.

image

Cliquer sur OK, puis cliquer encore sur OK pour créer le projet web correspondant, le wizard va nous créer cette fois-ci une application Silverlight sample, remarquez le dossier “Views” contenant les écrans de l’application.

image

Lancer le projet, vous devriez avoir une page Home comme celle-ci :

image

l’URL est la suivante : http://localhost:52523/SilverlightApplication4TestPage.aspx#/Home

Ci on clique sur “about” on obtient l’URL suivante http://localhost:52523/SilverlightApplication4TestPage.aspx#/About

et enfin si on clique sur “Back” du navigateur on revient  à l’URL de la page Home, Génial!!! C’est une des nombreuses nouveautés de Silverlight 3, ce dernier embarque un framework de navigation et du coup on peut utiliser la navigation du navigateur même pour les applications Silverlight

Et voila, c’est fini pour ce post, on a fait un Hello World et vu une petite nouveauté Silverlight 3, on verra dans de prochains posts sur Silverlight beaucoup de nouveautés de cette version 3, mais en attendant, n’hésitez pas à laisser vos commentaires :)

Sunday, September 06, 2009 4:04:08 AM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Silverlight 3: les nouveautées#

La version 3 de Silverlight ramène une longue liste de nouveautés tant au niveau ergonomique qu’accès aux données, on peut principalement en citer :

- Framework de navigation (historique du navigateur)

- Ergonomie : De nouveaux contrôles sont apparus comme le “Silverlight Child Window” ou encore “DomainDataSource”

- SLOOB : Silverlight out of browser

Et plein d’autres fonctionnalités avec notamment la sortie des .NET RIA Services qui nous permettront d’exposer la logique métier aux applications clientes de type Silverlight ou encore AJAX.

Nous ferons un tour d’horizon de toutes ces fonctionnalités dans de prochains posts.

Thursday, September 03, 2009 4:44:39 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Silverlight : problème de cross domain lors de l’appel à un service web#

Voici un problème qu’on rencontre souvent en essayant d’accéder à un web service à partir d’une application Silverlight, le web service étant déployé sur http://localhost:xxxx/… et la page contenant l’application Silverlight est déployée sur http://localhost:yyyy/… (Ce qui est le cas lorsqu’on travaille avec le serveur web de visual studio), voici le message d’erreur qu’on obtient :

An error occurred while trying to make a request to URI 'http://localhost:xxxx/Service1.svc'. This could be due to to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent.

Le problème se pose tout simplement parce qu’on n’est pas dans le même domaine et une application client (comme Silverlight ou AJAX) ne peut appeler des services que s’ils appartiennent au même domaine.

Pour remédier à cela on peut tout simplement déployer notre application sur IIS sous le même domaine et abandonner le développement sur le serveur web de visual studio. Mais on peut aussi forcer le service à accepter des appels en cross domain, il suffit d’ajouter à la racine du projet contenant le service web les deux fichiers XML suivants :

crossdomain.xml

  1: <?xml version="1.0"?> 
  2: <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
  3: <cross-domain-policy> <allow-http-request-headers-from domain="*" headers="*"/> 
  4: </cross-domain-policy>

clientaccesspolicy.xml

  1: <?xml version="1.0" encoding="utf-8"?>
  2: <access-policy>
  3:   <cross-domain-access>
  4:     <policy>
  5:       <allow-from http-request-headers="*">
  6:         <domain uri="*"/>
  7:       </allow-from>
  8:       <grant-to>
  9:         <resource path="/" include-subpaths="true"/>
 10:       </grant-to>
 11:     </policy>
 12:   </cross-domain-access>
 13: </access-policy>
Wednesday, September 02, 2009 9:19:55 AM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

All content © 2012, Zied Nemili