Saturday, November 21, 2009

Reactive Extensions - Much simpler asynchronous and event based programming


Reactive Extensions helps developers write asynchronous and event based operations in a much simpler way. The user must specify a SynchronizationContext to which the Rx messages are sent. For e.g: If you are using a console app, you should specify the Context as
Observable.Context = SynchronizationContexts.ReactiveEventLoop
For WPF applications your Context will be
Observable.Context = SynchronizationContexts.CurrentDispatcher;

You can write subscriptions to your control events using Rx like
Observable.FromEvent<RoutedEventArgs>(button1, "Click").Subscribe(x => this.Close());

Or
var __StartTimer = button2.GetClickEvents().Subscribe(x => MessageBox.Show("Starting timer..."));
where GetClickEvents is an extension method on UIElements to track clicks on them
public static IObservable<IEvent<RoutedEventArgs>> GetClickEvents(this UIElement uiElement)
{
     return Observable.FromEvent<RoutedEventArgs>(uiElement, "Click");
}

Friday, November 20, 2009

Reactive Extensions – First Look


Rx is a library for composing asynchronous and event based programs using observable collections. The library revolves around the concept of “Reactive programming”. Reactive programming or reactive programs is not a new concept, we have been using reactive programming before in our applications by registering to an event handler or a call back on an asynchronous operation.
All these operations were performed by specifying delegates or methods that are called at unpredictable times. i.e. the functions were called based on an action or a change in the existing data type or code. But we can also think that these operations are performed when data is passed to them as an item in a sequence. For e.g. a sequence of button click events are passed to the method OnButtonClick(). Every time the function gets an input it performs some operation.
Rx is a superset of the standard LINQ sequence operators that exposes asynchronous and event based computations as push based observable collections via the .NET 4.0 interfaces IObservable and IObserver. These interfaces form the heart of Rx.
IObservable interface represents the class that sends notifications (the provider); the IObserver interface represents the class that receives them (the observer). T represents the class that provides the notification information.
public interface IObservable<out T>
{       
    IDisposable Subscribe(IObserver observer);
}
The provider object implements the IObservable  that has a single method Subscribe, which indicates that an observer wants to receive push-based notifications. Callers to the method pass an instance of the observer.
public interface IObserver<in T>
{       
    void OnCompleted();       
    void OnError(Exception error);       
    void OnNext(T value);
}
The provider sends the following three kinds of notifications to the observer by calling IObserver<(Of <(T>)>) methods:
The current data. The provider can call the IObserver , OnNext method to pass the observer a T object that has current data, changed data, or fresh data.
An error condition. The provider can call the IObserver, OnError method to notify the observer that some error condition has occurred.
No further data. The provider can call the IObserver, OnCompleted method to notify the observer that it has finished sending notifications.

I have created a simple example to demonstrate the usage of IObservable and IObserver interfaces and the observer pattern implementation.
public class Employee
{
    public string Name { get; set; }
    public string Email { get; set; }
    public decimal Bonus { get; set; }
    public DateTime DateOfJoining { get; set; }
}

public class EmployeeSubject : IObservable<Employee>
{
    public EmployeeSubject ()
       {
        ___Employee = new Employee { Name = "Prajeesh", Bonus=90.90M, DateOfJoining= new DateTime(2005, 08, 01), Email = "prajeesh.prathap@gmail.com" };
       }

    public Employee GetEmployee() { return ___Employee; }
   
    public void UpdateEmployee(Employee employee)
    {
        ___Employee.Name = employee.Name;
        ___Employee.Email = employee.Email;
        ___Employee.Bonus = employee.Bonus;
        ___Employee.DateOfJoining = employee.DateOfJoining;
       
        //Notify the observers by pushing the updated employee details.
        ___Observers.ForEach(observer => observer.OnNext(___Employee));           
    }

    public IDisposable Subscribe(IObserver<Employee> observer)
    {
        ___Observers.Add(observer);
        observer.OnNext(___Employee);
        return observer as IDisposable;
    }

