August 2010 - Messages

Tutorial 14 – Binder une image stockée en base
31 August 10 04:56 AM | Nico | avec no comments

La vidéo du Tutorial

 

Design du Schéma

Nous allons ajouter les Entités qui contiennent les images des produits. Les images sont contenues dans la table ProductPhoto, qui est associée à la table Product avec la table ProductProductPhoto.

Dans Visual Studio, ouvrez le Schéma AdventureWorks.Entities.

Ouvrez le Server Explorer.

Avec la touche Ctrl enfoncée, sélectionnez les 2 tables ProductPhoto et ProductProductPhoto et dropez les dans le Schéma.
image
Une nouvelle Entité et une Relation sont créées dans le Schéma.

Comme la table ProductProductPhoto a une ForeignKet vers la table Product, la relation est automatiquement créée avec l’Entité Product du schéma.

La relation est une relation 0-N/0-N, mais il n’y a qu’une seule photo par Product.

L’image du produit est dans la colonne LargePhoto, qui est de type ByteArray.

Sauvez le Schéma.
image

Ecriture du code de chargement de l’image

Nous allons ajouter une commande pour charger l’image à partir de la base de données.

Ouvrez le fichier ADWService.cs.

Ajoutez une nouvelle Commande qui renvoie un Byte[] en fonction d’un identifiant de Product.
Byte[] LoadProductPhoto(int productId);
Cette Commande charge les ProductPhotos associées au productId, et renvoie le LargePhoto de la première de la liste; en fait, il n’y a qu’une photo associée par Product.

byte[] IADWService.LoadProductPhoto(int productId)
{
    IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
    List<ProductPhoto> productPhotos = dm.GetAssociated<ProductPhoto, ProductProductPhoto>(productId);
    if (productPhotos.Count > 0)
    {
        return productPhotos[0].LargePhoto;
    }
    return new Byte[0];
}

Ajout du contrôle pour afficher l’image

Ouvrez le fichier ADWControl.htm.

Ajoutez une ligne dans la table pour mettre un contrôle de type AspectizeImage.

Un controle AspectizeImage est un div nommé.

Nommez le contrôle ProductImage.

Compilez le projet.
<tr>
    <td align="right" style="width:200px">Photo:</td>
    <td style="width:200px" ><div aas:name="ProductImage" class="AspectizeImage"></div></td>
</tr>

Binding de l’image

Nous allons maintenant bindé notre contrôle. Ce binding est un peu particulier, car nous n’allons pas bindé de propriétés du controles sur les données du DataSet, mais utiliser directement le binding de la commande sur un événement du contrôle.

Dans BindingStudio, ouvrez la vue ADWProduct.

Ajoutez un Binding sur le contrôle ADWProduct.ProductImage.
image
Ce contrôle n’a pas de propriétés bindables pour afficher l’image, mais un évènement OnNeedImage.

Cet évènement est dynamique, c’est à dire qu’il est levé lorsque le paramètre de la commande bindée change de valeur.

Bindez cet événement sur notre commande serveur.

Le retour de la commande n’est pas bindé dans le DataSet.
image
Bindez le paramètre sur l’identifiant du product qui est sélectionné.

Sauvez la configuration.
image

Si nous lançons notre application, nous constatons bien que le controle image affiche la photo du produit.

image

A chaque sélection de produit, l’image associée est affichée.

Comprenons la cinématique d’échange:

- lorsque l’on sélectionne un Product, le productId prend la valeur du Product sélectionné.

- l’événement dynamique est levé, car le paramètre de la commande a changé de valeur.

- le contrôle Image fabrique une url avec le nom de la commande et le paramètre productId

- le browser appelle l’url, dont le type de retour est un mime type image

- le serveur appelle la commande avec le paramètre productId et renvoie le ByteArray qui représente l’image du produit

- le browser affiche le contenu sous forme d’image

Les échanges entre client et serveur sont minimes, seul le contenu de l’image est échangé, quand nécessaire.

Nous avons affiché une image, sans création de fichier temporaire sur le serveur, en bindant directement un contrôle sur une commande server.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 13 – Binder une ComboBox
30 August 10 03:26 AM | Nico | avec no comments

La vidéo du Tutorial

 

Le DatabaseEnum

Nous allons binder des informations supplémentaires sur l’entité Produit, la taille et l’unité associée.

Dans notre entité Product, nous avons bien la colonne Size:

image

Si nous regardons la table physique dans SQL Server, nous constatons qu’il y a une colonne SizeUnitMeasureCode pour représenter l’unité de mesure de la taille:

image

Cette colonne est une ForeignKey, et n’est pas présente dans mon Schéma. Ceci est normale car les ForeignKey du Schéma sont représentées avec des Relations.

Dans la base physique, la ForeignKey pointe vers une autre Table UnitMeasure, qui est la table de référence des Unités.

image

Nous allons enrichir notre Schéma pour tenir compte de cette table de référence. Nous pourrions ajouter une Entité UnitMeasure, et créer une Relation avec l’Entité Product.

Mais nous avons à notre disposition dans le Schéma, quelques chose de plus adapté pour gérer les tables de références, qui est le DatabaseEnum. Comme son nom l’indique, le DatabaseEnum est un Enum, dont les valeurs sont stockées dans la base.

Nous allons créer ce DatabaseEnum manuellement.

Dans Visual Studio, ouvrez le Schéma AdventureWorks.Entities.

A partir de la Toolbox, dropez un DatabaseEnum.

Nommez le UnitMeasure.
image
Renseignez son PhisicalName et son Schéma.

Mettez la propriété Identifier à False, la clé de cette Table est définie dans la colonne UnitMeasureCode (la propriété Identifier permet de définir automatiquement une colonne Id).
image
Ajoutez la colonne UnitMeasureCode avec les attributs suivants:
- Identifier: True. C’est bien cette colonne qui définit la clé.
- Name: UnitMeasureCode
- Type: String
- PhysicalName: UnitMeasureCode. C’est le nom de la colonne physique tel qu’il est défini dans la base. Si le PhysicalName n’est pas renseigné, le nom logique sera pris par défaut, mais il est plus sur de renseigner cet attribut, si nous souhaitons modifier le nom logique par la suite.
- Size: 3
image
Ajoutez la colonne Name avec les attributs suivants:
- Name: Name.
- Type: String.
- PhysicalName: Name.
- Size: 50.
image
Dans l’entité Product, ajoutez une nouvelle colonne: - Name: SizeUnitMeasureCode
- Nullable: True. Cette colonne peut être null, certains produits n’ont pas de size et donc pas d’unité.
- Type: UnitMeasureCode. Ce nouveau type est maintenant disponible, avec le DatabaseEnum.
- PhysicalName: SizeUnitMeasureCode.

Sauvegardez le Schéma. 
image

Avec notre DatabaseEnum, nous avons un nouveau type disponible. Ce n’était pas le cas avec les Entités; nous ne pouvons pas définir une colonne de type Product ou ProductCategory. Dans le cas de l’Entité, c’est la Relation qui nous permet de définir un lien entre 2 Entités. Dans le cas du DatabaseEnum, il n’y a pas de Relation, c’est le type de la colonne qui définit le lien. Ces 2 logiques sont différentes, même si elles sont représentées par un schéma physique similaire (une ForeignKey entre 2 tables).

Dans quel cas utiliser un DatabaseEnum ?

Le DatabaseEnum est utile quand il s’agit d’une liste de références, dont la liste est peu nombreuse et évolue peu dans le temps. Une liste de Pays, ou Département est un bon exemple de DatabaseEnum. A la différence d’une liste d’Entités, une liste de références est chargée en une fois dans l’application.

Le Contrôle ComboBox

Nous allons maintenant modifier notre Contrôle pour afficher et éditer la taille et l’unité de notre Product.

Dans Visual Studio, ouvrez le fichier MainControls.htm.

