Saturday, March 9, 2013

Reactive Extension with Silverlight


What is RE?
Reactive extension is a framework that support to the asynchronous and event programming using Observable collection.
Before start you need to download and install reactive extension framework to your computer. You can download installation using following URL.
What we are going to do?
In Silverlight when we are calling to WCF method which is in the server side we should call it as asynchronous. Normally we cannot call this WCF method as normal method. First we should have to register method Completed Event and then we should call to the WFC method asynchronously. Then inside the Method completed method we can read the WCF method return values as following example.

        private void GetEmployeesU()
        {
            client.GetEmployeesCompleted += client_GetEmployeesCompleted;
            client.GetEmployeesAsync();
        }

        void client_GetEmployeesCompleted(object sender, GetEmployeesCompletedEventArgs e)
        {
            List<Employee> employees = e.Result;
           
        }
But thing is we cannot use this as normal method call in C#.  But using RE (Reactive Extension) we can perform this task as bellow example.
Now Create a new Silverlight project called ExDemo and add the following reference to the Silverlight project.
·         System.Reactive.Core
·         System.Reactive.Interface
·         System.Reactive.Linq
·         System.Reactive.Providers
·         System.Reactive.Windows.Threading
To the web project add the Silverlight enable WCF file called ReDemoService and implement the following method on that service class.
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ReDemoService
    {
        [OperationContract]
        public List<Employee> GetEmployees()
        {
            var employees = new List<Employee>
            {
                new Employee(){ID=1,Name="Niluka Dilani",Email="abc@hotmail.com"},
                new Employee(){ID=2,Name="Chathura Achini",Email="cde@hotmail.com"},
                new Employee(){ID=3,Name="Florina Breban",Email="fgh@hotmail.com"}
            };

            return employees;
        }
    }

    [DataContract]
    public class Employee
    {
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Email { get; set; }
    }
Add WCF service reference to the Silverlight project and name it as ReDemoService and in service reference setting set the Collection type as Generic List and build the Silverlight project.
Add new class called ServiceManager into the Silverlight project and implement that class as bellow.
    public class ServiceManager
    {
        private ReDemoServiceClient client;

        public ServiceManager()
        {
            client = new ReDemoServiceClient();
        }
        public IObservable<List<Employee>> GetEmployees()
        {
            var employees = from completed in Observable.Create<GetEmployeesCompletedEventArgs>(observer=>
                {
                    var subcription = Observable.FromEventPattern<GetEmployeesCompletedEventArgs>(client, "GetEmployeesCompleted")
                        .Take(1)
                        .Select(e => e.EventArgs)
                        .Subscribe(x =>
                            {
                                if (x.Error != null)
                                {
                                    observer.OnError(x.Error);
                                    return;
                                }
                                observer.OnNext(x);
                            }
                            , observer.OnError, observer.OnCompleted);
                    client.GetEmployeesAsync();
                    return subcription;
                })
                            select completed.Result; ;
            return employees.ObserveOnDispatcher();
        }
    }
Here what we do is using reactive extensions we call our WCF method called GetEmployees and this method will return the IObservable Employee list. Here this method we can consider as normal C# method call.
Now go to the your MainPage.xmal file and design your UI as bellow.
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="REDemo.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:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Width="200" Height="26" Content="Load Employee" Click="Button_Click"/>
        <sdk:DataGrid x:Name="dgvEmployee" AutoGenerateColumns="False" Grid.Row="1">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Binding="{Binding ID}" Header="ID" Width="60"/>
                <sdk:DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="200"/>
                <sdk:DataGridTextColumn Binding="{Binding Email}" Header="Email" Width="200"/>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
    </Grid>
</UserControl>
Inside the Button_Click event implement the following code lines.
    public partial class MainPage : UserControl
    {
        private ServiceManager service;
        public MainPage()
        {
            InitializeComponent();
            service = new ServiceManager();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var result = service.GetEmployees();
            result.Subscribe(x =>
                {
                    dgvEmployee.ItemsSource = x;
                },
                er =>
                {
                },
                    () =>
                    {
                    });
        }
    }
Here in inside the Button_Click event what is happening is , first we call the GetEmployees methods which is implemented in the ServiceManager Class and it will return the IObservable Employee List .Here we will be assigned the return value as result. Since result type is IObservable, we need to call to subscribe method to read .Actually here result which +is belongs to IObservable type will act as data source and our subscribe method will subscribe the Employee object list. 

No comments: