Partager via


Cet article a fait l'objet d'une traduction automatique.

Bus des services Windows Azure AppFabric

Création d'un client continu à l'aide des bibliothèques de classes portables

David Kean

Téléchargez l'exemple de Code

Je me sens chanceux de vivre dans les jours de périphériques connectés en permanence.J'aime que je suis en mesure de répondre au courrier électronique à l'aide de mon téléphone tout en surfant sur le bus à domicile.C'est incroyable d'être capable de Skype avec ma famille à l'autre bout du monde et faire équipe avec des joueurs à travers le pays sur ma Xbox.Toutefois, dans ce monde de connectivité permanente à Internet, il y a, comme Joshua Topolsky, « un chaînon manquant dans notre expérience informatique » (engt.co/9GVeKl).

Ce chaînon manquant se réfère à l'absence de ce que Topolsky appelle un client continu ; C'est une solution de workflow brisée qui se produit lorsque vous déplacez d'un périphérique à l'autre.Que je passe chez mon PC, la tablette et le téléphone dans une journée typique, mon état actuel browsing session, documents, windows et application devrait circuler naturellement à chacun d'entre eux.De cette façon, je passe moins de temps sur la commutation de contexte et de plus de temps sur le jeu et le travail réel.

Dans cet article, je vais vous montrer comment créer une application client continu simple qui s'étend sur multiples plates-formes et périphériques.Je vais faire utiliser de nouvelles bibliothèques de classes Portable (PCLs) afin de faciliter le développement d'une application multi-plateforme et le nuage — en particulier Windows Azure AppFabric Service Bus — pour gérer la communication entre les périphériques.

Votre maison de façon …

C'est la fin de l'après-midi et je suis au travail, essayer de régler rapidement ce dernier bug, donc puis-je éviter les heures de pointe.L'appel téléphonique inévitable vient : « Miel, sur votre chemin d'accueil peut vous pick up certains lait, de pain et de pois chiches? » I hang up, se rendre au magasin et réaliser que j'ai oublié ce qu'il faut acheter.En fin de compte, je dirige la maison avec des articles que nous avons déjà dans le garde-manger.C'est frustrant et solution d'aujourd'hui tend à impliquer beaucoup de vocation dos-et-vient de Téléphone : « Avez-vous dit pois congelés ou pois chiches? » « Pois chiches.Et pendant que vous y êtes, pouvez vous acheter papier toilette ?

Pour aider à soulager les tensions de notre mariage autour de cette question particulière (les autres devront attendre un autre jour), j'écrirai une application simple appelée « Sur Your Way Home » qui s'exécute sur nos dispositifs à base de Windows Phone et Windows 8 bêta comprimés et permet à ma femme et moi suivre facilement notre liste d'épicerie.Il gardera nous tous les deux informé, en temps réel, de tout changement à la liste des courses ainsi qu'à tout moment, nous savons exactement ce que nous avons besoin d'acheter.

Étant donné qu'un smartphone fenêtre Téléphone et une tablette Windows 8-base sont des dispositifs différents, avec des saveurs différentes de Microsoft en cours d'exécution.NET Framework et Windows, j'utiliserai PCLs pour résumé les différences de la plateforme de rangement et me permettent de partager autant logique d'application que possible, y compris tous les de la communication avec le Bus de Service Windows Azure AppFabric.J'utiliserai également le patron modèle-vue-View (MVVM) (bit.ly/GW7l) afin de faciliter l'utilisation des mêmes modèles et ViewModels de notre point de vue spécifique au périphérique.

Bibliothèques de classes portable

Dans le passé, le développement cross-platform dans le.NET Framework n'a pas été facile.Tandis que le.NET Framework avait de grands rêves comme un moteur d'exécution multiplate-forme, Microsoft n'a pas encore entièrement remis sur la promesse.Si vous avez jamais tenté de livrer un.Application basée sur le NET Framework ou le cadre qui s'étend sur plusieurs périphériques, vous aurez remarqué que peu de choses a obtenu de la façon.