Dans le contrôle ADWProduct, ajoutez une ligne dans la table, avec un nouveau contrôle input TxtSize.
<tr>
      <td align="right" style="width:200px">Taille:</td>
      <td style="width:200px" ><input name="TxtSize" type="text" /></td>
</tr>
Ajoutez un controle ComboBox à côté de l'Input TxtSize.

Un controle ComboBox est un Select html, avec un nom. Les valeurs de ce Select sont gérées par le Binding.

Nommez le contrôle CboUnitSize.

Sauvez le fichier et compilez la Solution.
<select name="CboUnitSize"></select>
<tr>
      <td align="right" style="width:200px">Taille:</td>
      <td style="width:200px" ><input name="TxtSize" type="text" /><select name="CboUnitSize"></select></td>
</tr>

ListBinding

Nous allons maintenant Binder ces 2 nouveaux contrôles.

Dans BindingStudio, ouvrez la vue ADWProduct.

Ajoutez 2 Binding sur les 2 contrôles:
- TxtSize
- CboUnitSize

Le Binding de TxtSize est similaire à celui de TxtName; il a une propriété value bindée sur la colonne Size de l’Entité Product.

image
Le Binding de CboUnitSize est de type ListBinding et présente quelques caractéristiques particulières:

DataName: pointe vers la Table qui contient la liste des valeurs à afficher. Dans notre cas, il s’agit du DatabaseEnum UnitMeasure, qui est maintenant présente dans notre DataSet.

DisplayMember: désigne la colonne de la Table qui doit servir à l’affichage. Il s’agit ici de la colonne Name de la Table Unitmeasure.

ValueMember: désigne la colonne de la Table qui contient les valeurs de la liste. Il s’agit de la colonne UnitMeasureCode de la Table UnitMeasure.

SelectedValue: désigne la colonne qui est mise à jour lorsque la Combo sélectionne une valeur. Dans notre exemple, il s’agit de la colonne SizeUnitMeasureCode de notre Product.

Sauvegardez la configuration.
image

Si nous lançons notre application, nous constatons que nos nouveaux contrôles sont bien présents, mais que la liste est vide. En effet, nous n’avons nulle part précisé quand la Table UnitMeasure devait être remplie.

Chargement d’un DataBaseEnum

Nous allons ajouter ce code dans notre Commande de chargement  initial de données.

Dans Visual Studio, ouvrez le fichier ADWService.

Dans la Commande LoadInitialData, ajoutons le chargement du DatabaseEnum UnitMeasure.

Nous avons également une API pour charger tous les DataBaseEnum d’un Domain. Etant que nous avons un seul DatabaseEnum, ce code spécifique suffit pour le moment.

Compilez le Projet et relancez l’Application. 
DataSet IADWService.LoadInitialData()
{
    IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
    dm.LoadEntities<ProductCategory>();
    dm.LoadDatabaseEnum<UnitMeasure>();
    return dm.Data;
}

Nous constatons que la liste est correctement remplie et que la valeur sélectionnée correspond bien à l’Unité du produit courant.

image

Néanmoins, si nous sélectionnons un Product qui a une SizeUnit qui a la valeur null, nous avons l’exception suivante:

image

Ceci est normal, car aucune valeur des Unités n’a la valeur nulle. La ComboBox ne peut trouver une valeur null dans sa liste.

Nous allons donc ajouter une propriété à la ComboBox pour gérer la valeur nulle. Ceci est pris en charge avec la propriété custom NullValueDisplay. Une propriété custom se définit avec l’attribut aas:properties et un couple clé/valeur.

Dans Visual Studio, éditez le fichier MainControls.htm

Dans la définition du contrôle ComboBox, ajoutez la propriété custom NullDisplayValue avec la chaine de caractères que vous souhaitez afficher lorsque la valeur est null.

Compilez le projet.
<select name="CboUnitSize" aas:properties="NullValueDisplay:'Choose Unit ...'"></select>

Si nous relançons l’application, nous constatons que la ComboBox gère bien la valeur nulle et que la valeur affichée est bien la valeur définie dans le contrôle.

image

Voilà, nous avons vu comment binder une ComboBox sur une liste de valeur et définir la valeur d’une colonne d’une Entité à l’aide de cette ComboBox. Les ComboBox fonctionnent également avec des Relations, et il est possible de définir dynamiquement des associations par Binding, entre plusieurs Entités.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 12 – Affichage de vue dynamique
27 August 10 04:49 AM | Nico | 2 comment(s)

La vidéo du tutorial

Affichage de vue par binding

Nous souhaitons améliorer un peu l’ergonomie de notre application, et faire en sorte que la vue de détail d’un produit n’apparaisse que lorsqu’un produit est sélectionné.

Nous allons donc créer une autre vue, vide, qui va masquer la vue produit, quand un autre noeud sera sélectionné.

Dans BindingStudio, ajoutons une nouvelle vue, sur le controle Html.Panel.

Nommons cette vue EmptyView.

Il n’y a rien à binder dans cette vue, il s’agit d’un panel vide.
image
Dans le Layout de la vue ADWMain, ajoutons la vue EmptyView dans la zone ZoneProduct.

Il y a maintenant 2 vues dans la même zone.

Choisissons d’afficher la vue EmptyView par défaut.

La vue ADWProduct ne sera plus affichée par défaut; il ne peut y avoir qu’une vue par défaut pour une zone donnée.

Sauvegardons la configuration.
image

 

Dans notre application, nous constatons bien que la vue ADWProduct n’est plus affichée par défaut.

image

Mais elle ne s’affiche pas non plus lorsque nous sélectionnons un Produit. Pour cela, nous devons ajouter quelques bindings.

Dans la vue ADWArbre, sélectionnons le noeud Product.

Sur son évènement Click, nous pouvons binder une Commande.

Jusqu’à présent, nous avons bindé des Commandes Serveur, mais nous avons à notre disposition des Commandes Client, qui sont exécutées dans le Browser.

Le service UIService, qui fait partie du serveur Aspectize, donne accès à tout un tas de commandes utiles pour gérer les données et les vues en local.

La commande qui nous intéresse est la commande ShowView.

Elle a un paramètre viewName, qui est le nom de la vue à afficher.
image
Bindons le Paramètre sur la vue ADWProduct.

De même que nous avons bindé les paramètres sur les données du DataSet, nous pouvons bindé les paramètres sur les éléments d’une vue.

Notre paramètre est le nom de la vue elle-même.
image
Ajoutons le même CommandBinding sur les noeuds ProductCategory et ProductSubcategory, mais cette fois ci avec le paramètre EmptyView.

Sauvegardons la configuration.
image

Si nous relançons l’application, nous constatons bien que la vue s’affiche quand on click sur un noeud Produit, et qu’elle disparait quand on clique sur un autre noeud.

C’est bien le comportement que l’on souhaitait.

Tri des noeuds de l’arbre

Nous allons faire en sorte que les noeuds de l’arbre soient triés.

Dans la vue ADWTree, sélectionnez le Binding de l’arbre et le NodeBinding ProductCategory.

Chaque noeud a une propriété Sort, qui permet de définir l’ordre de tri des données.

Cliquez sur le bouton image
image
Nous pouvons choisir la ou les colonnes de tri, qui sont toutes les colonnes de l’Entité qui est bindée.

Sélectionnons la colonne Name, avec un tri ascendant.

Nous pouvons faire de même pour les autres NodeBinding.

Sauvegardons notre configuration.

image

 

 

 

 

 

 

Si nous lançons notre application, nous constatons que les noeuds sont bien triés par ordre de nom.

Ce tri est purement visuel, il est fait dans le client, et n’a aucun rapport avec la requête qui est faite en base de données.

La suite, au prochain épisode.

Classé sous : , , ,
Tutorial 11 – Sauvegarde des Données
25 August 10 04:11 AM | Nico | 2 comment(s)

La vidéo du tutorial

Commande de sauvegarde

Nous allons ajouter un bouton qui va nous permettre de sauvegarder nos données dans la Base.

