Jeg har fik et spørgsmål fra Morten Schmidt omkring deling af domæne klasser mellem serveren og Silverlight klienten. Jeg tror at det er et spørgsmål som mange Silverlight udviklere sidder med, så lad os kigge lidt nærmere på hvordan det kan gøres.
Simpelt kodeeksempel
Først skal vi have oprettet en solution og lidt projekter; jeg har startet med at lave en Silverlight applikation og en webapplikation til at hoste den. Silverlight klienten kalder jeg (meget opfindsomt) MyClientApplication og webapplikationen kalder jeg MyHostWebApplication. Dernæst tilføjer jeg et almindeligt klassebibliotek til solutionen kaldet ServerModel samt et Silverlight klassebibliotek kaldet ClientModel.
Nu skal vores domæne klasser tilføjes til løsningen. I ServerModel tilføjer jeg klassen Customer og tilføjer de nødvendige properties.
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Runtime.Serialization;
6:7: namespace ServerModel
8: {9: [DataContractAttribute(Name = "Customer")]
10: public class Customer11: {12: [DataMember]13: public Guid Id { get; set; }14: [DataMember]15: public string FirstName { get; set; }16: [DataMember]17: public string LastName { get; set; }18: [DataMember]19: public string FullName { get { return FirstName + " " + LastName; } set { } }20:21: #if !SILVERLIGHT
22: [DataMember]23: public string Address { get; set; }24: #endif25: }26: }27:
Bemærk at jeg har kun ønsker propertien Address med såfremt vi ikke er i et Silverlight projekt.
Nu kommer det store trick! Det vi egentlig ønsker, er jo at have den samme klasse i vores ClientModel projekt – så det er bare det vi gør. Jeg højreklikker på projektet og vælger Add –> Existing Item og finder Customer.cs filen. I stedet for at vælge Add vælger jeg Add As Link.
Det betyder egentlig, at i stedet for at tilføje filen, bliver der tilføjet et link til filen. Det betyder også, at bliver der lavet en opdatering i det ene projekt, slår det automatisk igennem på det andet projekt.
Når vi bruger klassen i vores ServerModel, bliver properties Address inkluderet, men når vi bruger den i vores ClientModel, bliver den udeladt – ganske fikst!
Lad mig prøve at bruge vores klasse; jeg opretter en service i vores webapplikation, der returner en udfyldt instans af vores Customer klasse. I clientapplikationen tilføjer jeg en reference til vores ClientModel projekt og laver en ServiceReference til vores service i webapplikationen.
I codebehind på vores XAML fil tilføjer jeg et kald til vores service metode, hvor jeg henter den instantierede kunde og sætter DataContext på siden.
CS-filen:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Net;
5: using System.Windows;
6: using System.Windows.Controls;
7: using System.Windows.Documents;
8: using System.Windows.Input;
9: using System.Windows.Media;
10: using System.Windows.Media.Animation;
11: using System.Windows.Shapes;
12: using ServerModel;
13: using MyClientApplication.ServiceReference1;
14:15: namespace MyClientApplication
16: {17: public partial class MainPage : UserControl18: {19: public MainPage()
20: {21: InitializeComponent();22:23: MyServiceClient client = new MyServiceClient();
24: client.RetrieveCustomerCompleted += (se, ea) =>25: {26: ServerModel.Customer c = ea.Result;27: //c.Address <-- here you can see that the address property is not available
28: LayoutRoot.DataContext = c;29: };30: client.RetrieveCustomerAsync();31: }32: }33: }34:
XAML filen:
1: <StackPanel2: x:Name="LayoutRoot">3: <TextBlock4: Text="{Binding Id}" />5: <TextBlock6: Text="{Binding FullName}" />7: <TextBlock8: Text="{Binding Address}" />9: </StackPanel>10:
Kører jeg webapplikationen nu, vil jeg få vist Id og FullName. Jeg vil ikke få vist Address, da den ikke er en del af den kompilerede klasse til Silverlight.
Den fulde kildekode til eksemplet finder du på mit skydrive.
Det er en meget forenklet udgave af, hvordan vi normalt opbygger den grundlæggende arkitektur i vores Silverlight projekter. Oftes vil vores services også være adskilt i seperate projekter og der vil være repositories der håndterer adgangen til vores services fra henholds klient og server.
I mange tilfælde vil det kunne betale sig, at tage mere eller mindre, udgangspunkt i et eksisterende framework. Der findes flere frameworks, der gør meget af det grundlæggende arkitektarbejde for os – herunder .NET RIA Services.
.NET RIA Services
Nikhil har skrevet en meget sjov post, der kort fortæller om, hvad .NET RIA Services er, og hvorfor man som udvikler bør anvende det (eller et lignende framework).
http://www.nikhilk.net/NET-RIA-Services-Twitter-Pitch.aspx
Gruppe på LinkedIn
For netop at få diskuteret nogle af de problemstillinger, der kan være i forbindelse med Silverlight udviklinger, er der en gruppe på LinkedIn til netop det. Formålet med gruppen er at mødes 5-6 gange årligt, diskutere problemstillinger og ellers få udvekslet lidt erfaringer.
http://www.linkedin.com/groups?about=&gid=2085262&trk=anet_ug_grppro
Happy Coding!
Thomas Castøe Martinsen