Du côté du Runtime l'Assemblée affacturage, versionnage et Assemblée noms sont différents entre le.Plates-formes nets.Par exemple, System.Net.dll sur le.NET Framework, qui contient des API réseau peer-to-peer, signifie quelque chose de complètement différent sur Silverlight, où il contient la pile de réseau de base.Pour trouver ces API sur le.NET Framework, vous aurez besoin de référence System.dll.Les versions d'assembly ne sont également pas les mêmes ; Silverlight adopte 2.0.5.0 pour les versions 2.0 à 4, alors que 2.0.0.0 et 4.0.0.0 ont été adoptées pour.NET Framework versions 2.0 à 4.Ces différences ont, dans le passé, ont empêché un assembly compilé pour une plate-forme de s'exécuter sur un autre.

Sur le Visual Studio côté droit dès le début, vous devrez décider quelle plateforme cible — les.NET Framework, Silverlight ou Windows Phone.Une fois cette décision prise, il est extrêmement difficile de déménager ou de soutenir une nouvelle plate-forme.Par exemple, si vous êtes déjà ciblant le.NET Framework, ciblant le.NET Framework et Silverlight signifie la création d'un nouveau projet et soit copier ou lier les fichiers existants dans ce projet.Si vous êtes chanceux, vous peut-être avez factorisé votre application de telle manière que les pièces spécifiques de la plate-forme sont facilement remplacés.Sinon (et c'est sans doute plus probable), vous aurez besoin de # If plate-forme votre chemin autour de chaque construire erreur jusqu'à ce que vous avez une génération propre.

C'est où les nouvelles PCLs peuvent aider.PCLs, disponibles comme un add-on gratuit pour Visual Studio 2010 (bit.ly/ekNnsN) et intégré à la version bêta de Visual Studio 11, fournir un moyen facile de cibler plusieurs plateformes à l'aide d'un seul projet.Vous pouvez créer un nouveau PCL, choisir les cadres, vous souhaitez cibler (voir Figure 1) et commencer à écrire du code.Sous les couvertures, les outils PCL gérer les différences d'API et filtrent IntelliSense afin que vous voyez seules les classes et les membres qui sont disponibles et fonctionnent dans tous les cadres que vous ont sélectionnés.L'assembly résultant peut ensuite référencé et exécuter, sans changement, sur tous les cadres indiquées.

Portable Class Library Target FrameworksFigure 1 Portable classe bibliothèque cible cadres

Présentation de la solution

Une manière typique pour organiser une application multi-plateforme en utilisant un PCL est d'avoir un ou plusieurs projets portables contenant les composants partagés et ont des projets spécifiques de la plate-forme pour chaque plate-forme qui fait référence à ces projets.Pour cette application, j'aurez besoin de deux solutions de Visual Studio — un créé dans Visual Studio 2010 (OnYourWayHome.VS2010) contenant mon app Windows Phone et l'autre créé dans Visual Studio 11 (OnYourWayHome.VS11) contenant mon application Windows Metro-style.J'ai besoin des solutions multiples parce qu'au moment de l'écriture, la Windows Phone SDK 7.1 fonctionne seulement sur le dessus de Visual Studio 2010, tandis que les nouveaux outils de Windows 8 sont disponibles uniquement dans le cadre de Visual Studio 11.(Actuellement), il n'existe pas une seule version qui prend en charge tous les deux.Ne désespérez, cependant ; une nouvelle fonctionnalité disponible dans Visual Studio 11 m'aide ici.Je suis en mesure d'ouvrir la plupart des projets créés dans la version précédente sans avoir à les convertir au nouveau format.Cela me permet d'avoir un seul projet PCL et de référence à partir de ces deux solutions.