Dans Visual Studio, ajoutons un Bouton dans le Control Toolbar.

Nommons le BtnSave, avec la value Save.

Compilons la solution.
<div aas:control="ToolBar">
    <input name="BtnSave" type="button" value="Save" />
</div>
Dans BindingStudio, ajoutons une nouvelle vue sur le contrôle Toolbar.

Un nouveau Binding apparait pour le bouton BtnSave.

L’évènement click est disponible pour Binder une Commande.

Jusqu’à présent, tous nos Binding de Commande pointaient vers des Commandes Serveur que nous avions écrit dans notre code, et qui concernaient le chargement des données.

Il se trouve que la Commande de sauvegarde de données est complètement générique et déjà disponible dans le serveur.

image
Dans la liste des Commandes, nous voyons le service DataAccessAdventureWorks.

C’est le service que nous avons configuré avec la ConnectionString de la base de données.

Ce service a des commandes bindable, et notamment la commande SaveTransactional.

Cette commande a 2 paramètres, dataSet et updateConcurrencyStrategy.
image

Bindons le 1er paramètre sur notre DataSet ADWData.

Le 2ème paramètre est la gestion de la Concurrence, qui peut prendre les valeurs suivantes:
- 0: la concurrence est testée sur toutes les colonnes, c’est le lock optimiste classique.
- 1: la concurrence est testée sur les colonnes modifiées uniquement. 
- 2: la concurrence n’est pas testée, c’est le dernier qui sauve qui a raison.

Nous allons supprimer le 2ème paramètre, ce qui revient à prendre sa valeur par défaut, qui est le lock optimiste sur toutes les colonnes.

image
Sur la vue ADWMain, ajoutons un Layout pour la vue ToolBar.

Le layout est dans la zone ZoneToolbar, et la vue est affichée par défaut.

Sauvegardons notre configuration.
image

 

En relançant l’Application, nous constatons que la Vue Toolbar s’affiche bien à l’endroit souhaité (nous avions fait le css dans ce but), avec le bouton Save.

image

Si nous modifions un nom de Produit, et que l’on click sur le bouton Save, on constatera que la valeur est bien mise à jour dans la base.

Il faut comprendre le mécanisme d’échange qui est fait ici:

  • Lorsque l’on modifie le nom de Produit, le Binding marque la ligne concernée comme modifiée.
  • Dans le client, à l’appel de la commande Save, le DataSet passé en paramètre est analysé.
  • Toutes les lignes modifiées, ajoutées ou supprimées sont extraites du DataSet.
  • Seules ces lignes altérées sont envoyées au Serveur. S’il n’y a aucun ligne concernée, la Commande n’est pas appelée.
  • Le Serveur reçoit toutes les lignes altérées. A l’aide du Schéma, les Commandes de sauvegarde sont exécutées dans la base. Le lock optimist est pris en compte.
  • Au retour de la commande, et s’il n’y a pas eu d’erreur, les lignes altérées sont passées en Unchanged, de façon à ne plus être prise en compte lors de la prochaine sauvegarde.

Ainsi, l’aller et retour avec le serveur n’est fait que s’il y a réellement des données à sauvegarder, et le volume des données échangées est réduit aux données nécessaires à la sauvegarde.

Voilà, nous avons géré la sauvegarde sans écrire la moindre ligne de code. Quel que soit la complexité du schéma, la sauvegarde est automatique. Nous verrons qu’elle peut être complètement transparente dans la navigation dans notre application, en étant bindée à différents endroits.

La suite, au prochain épisode.

Classé sous : , , ,
Tutorial 10 – Edition de données
24 August 10 04:00 AM | Nico | 2 comment(s)

La vidéo du tutorial

Controle d’édition de données

Nous allons utiliser le controle ADWProduct pour afficher le détail d’un produit, et éditer ses caractéristiques.

Dans Visual Studio, éditons le controle ADWProduct, en lui ajoutant une table et 2 lignes avec le nom et le numéro du produit.

Le controle est défini par du HTML tout à fait standard, nous pouvons organiser les différents éléments comme nous le souhaitons.

Nous pouvons éventuellement enrichir le fichier CSS pour habiller le contrôle.

Compilons la solution.
<div aas:control="ADWProduct">
<table>
<tr>
    <td>Nom du produit:</td>
    <td><input name="TxtProductName" type="text" /></td>
</tr>
<tr>
    <td>Numero du produit:</td>
    <td><input name="TxtProductNumber" type="text" /></td>
</tr>
</table>
</div>
Dans BindingStudio, nous pouvons créer une nouvelle vue sur le Controle ADWProduct.

Automatiquement, 2 Binding sont créés sur chacun des controle Input TxtProductName et TxtProductNumber, et la propriété value a également été ajoutée. 

En fait, à chaque fois qu’un nouveau contrôle est ajouté, BindingStudio crée le Binding associé. Si nous ajoutons un controle, il y a de fortes chances que nous souhaitons binderune donnée dedans. Si vous préférez gérer les Binding manuellement, il est possible de désactiver cette option.
image
Qu’allons nous binder dans la propriété value ? Ce serait logiquement un DataName Product.Name.

Mais nous souhaitons afficher les caractéristiques du produit sélectionné à partir de l’Arbre.

Nous voulons que cette vue soit synchroniser avec l’arbre, donc le DataName qui mène à la table Product doit être le même que dans l’arbre.

Nous reprenons donc le chemin, à partir de la table ProductCategory, puis ProductSubcategory, puis enfin Product, et choisissons la colonne Name.

Le Picker de DataName nous aide à sélectionner cette valeur en naviguant suivant notre schéma.

Nous pouvons choisir de même le DataName du controle TxtProductNumber qui pointe vers la colonne ProductNumber.

image
Comme ce DataName est long, et que la racine est commune à tous les controles de la vue, nous pouvons factoriser cette racine dans le Parent Data de la vue.




















Quand nous choisissons le DataName du contrôle TxtProductName, nous pouvons cocher la case Child Data et renseigner nos DataName relativement à la racine de la vue.

image
image
Il nous reste à lier la vue ADWProduct avec la vue de démarrage ADWMain.

Dans le Layout de la vue ADWMain, nous pouvons ajouter la vue ADWProduct dans la zone ZoneProduct.

Sauvons notre solution.
image

 

 

 

 

Si nous lançons notre Application, nous constatons bien cette nouvelle vue qui est synchronisée avec l’Arbre. 

image

 

Il faut bien comprendre que c’est avec les DataName définis dans le Binding que cette synchronisation est réalisée. En fait, un DataName est un chemin unique pour désigner une Donnée de notre Application. Tous les Contrôles qui pointent vers le même DataName sont automatiquement synchronisés; la donnée est unique en mémoire, et les controles affichent le contenue de la donnée.

Si nous modifions le Nom d’un produit, son nom modifié est immédiatement dans l’Arbre. Le nom est mis à jour parce que le Binding est défini OnPropertyChanged, c’est à dire que la donnée est mise à jour à chaque fois qu’elle change, et donc à chaque frappe du clavier.

Nous pouvons modifier notre Binding pour qu’il soit OnValidation, c’est à dire que la donnée est mise à jour lorsque le contrôle perd le focus. Nous verrons plus tard que ce comportement a un impact sur la validation des données.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 9 – Layout Binding
23 August 10 03:58 AM | Nico | 1 comment(s)

La vidéo du tutorial

Enrichissement de l’arbre

Nous allons ajouter un nœud supplémentaire avec les Product, toujours en lazy loading.

Dans Visual Studio, nous allons ajouter une nouvelle Commande pour charger les Product.

Cette commande est très similaire à la précédente; elle charge les Product associés à une SubCategory donnée par son ID.

Compilez la solution.
DataSet IADWService.LoadProducts(int productSubCategoryId)
{
    IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
    dm.LoadAssociated<Product, ProductProductSubcategory>(productSubCategoryId);
    return dm.Data;
}

