Following situation:
I have a BusinessObject called Person which i want to use in a Silverlight project. This Buisnessobject should be returned from a WCF service and should have some functionality on it. Now, if i define this object on the WCF service, i can use it only as
DTO, but i cannot add additional functionality on it(Or at least i am unable to use it in a silverlight application).
Now, i'm showing a way how you can get all this requirements done.
1. Create a new silverlight project
Just create a Silverlight 3.0 project.

Im using the visual studio built in webserver for providing the xap file as well as for the WCF service.
2. Create the business object and the wcf service
Now, just add a
Silverlight enabled webservice to the web project.

In this newly added service1.cs, i add a new method GetPerson and a new class Person which will be my Businessobject/Datatransverobject for this sample. I have put the Person class into the same file.
[ServiceContract
(Namespace = "")] [AspNetCompatibilityRequirements
(RequirementsMode
= AspNetCompatibilityRequirementsMode.
Allowed)] public class Service1
{ [OperationContract
] public Person GetPerson
() { return new Person
() {FirstName
= "manuel", LastName
= "kaderli", Salutation
= "Dear Mr. "}; } } [DataContract
] public class Person
{ [DataMember
] public string FirstName
{ get
; set
; } [DataMember
] public string LastName
{ get
; set
; } [DataMember
] public string Salutation
{ get
; set
; } }
This service is ready to use, and i now add a service reference on the silverlight project.
3. Use the service from silverlight
On the xaml page, i add a button and some TextBlocks. I'm using the Binding mechanism for get/set data to the controls.
<UserControl x:Class="SilverlightBusinessObject.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" Width="640" >
<Grid x:Name="LayoutRoot">
<StackPanel>
<Button x:Name="btnGetPerson" Content="GetPerson" Click="btnGetPerson_Click"></Button>
<TextBlock x:Name="txtFirstName" Text="{Binding FirstName, Mode=TwoWay}"></TextBlock>
<TextBlock x:Name="txtLastName" Text="{Binding LastName, Mode=TwoWay}"></TextBlock>
<TextBlock x:Name="txtSalutation" Text="{Binding Salutation, Mode=TwoWay}"></TextBlock>
</StackPanel>
</Grid>
</UserControl>
The csharp file does only call the service, and bind the person object to the LayoutRoot.
public partial class MainPage
: UserControl
{ public MainPage
() { InitializeComponent
(); } private void btnGetPerson_Click
(object sender, RoutedEventArgs e
) { Service1Client sc
= new Service1Client
(); sc.
GetPersonCompleted += new EventHandler
<GetPersonCompletedEventArgs
>(sc_GetPersonCompleted
); sc.
GetPersonAsync(); } void sc_GetPersonCompleted
(object sender, GetPersonCompletedEventArgs e
) { Person person
= e.
Result; LayoutRoot.
DataContext = person
; } }
When i now run this application, and after pressing the button it shows me the values of the three properties which are bound to the xaml.
4. Addin functionality to the person BusinessObject
I want to add a new control to the page, which should display the full letter salutation, in my sample this would be "Dear Mr. Kaderli Manuel". Of course i could do this right on the silverlight page. But this functionality belongs to the BusinessObject. Since the person object is sent via wcf, there is no possibility of code sharing. And i don't want to edit any generated proxy files.
What i now want to is to share the person BusinessObject between the web/wcf server and the silverlight application. But because they don't use the same .net framework(web/wcf uses .net 3.5 and the silverlight application obviously the silverlight framework) which are incompatible.
First i add a new project of type
Silverlight Class Library to my solution.

Then i move the Person class which is in the .svc service file into a seperate class in the newly created class library project. Now i can add the method GetLetterSalutatioin to this class.
Make sure to include
System.Runtime.Serialization with the using statement.
using System.Runtime.Serialization;
namespace BusinessDTO
{
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string Salutation { get; set; }
public string LetterSalutation
{
get
{
return string.Format("{0} {1} {2}", Salutation, LastName, FirstName);
}
}
public void DoSomethiing()
{
//add any other businesslogic here
}
}
}
Since i have remove this code from the web/wcf project there are now some errors, because tihs class is missing. I just add this Person class as link.
Just select
add existing item, select the Person class from the silverlight class library project, and make sure to use
add as link.
In the .svc file, i just have to add the new namespace:
using BusinessDTO;
In the silverlight project, it's even easier. Just add the BusinessObject project as a project reference.
Make sure to renew the service reverence on the silverlight application, in order to get the latest proxy. I had first to delete the existing service reference, and the to add it again to get it working.
Now, i'm able to write the following in the silverlight client:
BusinessDTO.Person person = e.Result;
string letterSalutatioin = person.LetterSalutation;
person.DoSomethiing();
Now i have clientside a object wihch comes from a wcf service but which also can have business functionality.
It is also possible to use the new property LetterSalutation as source for a control.
<TextBlock x:Name="txtLetterSalutation" Text="{Binding LetterSalutation, Mode=OneWay}"></TextBlock>
5. Use specific functionality client or serverside
Because i use the code from a silverlight class library now in a silverlight project as well as in a .net 3.5 project, there may be some problems.
E.g. some functionality like ObservableCollection are not in the same assmbly in the .net 3.5 framework and in the silverlight framework. Then you might have situations where you like to have code for either client or serverside.
For this you can use
#if SILVERLIGHT statement in the BusinessObjects classes.
#if SILVERLIGHT
//code available only for silverlight applicatioins
#else
//code available for web/wcf service
#endif
You can get the whole solution
right here.
Now, this is the way i'm working with BusinessObjects and silverlight/wcf. If one has a remark, or an other solution, please leave a commen.
cheers