Figures 2 et 3 montrent la mise en page de projet pour mon application.Sur votre­WayHome.Core, un projet PCL, contient les modèles, modèles de point de vue, services communs et abstractions de la plate-forme.Sur votre­WayHome.ServiceBus, aussi un projet PCL, contient les versions portables des API qui vont parler de Windows Azure.Les deux projets sont partagés entre la solution Visual Studio 2010 et Visual Studio 11.OnYourWayHome.Phone et OnYourWayHome.Metro sont des projets spécifiques de la plate-forme Windows Phone 7,5 et.NET pour les applications Metro-style, respectivement.Ceux-ci contiennent les vues spécifiques au périphérique (tels que les pages de l'application) et les implémentations des abstractions dans OnYourWayHome.Core et OnYourWayHome.ServiceBus.

Windows Phone Project Layout in Visual Studio 2010Figure 2 Windows Phone mise en page de projet dans Visual Studio 2010

Windows Metro-Style App Project Layout in Visual Studio 11La figure 3 Windows Metro-Style App projet mise en page dans Visual Studio 11

Conversion de bibliothèques existantes en PCLs

Pour communiquer avec Windows Azure, j'ai téléchargé l'échantillon Silverlight inter-domaines reste de servicebus.codeplex.com et converti en un projet PCL.Certaines bibliothèques sont plus faciles à convertir que les autres, mais vous serez inévitablement exécuter dans des situations où une méthode ou un type de donnée n'est disponible.Voici quelques raisons typiques qu'une API donnée ne pourrait pas être prise en PCLs :

L'API n'est pas mis en œuvre par toutes les plateformes traditionnelles.Fichier NET Framework IOs, comme System.IO.File et System.IO.Directory, tombent dans ce seau.Silverlight et Windows Phone utilisent les API System.IO.IsolatedStorage (si différente de la.NET Framework version), alors que Windows 8 Metro-style apps utilisent Windows.Storage.

L'API n'est pas Compatible à travers toutes les plates-formes certaines API apparence même, mais c'est difficile ou impossible d'écrire du code contre eux de manière portable et compatible.ThreadStaticAttribute, qui permet aux champs statiques pour avoir une valeur unique pour chaque thread, est un exemple.Bien qu'il est présent sur les plates-formes de la Windows Phone et la Xbox, ni de leurs exécutions le permet.

L'API est considéré comme obsolète ou héritage ces API soit contenir le comportement est peu susceptible d'être présente sur les futures plates-formes, ou ils ont été remplacés par des technologies plus récentes.BackgroundWorker est un exemple ; Il fut remplacé par le groupe de travail et les nouvelles fonctionnalités de programme asynchrone dans la version bêta de Visual Studio 11.

Nous avons Ran de temps plus API Weren ' t écrit la portabilité à l'esprit.Nous passons énormément de temps traverse chaque API pour s'assurer, qu'il peut être programmé de manière portable contre.Cela pourrait impliquent tweaking ou l'ajout de l'API pour le rendre portable.En raison du temps et des efforts impliqués, dans la première version de PCLs, nous avons mis à la disposition de Visual Studio Gallery, nous la grande valeur de la priorité, très utilisé API.System.Xml.Linq.dll et System.ComponentModel.DataAnnotations.dll sont des exemples d'API qui n'étaient pas disponibles dans cette première version, mais qui est maintenant disponibles dans la version bêta de Visual Studio 11.

Il y a deux façons de gérer une API qui tombe dans un de ces scénarios.Il y a parfois un simple remplacement.Par exemple, les méthodes Close (méthode Stream.Close, TextWriter.Close et ainsi de suite) ont été désapprouvées dans PCL et remplacés par Dispose.Dans de tels cas, c'est une question de remplacer un appel à l'ancienne avec ce dernier.Mais parfois c'est un peu plus difficile et prend plus de travail.Une situation que j'ai rencontrés lors de la conversion de l'API de Bus Service impliqué le fournisseur de code de hachage SHA256 HMAC.Il n'est pas disponible dans un PCL en raison des différences cryptographie entre Windows Phone et Metro-style apps.Utilisation de apps Windows Phone.API axée sur le NET pour crypter, décrypter et le hachage des données, tandis que le métro-style apps utilisent le nouveau native Windows Runtime (WinRT) API.

Le code en particulier qui échoué à construire après que la conversion était la suivante :

using (HMACSHA256 sha256 = new HMACSHA256(issuerSecretBytes))
{
  byte[] signatureBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(token));
  signature = Convert.ToBase64String(signatureBytes);
}

Pour aider à combler le fossé entre la cryptographie Téléphone API et la crypto WinRT APIs, j'ai inventé une abstraction de la plate-forme qui représente l'exigence de Service Bus. Dans ce cas, le Bus de Service nécessaire à un moyen de calculer un hachage SHA256 HMAC :

public abstract class ServiceBusAdapter
{
  public static ServiceBusAdapter Current
  {
    get;
    set;
  }
  public abstract byte[] ComputeHmacSha256(byte[] secretKey, byte[] data);
}

J'ai ajouté des ServiceBusAdapter au projet de portable, ainsi qu'une propriété statique pour l'établissement de l'abstraction actuelle, qui deviendra plus tard importante. Ensuite, j'ai créé Windows 8 spécifique SHA256 HMAC implémentations de cette abstraction et de Windows Phone - et mettez dans leurs projets respectifs, comme le montre Figure 4.

Implémentations de SHA256 HMAC figure 4 pour Windows Phone et Windows 8

// Windows Phone implementation
public class PhoneServiceBusAdapter : ServiceBusAdapter
{
  public override byte[] ComputeHmacSha256(byte[] secretKey, byte[] data)
  {
    using (var cryptoProvider = new HMACSHA256(secretKey))
    {
      return cryptoProvider.ComputeHash(data);
    }
  }
}
// Windows 8 implementation
public class MetroServiceBusAdapter : ServiceBusAdapter
{
  private const string HmacSha256AlgorithmName = "HMAC_SHA256";
  public override byte[] ComputeHmacSha256(byte[] secretKey, byte[] data)
  {
    var provider = MacAlgorithmProvider.OpenAlgorithm(HmacSha256AlgorithmName);
    var key = provider.CreateKey(_secretKey.AsBuffer());
    var hashed = CryptographicEngine.Sign(key, buffer.AsBuffer());
    return hashed.ToArray();
  }
}

Au démarrage du projet Windows Phone, je puis « bootstrap » le Bus de Service en définissant l'adaptateur de téléphone spécifiques comme la carte actuelle :

ServiceBusAdapter.Current = new PhoneServiceBusAdapter();

J'ai fait de même pour le projet Windows 8 :

ServiceBusAdapter.Current = new MetroServiceBusAdapter();

Avec tout en place, je l'ai changé alors le code d'origine non-compilation d'appeler par le biais de la carte :

var adapter = ServiceBusAdapter.Current;
byte[] signatureBytes = adapter.ComputeHmacSha256(issuerSecretBytes, Encoding.UTF8.GetBytes(token));

Si bien qu'il y a deux façons de calculer le hachage selon la plate-forme, le projet portable parle à la fois en utilisant une seule interface. Cela peut prendre un peu de travail à l'avant, mais je peux facilement réutiliser l'infrastructure que j'exécute en API plus besoin de transition entre les plates-formes.

Comme une note de côté, j'ai utilisé une propriété statique d'accéder et de s'inscrire à l'adaptateur, ce qui le rend plus facile de passer à l'utilisation de la carte des API existantes. Si vous utilisez un cadre d'injection de dépendance comme le cadre d'extensibilité géré (MEF), l'unité ou Autofac, vous trouverez qu'il est naturel à inscrire l'adaptateur spécifique à la plateforme dans le conteneur et le conteneur « d'injecter » la carte dans des composants portables qui en ont besoin.

Mise en application

Ma shopping liste application, sur Your Way Home, a deux idées simples : ShoppingListView, qui affiche les éléments de cours sur la liste d'épicerie ; et AddGroceryItemView, qui permet à un utilisateur d'ajouter plus d'éléments à la liste. 5 Figures et 6 montrer les versions Windows Phone de ces vues.

ShoppingListView
Figure 5 ShoppingListView