Dans BindingStudio, sélectionnez la Vue Explorer, puis le Nœud SubCategory.

Ajouter un Nœud Child.

Le nœud est Contextual.

Configurons le DataName vers la Table

.ProductProductSubcategory.Product

Associez la Property Text à la Colonne Name de l’entité Product.

image

De même que pour le nœud ProductCategory, nous configurons un CommandBinding sur le nœud ProductSubcategory pour appeler la Commande de chargement des Products.

Ajoutez un CommandBinding sur l’événement OnFirstExpand.

Sélectionnez la Commande LoadProducts.

Bindez le paramètre sur la colonne d’identifiant du noeud courant.

Sauvegardez l’application.

image

image

Lançons l’application. L’Arbre affiche bien les 3 niveaux attendus, toujours en Lazy Loading.

image

Layout Binding

Nous allons maintenant améliorer la mise en page de nos Vues.

En fait, nous voulons maintenant que cette vue de données soit dans une vue parent.

Dans nos contrôles, nous avions défini le controle ADWMain:

    <div aas:control="ADWMain">
        <div aas:name="ZoneToolBar" class="Panel"></div>    
        <div aas:name="ZoneTree" class="Panel"></div>    
        <div aas:name="ZoneProduct" class="Panel"></div>    
    </div>

C’est précisément le rôle de ce contrôle, être un container pour les autres contrôles.

Dans BindingStudio, ajoutez une nouvelle Vue sur le controle ADWMain.

Cette vue n’a pas de Binding de données, car elle ne contient que des controles Panel, qui sont des containers d’autres vues, et qui n’affichent pas de données de notre DataSet.

Nous allons configurer le Layout de cette vue.
image
Sélectionnez l’onglet Layout.

Cliquez sur le bouton clip_image002[4], une ligne de Layout apparait.

Nous pouvons sélectionner une des Zone de la vue; il y en a 3, chacune définie par un Panel nommé. Choisissons ZoneTree.

Associons la vue ADWTree.

Cochons la case à cocher, pour signifier que la vue Child est affichée en même temps que la vue Parent (sinon, la zone sera vide).

La vue ADWMain, est maintenant configurée pour contenir la vue ADWTree.
image
Faite un click droit sur la vue ADWMain.

Cliquez sur le Menu “Set as starting View”.

La vue ADWMain est maintenant définie comme vue de démarrage.

Sauvez l’Application.
image

 

 

 

 

Si nous lançons l’application, nous voyons maintenant que la vue de l’Arbre est délimitée en largeur:

image

Nous allons améliorer un peu le positionnement de la vue, à l’aide d’une feuille de Style.

Dans Visual Studio, ajoutez un fichier Styles.css

Définissez le positionnement des différentes zones, en fonction de leur nom.

Le CSS est tout à fait standard, et permet de personnaliser l’affichage comme vous le souhaitez.
.ZoneToolBar
{
	top:2em;
	left:0;
	height:3em;
	width:100%;
}
.ZoneTree
{
	top:3em;
	left:0;
	height:50em;
	width:34%;
	border: solid 1px;
	border-color:Black;
	overflow:auto;
}
.ZoneProduct
{
	top:3em;
	left:34%;
	width:64%;
	height:20em;
}
Pour que cette feuille de style soit prise en compte, il est nécessaire d’ajouter sa référence dans le fichier ADWWeb.application.htm.ashx, qui contient toutes les références de l’application.

Dans la section CSS Link, ajoutez la ligne:
<link rel='stylesheet' type='text/css' href='~/Style.css' />

Le répertoire du fichier est défini par ~, qui désigne le répertoire de l’Application.

Ce fichier est édité manuellement, car il permet de controler les différents CSS à charger, et l’ordre dans lesquels ils sont chargés. Ceci est utile si vous souhaitez ajouter d’autres CSS comme, par exemple, JQuery.

Compilez la solution.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xmlns:aas='http://aspectize.com/Ajax'>
<head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<!-- CSS Link -->
<link rel='stylesheet' type='text/css' href='../Aspectize.core/Aspectize.css' />
<link rel='stylesheet' type='text/css' href='~/Style.css' />
<!-- JS Files -->
<script type='text/javascript' src='../Aspectize.core/Aspectize.runtime.js'></script>
<script type='text/javascript' src='~/ADWWeb.library.js'></script>
<script type='text/javascript' src='~/main.js'></script>
<title>Aspectize ADWWeb Application</title>
</head>
<body></body>
</html>

Nous voyons maintenant que le CSS est bien pris en compte:

image

Voilà, nous avons vu comment les différentes vues pouvaient être agencées les unes par rapport aux autres, et comment l’application va pouvoir s’enrichir avec de nouvelles vues.

La suite, au prochain épisode.

Classé sous : , , ,
Tutorial 8 – Configurer mon arbre en lazy loading
20 August 10 05:22 AM | Nico | 1 comment(s)

La vidéo du Tutorial

 

Binding relationnel

Ajoutons un noeud fils à notre arbre.

Sélectionnez la vue ADWTree et le nœud ProductCategory

Cliquez sur le bouton Add Child clip_image002 pour ajouter un nœud Child.

Nous voulons que le nœud Child soit contextuel, c'est-à-dire que les données dépendent du Parent. En fait, les SubCategory affichées sont les SubCategory de la Category Parent.

Cliquez sur la case à cocher Contextual Node.

Le DataName que vous pouvez choisir est contextuel au DataName du nœud Parent, via une Relation du Schema.

Sélectionnez le DataName   .ProductSubcategoryProductCategory.ProductSubcategory

Les Nœuds fils suivront la relation Parent/Child selon le Schema.

image

Associez la Property Text du Nœud à la colonne Name de la Table.

Sauvegardez la configuration.

Lancez l’application pour constater le 2ème niveau de l’Arbre.

image

Mais il n’y a pas de 2ème niveau ! Nous avons beau ouvrir les Nœuds Category, il n’y a pas de nœuds Child !

Ceci est en fait normal. Souvenez-vous que c’est la commande Server, appelée au chargement de la fenêtre, qui charge les données. Or le code de cette commande ne charge que les ProductCategory. Nous pouvons modifier notre code pour charger en même temps les ProductSubCategory :

        DataSet IADWService.LoadInitialData()
        {
            IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
            //dm.LoadEntities<ProductCategory>();
            dm.LoadAssociated<ProductSubcategory, ProductSubcategoryProductCategory>();
            return dm.Data;
        }

L’API LoadAssociated nous permet de charger toutes les Associations entre ProductSubCategory et ProductCategory, en précisant la relation concernée; je pourrais avoir plusieurs relations entre mes entités, et nous devons préciser quelle relation nous voulons utiliser pour la jointure.

Si nous compilons notre solution et relançons l’application, nous constatons que les noeuds fils sont bien chargés cette fois-ci.

image 

Mais ce n’est pas tout à fait ce que nous souhaitons, car les données sont chargées d’un seul coup, et nous voulons avoir un lazy loading, c’est à dire charger les données au fur et à mesure de l'ouverture des noeuds.

Nous allons donc ajouter une 2ème commande, qui charge les SubCategories associées à une Category donnée par son Id:

Dans Visual Studio, ajoutons une 2ème Commande à notre Interface.

Cette Commande a un paramètre productCategoryID.
image
Le code de la Commande charge les SubCategory associé à la Category dont l’ID est passé en paramètre.

Compilez la solution, pour que cette commande soit disponible dans BindingStudio.
DataSet IADWService.LoadSubCategories(int productCategoryId)
{
     IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
     dm.LoadAssociated<ProductSubcategory, ProductSubcategoryProductCategory>(productCategoryId);
     return dm.Data;
}
Dans BindingStudio, nous allons binder cette nouvelle Commande sur l’évènement OnFirstExpand du noeud ProductCategory. image 
Bindons notre Commande.

Le Result est mergé dans le DataSet ADWData.
image
Le paramètre est bindé sur les données de l’arbre, le noeud Current.

