Tuesday, October 29, 2013

C#.net - Lazy Loading in C#.net

In this article i will show you how to use Lazy loading in C#.net.

What is Lazy Loading???
Lazy loading is a concept or design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used. The opposite of lazy loading is eager loading.
In short i can say that,Load object on Demand.

Let take a simple program. 
Suppose we have Customer and Order entity class.Assume that a single customer can have more than orders.If we want show orders for single customer then we need to load orders associate with Customer.Loading of orders can make performance hit badly if data is huge when customer object is initialized first time.

For avoiding the situation we can use Lazy Loading.Load the order object on demand whenever the Order object used in program.This is will make faster loading customer object and give the better performance of application.

This is a new feature of C# 4.0 its can be used when we are working with large objects when its not in use. This article will explain you about Lazy<T> class.

Theory part done now let see practical oriented program.

Step 1
Create a Console application give the solution name as SolLazyLoading.

Step 2
First a Create Order Entity class,it is look like this 
  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SolLazyLoading
{
    public class Order
    {
        public int OrderNo
        {
            get;
            set;
        }
    }
}

Step 3
Create a Customer class,it is look like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SolLazyLoading
{
    public class Customer
    {
        #region Field 
        // 1.Step. Initialized Lazy Loading Orders
        private Lazy<List<Order>> _GetOrders;

        #endregion

        #region Constructor

        public Customer()
        {
            this.CustomerName = "Yogesh Naik";

            // 3 Step. Create a Instance of Lazy List Order and Pass GetOrderData function as Parameter to get Order List.
            _GetOrders = new Lazy<List<Order>>(() => GetOrderData());

            // or you write like this // it's not a best practice
            //_GetOrders = new Lazy<List<Order>>(() => {
            //    List<Order> OrderList = new List<Order>();
            //    OrderList.Add(new Order() { OrderNo = 1 });
            //    OrderList.Add(new Order() { OrderNo = 4 });
            //    OrderList.Add(new Order() { OrderNo = 10 });
            //    return OrderList;
            //});
        }

        #endregion

        #region Property

        public String CustomerName
        {
            get;
            set;
        }

        public List<Order> GetOrders
        {
            get
            {
                // 2 Step. Get a Lazy Initialized value
                return _GetOrders.Value; 
            }
           
        }

        #endregion

        #region Private Method
        /// <summary>
        /// Get Order Data 
        /// </summary>
        /// <returns>List</returns>
        private List<Order> GetOrderData()
        {
            try
            {
                // Set Orders Data
                List<Order> OrderList = new List<Order>();
                OrderList.Add(new Order() { OrderNo = 1 });
                OrderList.Add(new Order() { OrderNo = 4 });
                OrderList.Add(new Order() { OrderNo = 10 });

                return OrderList;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message); 
            }
        }

        #endregion
    }
}

In the constructor of customer class, properties are initializing and declaring Lazy List object, which is generic List of orders and filled by GetOrderData method. This method will only call when lazy list object will be use.

Step 4
The following main method show behavior of Lazy Loading,it is look like this 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SolLazyLoading
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a Instance of Customer Object.
            Customer CustObj = new Customer();

            // Customer Name should be load but not a load Order Object here when Customer constructor called.
            System.Console.WriteLine("Customer Name : {0}",CustObj.CustomerName);

            foreach (Order OrderObj in CustObj.GetOrders) // here load a Order Object whenever it is used. i.e That is Lazy Loading.
            {
                System.Console.WriteLine("Order No : {0}", OrderObj.OrderNo);
            }
        }
    }
}

Now lets a put a Debug point where created instance of customer class, it is like like this



Click on Image for better view

Press F5 to run program on debug mode,Press F10 and now look at local window that still getorders object not load.Now Press F10 again,look at local window now.



Click on Image for better view

Here GetOrder object load whenever it is used.

So i hope you understand the concept of Lazy Loading(Load Object on Demand).

Run the Project.

Download
Download Source Code

Wednesday, October 16, 2013

WPF - Attached Property in WPF

An attached property is a concept defined by XAML. An attached property is intended to be used as a type of global property that is settable on any object. In Windows Presentation Foundation (WPF), attached properties are typically defined as a specialized form of dependency property that does not have the conventional property "wrapper".

Why and When we create an Attached Property??? Big Question....

One purpose of an attached property is to allow different child elements to specify unique values for a property that is actually defined in a parent element. A specific application of this scenario is having child elements inform the parent element of how they are to be presented in the user interface (UI).

You might create an attached property when there is a reason to have a property setting mechanism available for classes other than the defining class.