AddGroceryItemView
Figure 6 AddGroceryItemView

ShoppingListView affiche tous les éléments qui doivent encore être achetés, avec l'idée que vous vous promenez autour du magasin, vérifier sur chaque élément que vous l'ajoutez à votre panier. Après avoir acheté les articles, en cliquant sur check out provoque les éléments activés soit retiré de la liste, que n'est plus, ils ont besoin d'être acheté. Dispositifs de partage la même liste de magasinage instantanément (puits, aussi instantanément que permet le réseau derrière elle) voir modifications apportées par une autre personne.

Les points de vue, qui vivent dans les projets spécifiques de la plate-forme, consistent principalement en XAML et ont très peu codebehind, qui limite la quantité de code, que vous devez dupliquer entre les deux plates-formes. À l'aide de la liaison de données XAML, les points de vue lient à portable ViewModels qui fournissent les commandes et les données qui s'exécutent les points de vue. Parce qu'il n'y a aucun cadre commun de l'interface utilisateur que les navires sur toutes les plateformes, projets PCL ne référence API d'interface utilisateur spécifique. Toutefois, lorsque la cible des cadres qui les soutiennent, ils peuvent profiter des API qui est généralement utilisés par les ViewModels. Cela comprend les types de base qui font le travail, telles que INotifyPropertyChanged, ICommand et INotifyCollectionChanged de liaison de données XAML. Aussi, bien que le cadre WinRT XAML ne supporte pas les, System.ComponentModel.DataAnnotations et INotifyDataErrorInfo ont été ajoutés par souci d'exhaustivité, et cela permet aux cadres de validation de XAML personnalisées à l'appui des ViewModels/modèles portatifs.

7 Chiffres et 8 montrent des exemples d'interactions vue/View. La figure 7 montre les contrôles de la version de téléphone de la fenêtre de AddGroceryItemView et de leurs liaisons. Ces contrôles sont liés contre les propriétés sur la AddGroceryItemViewModel, qui est partagée avec le Windows Phone et le Windows 8 projets, comme le montre Figure 8.

Figure 7 commandes de AddGroceryItemView pour fenêtre Téléphone

<StackPanel>
  <TextBox Text="{Binding Name, Mode=TwoWay}"
           Width="459"
           Height="80" />
  <Button Command="{Binding Add}"
          Content="add"
          Margin="307,5,0,0" />
  <TextBlock Text="{Binding NotificationText}"
             Margin="12,5,0,0"/>
</StackPanel>

Classe de AddGroceryItemViewModel de la figure 8 pour Windows 8

public class AddGroceryItemViewModel : NavigatableViewModel
{
  private string _name;
  private string _notificationText;
  private ICommand _addCommand;
  [...]
  public ICommand AddCommand
  {
    get { return _addCommand ??
(_addCommand = new ActionCommand(Add)); }
  }
  public string Name
  {
    get { return _name ??
String.Empty; }
    set { base.SetProperty(ref _name, value, "Name"); }
  }
  public string NotificationText
  {
    get { return _notificationText ??
string.Empty; }
    set { base.SetProperty(ref _notificationText, value, "NotificationText"); }
  }
}

Événement de Sourcing

Sur Your Way Home repose lourdement autour du concept d'événement sourcing (bit.ly/3SpC9h). C'est l'idée que toutes les modifications de l'État à une application sont publiées et stockées comme une séquence d'événements. Dans ce contexte, les événements ne désigner la chose définie par le mot-clé c# événement (bien que l'idée est la même), mais plutôt de classes concrètes qui représentent un seul changement au système. Ceux-ci sont publiés par ce qu'on appelle un agrégateur d'événements, qui avertit ensuite un ou plusieurs gestionnaires d'événements qui fonctionnent en réponse à l'événement. (Pour en savoir plus sur l'agrégation de l'événement, voir article de Shawn Wildermuth, « Composite Web Apps avec prisme, » msdn.microsoft.com/magazine/dd943055.)