Sauvons notre Application.
image

 

 

 

Si nous relançons l’application, nous constatons que notre arbre est bien rempli, comme précédemment. Par contre, d’un point de vue des échanges avec le Serveur, c’est complètement différent, puisqu’un aller et retour se produit, la première fois que nous ouvrons un noeud ProductCategory.

Nous avons réaliser un arbre en lazy loading, en quelques clics de souris, et sans ajouter le moindre code technique.

La suite, au prochain épisode.

Classé sous : , , ,
Tutorial 7 – Première vue, premiers Bindings
19 August 10 04:09 AM | Nico | 1 comment(s)

La vidéo du tutorial

 

Configuration des Vues

Commençons par créer la première Vue de notre Application. Une Vue est une Instance d’un contrôle, que l’on va configurer, c’est à dire :

  • Lier ses propriétés avec des Données, avec un DataBinding.
  • Lier ses événements avec des Commandes, avec un CommandBinding.
  • Lier son affichage avec d’autres Vues, avec un LayoutBinding.

DataBinding

Nous allons créer notre première vue sur le Contrôle ADWTree et faire notre premier DataBinding.

Dans le Solution Explorer, sélectionnez l’Application ADWWeb

Faites un Click Droit et choisissez le menu

Add  clip_image002 New View

Sélectionnez ADWTree

Cliquez sur OK

image

Dans une Vue, nous pouvons ajouter un Binding pour chaque Contrôle de la Vue.

Le Contrôle ADWTree a un Contrôle TreeView, ProductCategoryTree, et le Binding associé est automatiquement créé, il porte le nom ADWTree.ProductCategoryTree, qui est le nom de la vue associé au nom du Contrôle.

image

Commençons par ajouter un nœud en cliquant sur le bouton Add Root clip_image008

Le DataName permet de choisir l’Entité du DataSet associé au nœud ; l’arbre présente toutes les Entités et Relations du Schéma du DataSet

Choisissons l’Entité ProductCategory, pour binder le premier niveau de l’arbre sur cette Entité.

image

La propriété Text du Nœud apparait dans les Node properties.

Associons un DataName.

Cette fois-ci, ce ne sont pas les tables du DataSet, mais les colonnes de la table ProductCategory qui apparaissent

Choisissez Name, le Text du TreeNode est maintenant bindé sur le champ Name de la table des ProductCategory

Sauvegardez

image

Lançons notre Application pour voir le résultat.

Nous ne voyons rien du tout dans la page !

Ceci est normal, car la Table du DataSet est vide. A aucun moment, nous avons défini comment et quand les données sont accédées. Pour faire cela, nous allons ajouter un Binding sur notre Vue pour configurer le chargement des Données. Le bon moment pour appeler notre Commande est le chargement de la vue. Nous allons donc configurer l’événement OnLoad de la vue.

CommandBinding

Ajoutons un Binding sur la Vue en cliquant sur le bouton clip_image014.

Seule le Contrôle de la vue est disponible, la Contrôle ADWTree n’a pas d’autres contrôles configurables, autre que lui-même et le TreeView

image

Dans l’onglet Commands, cliquez sur le bouton clip_image014[1]

Choisir l’évènement OnLoad dans la liste des événements configurables.

Un CommandBinding sur l’évènement OnLoad est ajouté.

image

Sélectionnez notre Commande Server LoadInitialData

image

Sélectionnez le DataSet ADWData en tant Result du CommandBinding

Cochez la case Merge Data

Au chargement de la Vue, la Commande sera automatiquement appelée et son résultat sera fusionné avec le DataSet de l’Application

image

Nous pouvons lancer l’application pour vérifier que notre configuration correspond bien à ce que nous voulons.

clip_image024

Comprenons bien la cinématique de l’application :

· Au chargement de l’application, la Vue de démarrage (ADWTree) est affichée

· Cette vue a un événement OnLoad qui est déclenché.

· Le Binding de l’événement OnLoad est appelé ; il s’agit de la Commande Serveur LoadInitialData.

· Le code de la commande est exécuté sur le Serveur; les données sont requêtées dans la DataBase.

· Le DataSet résultat est envoyé sur le client et est mergé dans le DataSet ADWData.

· Le Contrôle actualise les données contenues dans la table ProductCategory et affiche les différents nœuds.

A noter que tout ceci s’est produit, uniquement parce que nous avons configuré les différents éléments. Aucun code n’a été nécessaire pour programmer cet enchainement. Le seul code qu’il a été nécessaire d’écrire est la logique de chargement des données (et encore, on pourrait imaginer que cela se fasse automatiquement à partir du DataBinding).

De plus, il y a bien eu un aller et retour serveur, mais uniquement pour exécuter une commande et renvoyer des données. Aucun HTML de notre application n’est généré sur le serveur. Nous verrons plus tard, comment cette construction permet d’avoir une application extrêmement fluide.

La suite, au prochain épisode.

Classé sous : , , ,
Tutorial 6 – Configurer l’accès aux données
19 August 10 02:53 AM | Nico | 1 comment(s)

La vidéo du Tutorial

 

Binding Studio

Binding Studio est l’outil avec le quel nous allons configurer les applications.

Par configuration, nous allons déclarer tout ce que nous n’avons pas écrit dans le code :

  • Les caractéristiques des Applications (Sécurité, Log, Trace, …)
  • Le lien entre le code de l’application (les Services et les Commandes), et les Contrôles de l’IHM.
  • Le lien entre les Données du Schéma et les Contrôles de l’IHM.

Toutes les informations sont extraites dynamiquement des dll et des fichiers html, et interviennent dans la configuration de l’Application.

Il faut bien avoir en tête, que nous avons besoin de compiler les projets, pour que les éléments des dll soient configurés dans Binding Studio.

A chaque fois que nous ajoutons un élément configurable dans une dll (Service, Control, Schema), nous devons compiler avec Visual Studio avant de configurer Binding Studio.

Configuration des Données de l’Application

Nous allons d’abord définir quels sont les Modèles utilisés dans l’Application. Chaque Application contient des DataSet, qui sont définis par un nom et nos Domaines.

Ouvrez la configuration de l’Application ADWWeb.

Cliquez sur le Menu contextuel Open

Dans l’onglet ContextData, ajouter un élément avec le bouton clip_image002[4]

Nommez la Data ADWData.

Cochez la case DataSet.

Ajoutez le Domain AdventureWorks

image

L’Application ADWWeb est maintenant configurée pour avoir un DataSet, qui a pour nom Product, et qui contient la structure du Domaine AdventureWorks. Le Domaine AdventureWorks est défini dans le Schéma que nous avons créé dans Visual Studio. Il est possible d’avoir autant de Domaines que l’on souhaite dans un DataSet.

Nous allons exploiter ce DataSet pour configurer le Binding de l’interface utilisateur.

Configuration du Service d’Accès aux Données

L’Application ADWWeb a un seul service configuré, qui est le service d’accès aux données.

Un Service configuré est un service qui a des paramètres définis.

Dans le Solution Explorer, sélectionnez l’Application ADWWeb

Faites un Click Droit et choisissez le menu

Add  clip_image002 New Service

image

Plusieurs types de service sont disponibles.

Choisissez le Type DataBaseService.

Nommez le Service « DataAccessAdventureWork »

image

La liste des paramètres du Service apparaît.

Saisissez votre ConnectionString et le DataBaseType à SQLServer2005.

Sauvegardez la configuration.

image

Remarquez que le nom du service configuré « DataAccessAdventureWork », est le nom utilisé dans le code que nous avons écrit tout à l’heure. Quand l’appel EntityManager.FromDataBaseService("DataAccessAdventureWork") sera fait, c’est précisément cette configuration qui sera chargée, avec les valeurs de ces paramètres.