An Attached Behavior is simply an Attached Property.Using attached behaviors, you can bundle up a piece of event-handling logic in a small, specific, reusable package which you can then apply to controls using XAML even we can use attached Property in Style.

Lets take a simple example,suppose i want to create a textbox that allow to user to enter digit only. In traditionally way we use Textbox PreviewTextInput event to block non digit value.

Let see how can we achieve this task.

Step 1
Create a WPF Application and give the solution name as SolAttachedBehavior.

Step 2
Add a Textbox control in window,it is look like this

<Grid>
<TextBox x:Name="txtUser" Height="23" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" PreviewTextInput="txtUser_PreviewTextInput"></TextBox>
</Grid>

Step 3
Now write the following Non digit blocking logic to Textbox PreviewTextInput Event,it is look like this
private void txtUser_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            try
            {
                if (!Char.IsDigit(e.Text.FirstOrDefault<char>()))
                {
                    e.Handled = true;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

This approach works fine if we have one textbox but what about when we have multiple textboxes for blocking non digit value.it is not reusable code then what is the solution??? The solution is to make a reusable code with Attached Property.

Step 4
Remove TextBox PreviewTextInput event from XAML and Comment PreviewTextInput event code in Code Behind.
Now we will create Attached Property for TextBox which block Non digit value.it is look like this.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace SolAttachedBehavior
{
    public static class TextBoxBehavior
    {

        #region Dependency Property

        // Boolean Attache Proeprty with Getter and Setter 
        public static readonly DependencyProperty IsDigitInputProperty =
            DependencyProperty.RegisterAttached("IsDigitInput", typeof(Boolean), typeof(TextBoxBehavior), 
            new UIPropertyMetadata(false, TextBox_IsDigitInput));

        #endregion

        #region Get and Set Accessor Static Methods of IsDigitInput Property

        public static Boolean GetIsDigitInput(DependencyObject DObj)
        {
            return (Boolean)DObj.GetValue(IsDigitInputProperty);
        }

        public static void SetIsDigitInput(DependencyObject Dobj, Boolean Value)
        {
            Dobj.SetValue(IsDigitInputProperty, Value);
        }

        #endregion

        #region Event of Attached property

        public static void TextBox_IsDigitInput(Object sender, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                TextBox txtInput = (TextBox)sender;

                if (txtInput != null)
                {
                    Boolean IsDigitInputValue = (Boolean)e.NewValue;

                    if (IsDigitInputValue)
                    {
                        // Wire Up TextBox_PreviewTextInput Event to Execute IsDigit Logic
                        txtInput.PreviewTextInput += (s, tc) => {

                            if (!char.IsDigit(tc.Text.FirstOrDefault<char>()))
                            {
                                tc.Handled = true;
                                return; // Stop Event if Condition true
                            }
                               
                            
                        };
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message); 
            }
        }
        
        #endregion



       
    }
}

An attached behavior in WPF is normally a static class with one or more attached properties. The trick in this class is to listen to the change event of one of the properties, and to act upon it.

Step 5
Mapping TextBoxBehavior class in window XAML,it is look like this
xmlns:Behavior="clr-namespace:SolAttachedBehavior"

Finally it is look like on window tag
<Window x:Class="SolAttachedBehavior.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Behavior="clr-namespace:SolAttachedBehavior"
        Title="MainWindow" Height="350" Width="525">

<Window>

Step 6
Apply Attached Property to textBox,it is look like this
<Grid>
<TextBox x:Name="txtUser" Height="23" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Behavior:TextBoxBehavior.IsDigitInput="True"></TextBox>
</Grid>

Step 7
using attached property in style,it is look like this
<Window.Resources>
        <Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
            <Setter Property="Behavior:TextBoxBehavior.IsDigitInput" Value="True">   </Setter>
        </Style>
 </Window.Resources>
 

<TextBox x:Name="txtUserStyle" Height="23" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyle}" Margin="15,10"></TextBox>

Full XAML Code
<Window x:Class="SolAttachedBehavior.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Behavior="clr-namespace:SolAttachedBehavior"
        Title="MainWindow" Height="350" Width="525">
    
    <Window.Resources>
        <Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
            <Setter Property="Behavior:TextBoxBehavior.IsDigitInput" Value="True"></Setter>
        </Style>
    </Window.Resources>
    
    <Grid>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox x:Name="txtUser" Height="23" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Behavior:TextBoxBehavior.IsDigitInput="True"></TextBox>
            <TextBox x:Name="txtUserStyle" Height="23" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyle}" Margin="15,10"></TextBox>
        </StackPanel>
    </Grid>
</Window>



Output

Click on Image for Better View

Download
Download Source Code