Par exemple, l'événement qui représente un élément d'alimentation étant ajouté à la liste des courses le ressemble à ce qui est montré dans Figure 9.

La figure 9 élément événement ajouté

// Published when a grocery item is added to a shopping list
[DataContract]
public class ItemAddedEvent : IEvent
{
  public ItemAddedEvent()
  {
  }
  [DataMember]
  public Guid Id
  {
    get;
    set;
  }
  [DataMember]
  public string Name
  {
    get;
    set;
  }
}

La classe ItemAddedEvent contient des informations sur l'événement : dans ce cas, le nom de l'élément de l'épicerie qui a été ajoutée et un ID qui a utilisé pour représenter uniquement l'élément épicerie dans un shopping liste. Événements sont également marqués avec [DataContract], qui le rend plus facile pour eux d'être sérialisée sur disque ou envoyés sur le réseau.

Cet événement est créé et publié lorsque l'utilisateur clique sur le bouton Ajouter à la AddGroceryItemView, comme le montre Figure 10.

La figure 10, édition de l'événement

public class AddGroceryItemViewModel : NavigatableViewModel
{
  private readonly IEventAggregator _eventAggregator;
  [...]
  // Adds an item to the shopping list
  private void Add()
  {
    var e = new ItemAddedEvent();
    e.Id = Guid.NewGuid();
    e.Name = Name;
    _eventAggregator.Publish(e);
    NotificationText = String.Format("{0} was added to the shopping list.", Name);
    Name = string.Empty;
  }
}

Notez que cette méthode n'est pas directement apporter des modifications à la liste des courses ; Il publie simplement la ItemAddedEvent de l'agrégateur de l'événement. C'est la responsabilité de l'un des gestionnaires d'événements à l'écoute de cet événement pour faire quelque chose avec elle. Dans ce cas, une classe appelée ShoppingList est abonnée à et gère l'événement, comme le montre Figure 11.

Figure 11 la classe ShoppingList

public class ShoppingList : IEventHandler<ItemAddedEvent>                                        
{
  public ShoppingList(IEventAggregator eventAggregator)
  {
    Requires.NotNull(eventAggregator, "eventAggregator");
    _eventAggregator = eventAggregator;
    _eventAggregator.Subscribe<ItemAddedEvent>(this);
  }
  [...]
  public ReadOnlyObservableCollection<GroceryItem> GroceryItems
  {
    get { return _groceryItems; }
  }
  public void Handle(ItemAddedEvent e)
  {
    var item = new GroceryItem();
    item.Id = e.Id;
    item.Name = e.Name;
    item.IsInCart = false;
    _groceryItems.Add(item);
  }
}
}

Chaque fois que ItemAddedEvent est publiée, ShoppingList crée un nouveau GroceryItem en utilisant les données de l'événement et l'ajoute à la liste des courses. Le ShoppingListView, qui est indirectement lié à la même liste par le biais de son ShoppingListViewModel, est également mis à jour. Cela signifie que lorsque l'utilisateur navigue vers la page liste des achats, les articles, qu'il vient d'être ajouté à la liste sont affichées comme prévu. Le processus de suppression d'un élément de la liste des courses, y ajouter un élément à un panier et vérifier le panier sont que toutes traitées en utilisant le même modèle de publication/abonnement événement.

Il peut d'abord sembler comme beaucoup d'indirection pour quelque chose d'aussi simple que l'ajout d'éléments à une liste d'épicerie : la méthode AddGroceryItemViewModel.Add publie un événement à la IEventAggregator, qui passe sur la ShoppingList, qui ajoute à la liste d'épicerie. Pourquoi ne la méthode AddGroceryItemViewModel.Add simplement contourner l'IEventAggregator et ajoutez le nouveau GroceryItem directement à la ShoppingList ? Je suis heureux que vous avez demandé. L'avantage de traiter toutes les modifications de l'État du système comme des événements, c'est qu'il encourage toutes les parties individuelles de l'application à être très faiblement couplés. Parce que l'éditeur et les abonnés ne sais pas sur l'autre, insertion d'une nouvelle fonctionnalité dans le pipeline, telles que la synchronisation de données depuis et vers les nuages, est beaucoup plus simple.