Il y a de fortes chances que la valeur des paramètres de configuration ne soit pas la même dans un environnement de production. Nous verrons comment modifier ces valeurs pour qu’elles soient prises en compte dans un autre environnement.

 

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 5 – Mes premiers contrôles HTML
18 August 10 03:11 AM | Nico | 2 comment(s)

La vidéo du Tutorial

L’IHM

Nous allons maintenant écrire le code de notre IHM.

Vu qu’il s’agit d’une application Web, il s’agit essentiellement du HTML. Mais le HTML que nous allons écrire n’est pas exactement le HTML qui sera visible dans notre site.

En fait, nous allons créer des contrôles HTML, qui seront instanciés et configurés plus tard, pour faire le rendu de notre site.

Ajoutez un nouvel Item dans le projet

Choisissez le Template Aspectize HTML Control

Nommez le MainControls

Cliquez sur OK

image

Le fichier HTML apparait.

image

Le fichier HTML contient une balise div avec l’attribut aas :control. Il s’agit d’un contrôle HTML, qui pourra être bindé aux données de l’application.

Tous les Contrôles sont des DIV nommés et contiennent juste le HTML d’affichage.

Le HTML d’affichage s’exprime :

  • Avec du HTML standard (Tables, boutons, Texte, Checkbox, Select, …)
  • Avec des contrôles Aspectize (Grid, Tree, Panel, Image, Tab, …) désigné par l’attribut class

Tous les Tags doivent être nommés :

  • Avec l’attribut name= " " , pour le HTML standard
  • Avec l’attribut aas :name= " " pour les contrôles Aspectize

Pour notre exemple, nous allons créer 4 contrôles.

Nous pouvons utiliser la ToolBar et droper les différents contrôles pour générer le HTML.

clip_image006

Ajouter 4 balises div avec l’attribut aas :control et les noms associés :

ADWMain, contrôle de démarrage de l’application

Toolbar, qui contient les boutons de notre application

ADWArbre, qui contient l’arbre de navigation

ADWProduct, qui contient le détail du produit

<div aas:control=”ADWMain”>
</div>
<div aas:control=”ToolBar”>
</div>
<div aas:control=”ADWArbre”>
</div>
<div aas:control=”ADWProduct”>
</div>

Ajoutons le contenu du contrôle ADWMain, qui contient 3 Panel nommé.

<div aas:control="ADWMain">
<div aas:name="ZoneToolBar" class="Panel"></div>
<div aas:name="ZoneArbre" class="Panel"></div>
<div aas:name="ZoneProduct" class="Panel"></div>
</div>

Le contrôle Toolbar contient un bouton Save

<div aas:control=”ToolBar”>
<input type=”button” name=”Save” value=”Save” />
</div>

Le contrôle ADWArbre contient un AspectizeTreeView

<div aas:control=”ADWArbre”>
<div aas:name=”ProductCategoryTree” class=”AspectizeTreeView”></div>
</div>

Le contrôle ADWProduct contient le HTML de détail d’un produit.

Nous pouvons agencer le HTML comme nous le souhaitons, et faire une table pour aligner les différents éléments.

<div aas:control="ADWProduct">
<table><tbody>
<tr>
<td align='right'>Nom du produit :</td>
<td><input type="text" name="ProductName" style="width: 313px" /></td>
</tr>
<tr>
<td align='right'>Numero du produit :</td>
<td><input type="text" name="ProductNumber" style="width: 313px" /></td>
</tr>
</tbody></table>
</div>

Bonne nouvelle ! Nous avons terminé le développement de l’IHM, il n’y a aucun code à écrire.

L’assemblage des contrôles pour former une page se fait dynamiquement avec du binding.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 4 – Ecrire du code serveur pour charger des données
14 August 10 06:54 AM | Nico | 2 comment(s)

La vidéo du tutorial

Le code Serveur

Nous allons maintenant écrire le code Serveur de notre Application Web.

Le code Serveur est principalement chargé de lire les données depuis la base de données.

Le code Serveur est implémenté sous la forme d’un Service. Un Service implémente une Interface qui est constituée de méthodes.

Chaque méthode est une Commande, qui est l’unité de traitements métiers.

Nous allons donc créer un Service ADWService et une commande LoadInitialData() qui a pour objectif de lire les données de la base.

Toutes les commandes de données renvoient un DataSet.

Lecture de données de la base

Ajoutez un nouvel Item dans le Projet

Choisissez le Template AspectizeService (qui doit se trouver dans la Section MyTemplate)

Nommez le ADWService

Cliquez sur OK

clip_image002

Le fichier ADWService.cs est généré, il ressemble à celui-là

clip_image004

Ajoutez une méthode LoadInitialData à l’interface.

Cette méthode n’a pas de paramètres et renvoie un DataSet.

clip_image006

Nous allons écrire le code qui va charger les Entités ProductCategory et retourner le DataSet.

Pour ce faire, nous allons appeler un Service DataBaseService, qui sera configuré pour se connecter à notre base; nous verrons plus loin comment configurer ce service.

Comme tous les services configurés, le service est nommé et a pour nom DataAccessAdventureWork.

Le code est le suivant :

    public interface IADWService
    {
        DataSet LoadInitialData();
    }
    [Service(Name = "ADWService")]
    public class ADWService : IADWService
    {
        DataSet IADWService.LoadInitialData()
        {
            IDataManager dm = EntityManager.FromDataBaseService("DataAccessAdventureWorks");
            dm.LoadEntities<ProductCategory>();
            return dm.Data;
        }
    }

Le composant EntityManager est le composant qui permet l’accès aux données (la couche DAL du Serveur).

Il implémente les Interfaces suivantes :

  • IEntityManager, qui sert à manipuler les données en mémoire
  • IDataManager, qui sert à lire ou écrire les données d’une base
  • IDDLManager, qui sert à générer un script DDL
  • IDataFileManager, qui sert à lire ou écrire des fichiers XML

La méthode LoadEntities<AdventureWorks.ProductCategory> charge toutes les Entités ProductCategory, donc toutes les lignes de la table Production.Category correspondante dans le DataSet sous-jacent.

Toutes les interfaces ont un membre Data, qui permet de récupérer le DataSet sous-jacents.

Il y a d’autres méthodes sur ces interfaces qui permettent d’adresser les données. Nous verrons plus loin l’usage de ces méthodes. L’idée est d’accéder aux données relationnelles de façon logique. Vous pouvez regarder l’aide en ligne pour avoir la description des différentes méthodes.

Compilons notre projet. Nous avons une première version (limitée mais une première version qui fonctionne) de notre Application, avec un Service qui a une seule méthode.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 3 – Création du schéma
13 August 10 07:56 AM | Nico | 2 comment(s)

La vidéo du Tutorial

Le Schéma

Le Schéma est le Contexte Métier de notre application, avec lequel nous allons travailler tout au long du développement et de la configuration de nos Applications.

Il représente les données manipulées par les Applications, qu’il s’agisse de données stockées dans une base ou dans un fichier, ou bien des données affichées dans une IHM.

Toutes ces données ont la caractéristique d’être relationnelles, c'est-à-dire qu’elles ont des relations entre elles. C’est principalement cette caractéristique que le schéma nous aide à modéliser et visualiser.

Le schéma fait partie intégrante du développement, il fait partie de notre projet, et est présent dans les Dll du RunTime. Il sert à la fois de Documentation et de représentation du métier dans le code et la configuration.

Il a été réalisé avec la technologie DSL Tool de Microsoft, et est donc, à ce titre, un plug-in de Visual Studio.

Import du Schéma AdventureWorks

Ajoutons un nouvel élément dans notre projet Visual Studio.

Choisissez le Template AspectizeEntityDesigner.

Nommez le fichier AdventureWorks.Production.Entities

clip_image002

clip_image004

La Zone clip_image006 est la surface du Schéma, là où est représenté le modèle.

La Zone clip_image008 est la boite à outils (ToolBox), à partir de laquelle vous créez les éléments.

La Zone clip_image010 est la fenêtre de propriétés (Properties) dans laquelle vous renseignez les différentes propriétés des éléments du Schéma.

Nous allons importer quelques Entités à partir de la base physique de SQL Server.

Pour accéder à la base SQL Server à partir de Visual Studio, il faut ouvrir la fenêtre « Server Explorer ».

Sélectionnez le nœud « Data Connection » et cliquez sur le Menu « Add Connection »

clip_image012

Choisissez votre Server ainsi que la base AdventureWorks.

Vous pouvez tester la Connection en cliquant sur test Connection.

Cliquez sur OK pour valider la Connection.

clip_image014

La liste des Tables physiques est maintenant accessible dans Visual Studio.

Sélectionnez les 3 tables :

  • Product
  • ProductCategory
  • ProductSubcategory

clip_image016

Drag & Drop les Tables sur la Surface du Schéma.

Réorganisez les différentes Entités et Relations.

clip_image018

Les premiers éléments du Schéma sont importés dans le Designer.

Alors que nous avons importé 3 Tables Physiques, nous avons dans notre Schéma 3 entités (ProductCategory, ProductSubcategory et Product) qui correspondent aux 3 Tables physiques et 2 relations (ProductSubcategoryProductCategory et ProductProductSubcategory) qui correspondent aux 2 ForeignKey des Tables ProductSubcategory et Product.

Les Relations sont représentées à part entière et les ForeignKey n’apparaissent pas dans les Entités.

Le Schéma Logique a ainsi une représentation différente du Schéma Logique.

Compilons notre projet.

error 24  Nous avons une erreur qui nous indique que Class est un mot clé interdit pour un nom de Propriété. Nous pouvons renommer Class en ClassProduct pour permettre la compilation. Nous renommons le nom logique, qui est différent du nom de la colonne physique de la base.

Le binaire ADWWeb.dll contient notre schéma, qui va nous permettre d’utiliser les Données dans notre Application.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 2 – Premier lancement et Configuration
12 August 10 04:58 AM | Nico | 2 comment(s)

La vidéo du Tutorial

Les Outils

Les outils Aspectize sont complémentaires de Visual Studio, et Visual Studio reste l’outil principal pour réaliser le code métier de l’application.

Nous avons à notre disposition :

  • EntityDesigner, qui est un DSL, intégré à Visual Studio, pour réaliser le design des Schemas.
  • BindingStudio, qui est un outil externe, pour créer des Applications, et configurer le Binding des Applications.

Nous avons également des Templates intégrés à Visual Studio :

  • Aspectize Library, Template Projet pour créer une dll
  • Aspectize Schema, Template Item pour créer un Schema
  • Aspectize Service, Template Item pour créer un Service
  • Aspectize UserControl, Template Item pour créer un User Control

Ainsi que quelques snippets pour générer des petits morceaux de code :

  • aasvc pour écrire une classe de Service
  • aauc pour écrire une classe de UserControl (utile en WinForm uniquement)
  • aax pour un Throw

Tous ces Templates ou Snippets, ne sont que des facilités pour créer ou configurer les éléments dans Visual Studio. Il n’y a rien de spécifique qui ne puisse être fait directement avec l’interface de Visual Studio.

Les Template permettent notamment de configurer les éléments suivants:

  • les références nécessaires aux dll Aspectize
  • le répertoire de build dans le bon répertoire de l’Application

Ce que nous pourrions faire manuellement dans Visual Studio.

Host et Application Aspectize

Le Host est le Serveur d’Applications Aspectize. Il est toujours installé par défaut, et il est nécessaire pour faire tourner une application Aspectize client, serveur ou web. Nous pouvons avoir autant de Host que nous voulons sur un poste de travail (bien que l’intérêt soit limité), et leur structure est toujours la même.

Le Host est un répertoire qui contient :

  • Un répertoire Applications qui contient lui-même des sous-répertoires ; chaque sous-répertoire correspond à une Application.
  • Un répertoire Aspectize.core, qui contient tous les binaires Aspectize.
  • Un répertoire bin pour le Host Web, qui contient le HttpHandler.
  • Le fichier AspectizeHost.exe, qui est l’exécutable du serveur d’Applications (utile pour les applications WinForm ou Serveur).
  • Le fichier Web.Config pour IIS

clip_image001

Une Application Aspectize, est un répertoire du Host, qui a le nom de l’Application.

Chaque répertoire d’Application contient :

  • Les DLL de code, réalisées avec Visual Studio.
  • Toutes les ressources de l’Application ; les fichiers HTML, JS, CSS, images…
  • Un fichier de configuration « nomapplication.config.aas », produit par Binding Studio. Ce fichier est un fichier binaire, non éditable.
  • Eventuellement, il peut y avoir un autre fichier de configuration « nomapplication.production.aas » qui est la configuration de production, et qui permet de surcharger les éléments de configuration dans l’environnement de Production. Nous verrons ce point plus tard, lors de la mise en production.

Il peut également y avoir des répertoires supplémentaires, qui contiennent des DLL partagées par plusieurs Applications. Dans ce cas, il n’y a pas de fichier de configuration dans ce répertoire, il y a juste des DLL qui seront chargées au démarrage d’une Application située dans un autre répertoire.

Une Application est Client, Serveur ou Web. Toutes les Applications sont créées avec Binding Studio.

Pour déployer une Application Aspectize, il suffit de déployer le répertoire de l’Application dans le Host.

Avant de lancer Binding Studio, il faut disposer d’un répertoire vide accessible en écriture.

ATTENTION : si plusieurs personnes partagent le même projet, il est nécessaire que le chemin logique du Host soit le même pour tout le monde. En effet, ce path est utilisé par VisualStudio comme target path, et est donc présent dans le fichier du projet.

Il peut être pratique de créer un disque logique, de façon à uniformiser le chemin d’accès au Host. Vous pouvez le faire en exécutant, par exemple, la ligne de commande suivante (Démarrer à Executer) : « subst S: D:\Test\Aspectize ».

clip_image003

Afin de disposer de ce disque à chaque démarrage du poste, configurez la registry ainsi :

Lancez Regedit.exe.

clip_image005

Ouvrez la clé suivante : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Ajoutez une entrée « String Value », que vous pouvez appeler Host Aspectize (le nom n’a aucune importance).

Editez la valeur avec votre ligne de commande : « subst S: D:\Test\Aspectize ».

Ainsi, à chaque démarrage de votre poste, vous aurez un répertoire S:\ qui est votre LocalHost Aspectize.

Dans la suite, nous travaillerons avec le Host C:\AspectizeHost.

Binding Studio

Démarrons Binding Studio.

La première fois que nous lançons Binding Studio, nous devons préciser l’emplacement du Host local de développement.

clip_image007

Choisissez le répertoire du Host

C:\AspectizeHost

Cliquez sur Next

 

clip_image009

Si vous ne souhaitez pas faire d’application Web, la configuration est terminée.

Cliquez sur Yes si vous souhaitez faire des Applications Web pour configurer le LocalHost en mode Web.

clip_image011

Choisissez l’Alias du site Web

WebHost

Cliquez sur Create Application

 

Un répertoire virtuel sera automatiquement créé. Vous pouvez aussi faire cette configuration à la main dans IIS :

Lancez la configuration d’IIS (qui se trouve dans les Outils d’Administration) et cliquez sur le Menu « Add Application » sous le site par défaut.

clip_image013

Saisissez WebHost comme Alias, et le répertoire du Host « C:\AspectizeHost » comme répertoire physique.

clip_image015

Cliquez sur OK, pour valider la création de l’Application.

Le Serveur Web est maintenant accessible, toutes les URL débutent par http://localhost/WebHost. C’est l’URL du Local Host Aspectize.

Si nous revenons dans BindingStudio, nous pouvons tester la configuration de notre Host :

clip_image017

Si vous cliquez sur Test, la page suivante doit s’afficher :

clip_image019

Si ce n’est pas le cas, il est possible qu’il y ait un problème avec ASP.NET.

Vous pouvez réinitialisez ASP.NET avec la commande aspnet_regiis.exe, comme cela est expliqué dans le lien du bouton Help.

Tant que vous n’avez pas cette page qui s’affiche, c’est que la configuration d’IIS n’est pas bonne.

Cliquez sur Close pour fermer l’assistant.

Binding Studio est prêt à l’utilisation. L’onglet StartPage est affiché par défaut à chaque démarrage de BindingStudio.

clip_image021

Nous allons créer une première Application.

Sur l’onglet de démarrage, cliquez sur Create.

clip_image023

Sélectionnez Web Application

 

Donnez-lui un nom

ADWWeb

Choisissez une Location

C:\TestAspectize

Le répertoire de stockage n’est pas le même répertoire que le Host, c’est un répertoire qui va contenir les sources de la configuration de notre Application. Ce répertoire contiendra les fichiers qui pourront aller dans un gestionnaire de sources, comme Visual SourceSafe ou Team System.

Cliquons sur OK, notre première Application est créée.

Nous pouvons lancer l’Application en cliquant sur le bouton Launch de la barre d’outilsclip_image025.

La fenêtre du Navigateur s’affiche ; pour l’instant, cela n’a pas d’autre intérêt que de valider que le Host fonctionne correctement.

Nous pouvons regarder le contenu du répertoire D:\Test, que nous avons choisi pour y créer notre Application. Il y a un répertoire ADWWeb avec les fichiers de travail de Binding Studio :

  • ADWWeb.aapp
  • ADWWeb.asln

Ce sont des fichiers XML, qui contiennent la configuration éditée par Binding Studio. Le fichier ADWWeb.asln est le fichier de la solution, le fichier ADWWeb.aapp est le fichier de l’application.

De même qu’il y a des sources Visual Studio (*.sln, *.csproj, *.cs, …), et que Visual Studio génère un binaire (*.dll ou *.exe), il y a des sources Binding Studio (*.asln, *.aapp, *.aviw) et Binding Studio génère un fichier binaire *.Config.aas.

Regardons le contenu du répertoire S:\ :

  • Le répertoire Applications, qui contient un répertoire ADWWeb, qui contient le fichier ADWWeb.Config.aas, qui est le fichier de configuration généré par Binding Studio. C’est aussi dans ce répertoire, que Visual Studio copiera les dll et les fichiers html/css de la solution (et la raison pour laquelle ce répertoire doit être le même pour tout le monde).
  • Le répertoire Aspectize.core, qui contient les binaires Aspectize
  • Le répertoire bin qui contient les fichiers AspectizeHttpHandler.dll et BootHost.dll, nécessaire pour l’intégration dans IIS.

L’organisation des fichiers de travail est présentée ici :

clip_image027

Nous pouvons créer notre projet Visual Studio qui va contenir le code source de notre Application.

Dans Visual Studio créons un Nouveau Projet.

Choisissons le Template Aspectize Web Application, qui permet de créer une Application Web.

Nommons le projet ADWWeb.

Cliquez sur OK

clip_image029

Une boite de Dialogue apparait pour choisir notre Application Aspectize ADWWeb précédemment créée, avec laquelle elle est liée.

Cela permet de copier tous les binaires au bon endroit.

Cliquez sur OK, le projet est créé.

clip_image031

Notre environnement de travail est maintenant prêt, et nous allons pouvoir commencer à écrire le code et configurer les Applications.

Par configuration, nous allons déclarer tout ce que nous n’écrirons pas dans le code :

  • Les caractéristiques des Applications (Sécurité, Log, Trace, …)
  • Le lien entre le code de l’application Serveur (les Services et les Commandes), et l’application Cliente.
  • Le lien entre les Données du Schéma et les Contrôles de l’IHM.

Cycle de Travail

Par la suite, nous allons suivre la démarche préconisée avec la solution Aspectize:

1 Création du Schéma avec Aspectize Entity Designer

2 Ecriture du Code Serveur avec Visual Studio

3 Design de l’IHM avec Visual Studio

4 Configuration avec Aspectize Binding Studio

clip_image032

C’est le cycle principal de développement qui est montré ici. L’objectif est de travailler en cycles courts et d’avoir une application qui fonctionne et qui est montrable dès le premier jour du développement.

Nous ferons un premier cycle pour la lecture de la première table et le début de la visualisation des données dans l’IHM. Puis d’autres pour les données successives.

Nous ferons un autre cycle pour sauvegarder les données dans la base. Puis un autre, pour la validation des données.

En fait, à chaque étape, nous procéderons selon ce cycle court et pragmatique.

La suite au prochain épisode.

Classé sous : , , ,
Tutorial 1 – Installation
11 August 10 05:34 AM | Nico | 3 comment(s)

Préambule et Objectifs

L’objectif de ces tutoriaux est de prendre en main la solution Aspectize par la pratique. Il s’agit de montrer l’approche que nous préconisons, et comment réaliser concrètement une application.

L’Application à réaliser est une Application Web sur la base Adventure Works, base exemple de SQL Server.

L’application permet de :

  • naviguer dans l’arborescence des produits, regroupés par Catégories et Sous-catégories
  • visualiser des données d’un produit
  • modifier les données d’un produit
  • valider les données saisies par l’utilisateur
  • sauvegarder les données dans la base
  • gérer la sécurité de mon application

A l’issu de ces tutoriaux, vous aurez tous les éléments pour démarrer votre propre application avec les outils Aspectize.

La durée totale des tutoriaux doit être de l’ordre de 4h.

Les tutoriaux sont développés en C#, mais il est tout à fait possible de le faire de la même façon en VB.Net. Si vous êtes plus à l’aise en VB.Net, n’hésitez pas à le faire, le peu de code à écrire ne sera pas un problème pour l’adapter.

La vidéo du tutorial

 

 

Pré-requis et Installation

Avant de commencer, nous devons avoir installé :

  • Visual Studio 2005 ou 2008 SP1 (la version Professional convient très bien). La version 2010 arrivera prochainement et il n’y a aucune particularité vis à vis de la version de Visual Studio, tout fonctionne exactement de la même façon.
  • SQL Server 2000 ou 2005 ou 2008 (la version Express convient très bien)
  • IIS version 6 minimum et ASP.NET ; si ces composants ne sont pas installés, le Setup ne pourra pas se dérouler correctement.

Nous allons procéder à l’installation des produits Aspectize :

  • Aspectize Binding Studio
  • Aspectize Entity Designer (version pour VS 2005 ou VS 2008)
  • Base de Données Adventure Works

Les Setup sont téléchargeables ici: http://aspectize.com/files/folders/products/entry1346.aspx

 

Installation de Aspectize Entity Designer

Dans le sous-répertoire EntityDesigner2008 (ou EntityDesigner2005 si vous travaillez avec Visual Studio 2005), lancez AspectizeEntityDesigner.msi pour installer Entity Designer. Il s’agit d’un plug-in Visual Studio, de type DSL.

Il n’y a aucune option particulière dans le Setup, suivez les étapes de l’Assistant : ce Setup est un peu lent, car il interagit avec Visual Studio. Il faut donc être patient…

clip_image002

 

Installation de Aspectize Binding Studio

Dans le répertoire de livraison, lancez BindingStudio.msi pour installer Binding Studio.

Dans l’écran des options, cochez les cases Aspectize Binding Studio, Visual Studio Templates et Aspectize Web Application Server for IIS.

clip_image004

 

Installation de la base AdventureWorks

La base AdventureWorks est disponible en téléchargement à l’URL suivante : http://msftdbprodsamples.codeplex.com/

Lancez AdventureWorks.msi.

Ouvrez SQL Server Management Studio.

Un Refresh de l’Explorer doit faire apparaître la base AdventureWorks.

Voilà, c’est fini, nous allons pouvoir commencer à développer notre application, la suite au prochain épisode.

Classé sous : , ,