    Employee ___Employee;
    List<IObserver<Employee>> ___Observers = new List<IObserver<Employee>>();
}

public class EmployeeObserver : IObserver<Employee>
{
    public void  OnCompleted()
    {
       Console.WriteLine("Subscription completed");
    }

    public void  OnError(Exception error)
    {
       Console.WriteLine("Unexpected error occurred {0}", error.Message);
    }

    public void  OnNext(Employee value)
    {
       Console.WriteLine("Employee Details");
        Console.WriteLine("Name : " + value.Name);
        Console.WriteLine("Date of joining : " + value.DateOfJoining.ToShortDateString());
        Console.WriteLine("Email : " + value.Email);
        Console.WriteLine("Bonus : " + value.Bonus.ToString());
        Console.WriteLine();
    }
}

In the console application, I have the code written as
var __EmployeeSubject = new EmployeeSubject();
var __Observer = new EmployeeObserver();
__EmployeeSubject.Subscribe(__Observer);

var __Employee = __EmployeeSubject.GetEmployee();
__Employee.Bonus = 55.55M;
__EmployeeSubject.UpdateEmployee(__Employee);

Output:
Employee Details
Name : Prajeesh
Date of joining : 8/1/2005
Email : prajeesh.prathap@gmail.com
Bonus : 90.90

Employee Details
Name : Prajeesh
Date of joining : 8/1/2005
Email : prajeesh.prathap@gmail.com
Bonus : 55.55

In the next post, I’ll show some samples using the Rx framework and how it can be used in our applications.

Wednesday, November 11, 2009

Using XamEditors in Infragistics XamDataGrid


Setting the Field’s EditorStyle property to a XamEditor control allows inline editing and updating of properties much easier inside a XamDataGrid. You can choose from a wide range of Editors from Infragisitcs and use it as the EditorStyle.
For editing a currency value in my Grid I have declared the FieldSettings as
<igdp:Field Label="Billed Amount" Name="BilledAmount" Column="1">
    <igdp:Field.Settings>
        <igdp:FieldSettings EditAsType="{x:Type sys:Decimal}">
            <igdp:FieldSettings.EditorStyle>
                <Style TargetType="{x:Type igEditors:XamCurrencyEditor}">
                    <Setter Property="Mask" Value="{}{currency:7.2:c}" />
                Style>
            igdp:FieldSettings.EditorStyle>                                   
        igdp:FieldSettings>
    igdp:Field.Settings>
igdp:Field>
Similarly for editing a value that should be selected from a combo box item collections.
<igdp:UnboundField  Name="ClientType" BindingPath="ClientType.Name" Label="Type" Column="4">
    <igdp:Field.Settings>
        <igdp:FieldSettings EditorType="{x:Type igEditors:XamComboEditor}">
            <igdp:FieldSettings.EditorStyle>
                <Style TargetType="{x:Type igEditors:XamComboEditor}">
                    <Setter Property="DisplayMemberPath" Value="Name" />
                    <Setter Property="ValuePath" Value="Id" />
                    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ClientTypeCollection,
                        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
                    <Setter Property="ValueType" Value="{x:Type entities:SampleClientType}" />
                    <Setter Property="IsAlwaysInEditMode" Value="False" />
                    <Setter Property="IsEditable" Value="False" />
                    <Setter Property="DropDownButtonDisplayMode" Value="OnlyInEditMode" />
                Style>
            igdp:FieldSettings.EditorStyle>
        igdp:FieldSettings>
    igdp:Field.Settings>
igdp:UnboundField>
Output screens











Thursday, November 5, 2009

Fluent Validation - WPF implementation


Working with FluentValidation makes my validation code cleaner and easier to integrate with the main application. I started removing my Enterprise library validation attributes and created Validators for my entities. The next major step was to integrate it with WPF. I have mentioned in one of my earlier posts on how to achieve this by implementing IDataErrorInfo on the business entities. Well, I had to follow the same approach for the FluentValidation classes also.
Here’s some sample code on the POC.
My BaseEntity class remains almost same, but with less code and looks clean
[Serializable]
public abstract class BaseEntity : INotifyPropertyChanged, IDataErrorInfo
{
    public T Id { get; set; }
    public Guid CreatedBy { get; set; }
    public Guid ChangedBy { get; set; }
    public DateTime CreatedDtTm { get; set; }
    public DateTime ChangedDtTm { get; set; }
    public Byte[] Version { get; set; }