La synchronisation des données pour le Cloud

J'ai couvert les fonctionnalités de base de l'application exécutée sur un périphérique unique, mais il n'y a toujours le problème de l'obtention des modifications utilisateur apporte à la liste d'autres périphériques, et vice versa. C'est là qu'intervient le Bus de Service Windows Azure AppFabric.

Windows Azure AppFabric Service Bus est une fonctionnalité qui permet aux applications et aux services de facilement parler avec eux sur l'Internet, en évitant les complexités de la navigation dans les obstacles de communication tels que les pare-feu et les périphériques de traduction d'adresses réseau (NAT). Elle fournit des points de terminaison reste et de HTTP de Windows Communication Foundation (WCF) hébergés par Windows Azure et se situe entre l'éditeur et l'abonné.

Il existe trois principales façons de communiquer à l'aide de Windows Azure AppFabric Service Bus ; aux fins de mon application, cependant, je juste couvrirai sujets. Pour un aperçu complet, consultez « Une Introduction à la Windows d'azur AppFabric Service Bus » à bit.ly/uNVaXG.

Pour les éditeurs, une rubrique Service d'autobus s'apparente à une file d'attente de gros dans le nuage (voir Figure 12). Complètement ignorant qui est à l'écoute, éditeurs poussent des messages au sujet, où ils sont détenus à l'infini jusqu'à demandées par un abonné. Pour obtenir des messages de la file d'attente, les abonnés tirent un abonnement, qui filtre les messages publiés sur le sujet. Abonnements agissent comme une file d'attente particulière, et messages supprimés d'un abonnement encore verra d'autres abonnements si incluent leurs propres filtres.

Service Bus Topic
La figure 12 Service Bus sujet

Dans sur Your Way Home, la classe AzureServiceEventHandler est le pont entre l'application et le Bus de Service. Similaire à ShoppingList, elle implémente également IEventHandler <T>, mais au lieu d'événements spécifiques, AzureServiceEventHandlers peut gérer tous, comme le montre Figure 13.

The AzureServiceEventHandler Class
Figure 13 la classe AzureServiceEventHandler

public class AzureServiceBusEventHandler : DisposableObject, IEventHandler<IEvent>, IStartupService
{
  private readonly IAzureServiceBus _serviceBus;
  private readonly IAzureEventSerializer _eventSerializer;
  public AzureServiceBusEventHandler(IEventAggregator eventAggregator,
    IAzureServiceBus serviceBus, IAzureEventSerializer eventSerializer)
  {
    _eventAggregator = eventAggregator;
    _eventAggregator.SubscribeAll(this);
    _serviceBus = serviceBus;
    _serviceBus.MessageReceived += OnMessageReceived;
    _eventSerializer = eventSerializer;
  }
  [...]
  public void Handle(IEvent e)
  {
    BrokeredMessage message = _eventSerializer.Serialize(e);
    _serviceBus.Send(message);
  }
}

Chaque modification de qu'un utilisateur permet à l'état de la liste des courses est gérée par AzureServiceBusEventHandler et a poussé directement sur le nuage. AddGroceryItemViewModel, qui publie l'événement, ni ShoppingList, qui gère le périphérique local, est conscient que cela n'arrive.

Le voyage retour du nuage est où une architecture basé sur un événement vraiment rentable. Lorsque le AzureServiceEventHandler détecte qu'un nouveau message a été reçu sur le Bus de Service (par l'intermédiaire de l'événement IAzureServiceBus.MessageReceived C#), c'est l'inverse de ce qu'elle fait plus tôt et désérialise le message reçu dans un événement. A partir de là, il obtient publié via l'agrégateur de l'événement, dont peuvent être traités comme si l'événement venait dans l'application, comme le montre Figure 14.

La figure 14 désérialisation d'un Message reçu