    public void RaisePropertyChanged(params string[] propertyName)
    {
        propertyName.ToList().ForEach(x =>
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(x));
        });
    }

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    public abstract ValidationResult SelfValidate();

    public bool IsValid
    {
        get { return SelfValidate().IsValid; }
    }

    public string Error
    {
        get { return ValidationHelper.GetError(SelfValidate()); }
    }

    public string this[string columnName]
    {
        get
        {
            var __ValidationResults = SelfValidate();
            if (__ValidationResults == null) return string.Empty;
            var __ColumnResults = __ValidationResults.Errors.FirstOrDefault<ValidationFailure>(x => string.Compare(x.PropertyName, columnName, true) == 0);
            return __ColumnResults != null ? __ColumnResults.ErrorMessage : string.Empty;
        }
    }
}
My Employee entity type inherits from the BaseEntity
public class Employee : BaseEntity<Guid>
{
    public string Code
    {
        get { return ___Code; }
        set
        {
            if (___Code != value)
            {
                ___Code = value;
                RaisePropertyChanged("Code");
            }
        }
    }

    public string FirstName
    {
        get { return ___FirstName; }
        set
        {
            if (___FirstName != value)
            {
                ___FirstName = value;
                RaisePropertyChanged("FirstName");
            }
        }
    }

    public string Email
    {
        get { return ___Email; }
        set
        {
            if (___Email != value)
            {
                ___Email = value;
                RaisePropertyChanged("Email");
            }
        }
    }
   

    public DateTime DateOfJoining
    {
        get { return ___DateOfJoining; }
        set
        {
            if (___DateOfJoining != value)
            {
                ___DateOfJoining = value;
                RaisePropertyChanged("DateOfJoining");
            }
        }
    }

    public List<EmployeeBenefit> Benefits { get; set; }

    public override ValidationResult SelfValidate()
    {
        return ValidationHelper.Validate<EmployeeValidator, Employee>(this);
    }

    string ___Code;
    string ___FirstName;
    string ___Email;
    DateTime ___DateOfJoining;
}
The validation logic for the Employee entity is available in the EmployeeValidator class
public class EmployeeValidator : AbstractValidator<Employee>
{
    public EmployeeValidator()
    {
        RuleFor<string>(x => x.Code).Length(5, 10)
            .WithMessage("Code" + ValidationConstants.StringLengthValidation + "5 - 10").WithPropertyName("Code");
        RuleFor<string>(x => x.FirstName).Length(1, 25)
            .WithMessage("FirstName" + ValidationConstants.StringLengthValidation + "1 - 25").WithPropertyName("FirstName");       
        RuleFor<string>(x => x.Email).EmailAddress()
            .WithMessage("Email" + ValidationConstants.NotValidValidation).WithPropertyName("Email");
        RuleFor<DateTime>(x => x.DateOfJoining).Must((x, y) => x.DateOfJoining < new DateTime(1900, 1, 1) || x.DateOfJoining > DateTime.Now)
            .WithMessage("Date of joining should be between 01-Jan-1900 and today").WithPropertyName("DateOfJoining");

    }
}
ValidationHelper class has two main methods that returns a string message for the failed validations and a Validator method to validate the entity.
public static ValidationResult Validate(K entity)
    where T : IValidator, new()
    where K : class
{
    IValidator __Validator = new T();
    return __Validator.Validate(entity);
}

public static string GetError(ValidationResult result)
{
    var __ValidationErrors = new StringBuilder();
    foreach (var validationFailure in result.Errors)
    {
        __ValidationErrors.Append(validationFailure.ErrorMessage);
        __ValidationErrors.Append(Environment.NewLine);
    }
    return __ValidationErrors.ToString();
}
Output