public class AzureServiceBusEventHandler : DisposableObject, IEventHandler<IEvent>,
  IStartupService
{
  private readonly IAzureServiceBus _serviceBus;
  private readonly IAzureEventSerializer _eventSerializer;
  [...]
  private void OnMessageReceived(object sender, MessageReceivedEventArgs args)
  {
    IEvent e = _eventSerializer.Deserialize(args.Message);
    _eventAggregator.Publish(e);
  }
}

Le ShoppingList n'est pas au courant (ni est elle soins) sur la source de l'événement et les poignées de ceux provenant du Service Bus/nuage comme s'ils venaient directement de l'utilisateur de l'entrée. Il met à jour sa liste d'épicerie, qui à son tour provoque aucun des points de vue liés à cette liste mise à jour de plus.

Si vous payez une attention particulière, vous remarquerez un petit problème avec le flux de travail : Les événements qui s'envoyés le nuage du dispositif local de reviennent à ce même dispositif et provoquent la duplication des données. Pire encore, des changements aux autres, sans rapport avec les listes shopping viendra également sur ce périphérique. Je ne sais pas vous, mais je suis sûr que je ne veux pas voir des choix alimentaires autres personnes figurant sur la liste de mes achat. Pour éviter cela, une rubrique Service d'autobus est créée par la liste et un abonnement par le dispositif, qui écoute sur le sujet. Lorsque les messages sont publiés au sujet de l'appareil, une propriété contenant l'ID de périphérique est envoyée avec les messages, le filtre d'abonnement utilise pour exclure les messages provenant de son propre appareil. Figure 15 montre ce flux de travail.

Device-to-Device Workflow
Workflow d'appareil à appareil figure 15

Récapitulation

J'ai couvert beaucoup dans cet article : Les bibliothèques de classes portable simplifié ma solution et réduit de façon significative la quantité de code que j'avais besoin d'écrire cibler les deux plates-formes. Aussi, changer l'état de l'application via les événements rend très facile de synchroniser cet État avec le nuage. Il y a encore beaucoup que j'ai gauche non-dit, cependant, que vous devrez tenir compte lors du développement d'un client en continu. Je ne parle d'événement hors connexion mise en cache et faute de la tolérance (si le réseau pas disponible lorsque je publie un événement?), les conflits de fusion (si un autre utilisateur apporte une modification qui entre en conflit avec mine?), lecture (si j'attache un nouveau périphérique à la liste des courses, comment il mis à obtenir jour?), (comment empêcher des utilisateurs non autorisés, accès aux données qu'ils ne devraient pas?) de contrôle d'accès et enfin, persistance. Dans l'exemple de code pour cet article, l'application n'est pas enregistrer la liste des courses entre lance. Je vous laisse cela comme un exercice pour vous ; Il pourrait être un défi intéressant si vous voulez jouer avec du code. Un naïf (ou plutôt la traditionnelle) moyen de persistance de l'approche pourrait être pour un mettre un crochet directement dans la classe ShoppingList, marquer les objets GroceryItem comme sérialisable et enregistrer dans un fichier. Avant d'aller dans cette voie, cependant, arrêter et y réfléchir : Étant donné que le ShoppingList gère déjà les événements en mode natif et déjà fout d'où ils viennent, la synchronisation des données depuis et vers le nuage ressemble étonnamment sauver et restaurer les données du disque, il n'est pas ?

David Kean est un développeur sur le.L'équipe NET Framework de Microsoft, où il travaille dans l'équipe de la bibliothèque de classe de Base (BCL). Auparavant, il a travaillé sur l'outil souvent réputé mais également grandement incompris FxCop et ses frères et soeurs connexes, analyse de Code de Visual Studio. À l'origine de Melbourne, en Australie, il est maintenant basé à Seattle, Wash., avec sa femme, Lucy et ses trois enfants, Sarah, Jack et Ben. Il peut trouver les blogs sur davesbox.com.

Je remercie les experts techniques suivants d'avoir relu cet article : Nicholas Blumhardt et Immo Landwerth