November 19, 2010

C# - Delegates Part 2


In the previous part we saw how we can use a simple delegate. In the article I will explain what is a "Mmulticast Delegate" and how we create and use it. Multicast delegates are the combination two or more delegates of same type and they together form a delegate chain. Each participant in the delegate chain should have a void return type.

Let us take an example of an Order processing system that makes use of the Multicast delegate. The example I created has an OrderShipment class and that makes use of Multi-cast delegate. First we will explore the OrderShipment Class and then we will move the client code that makes use of the OrderShipment class and Multicast delegate.

OrderShipment Class

This class breaks the Order processing into a small group of functions that will match the type single delegate, which is eligible for delegate chaining.
Note: You can download the code (If you want) and walk through the code explanation below.

1) In this class first a multicast delegate is declared. Actually, it is normal delegate syntax only. Soon, we are going to use this for the purpose delegate chaining. The delegate accepts Order id and customer id as parameter and returns nothing that is void. Please keep in mind that multicast delegate principle work for void return type only. There is no restriction on the Parameters that it receives. Below is the Delegate declaration:

//001_1: Declare the Multi-cast delegate. Note the return type should be void
public delegate void OrderProcessingMethods(int OrderId, int CustomerId);

2) The function split into five parts is actually used for the Order processing. The split functions that will become part of the delegate chaining are shown below:

 //001_2: Implement the Order Processing Functions
//Processing Function 1
public void GetShoppingCartItems(int OrderId, int CustomerId)
 Console.WriteLine("(1) GetShoppingCartItems");
 Console.WriteLine("All shopping Cart Items are Collected.");
 Console.WriteLine("Formed a Order with supplied Orderid");

//Processing Function 2
public void CalculateOrderPrice(int OrderId, int Customerid)
 Console.WriteLine("(2) CalculateOrderPrice");
 Console.WriteLine("Price of each products collected from the shopping cart summed up");
 Console.WriteLine("Order Price calculated");

//Processing Function 3
public void CalculateDiscount(int OrderId, int Customerid)
 Console.WriteLine("(3) CalculateDiscount");
 Console.WriteLine("Get the Discount amount for the VIP");
 Console.WriteLine("Reduce Order Price");

//Processing Function 4
public void AwordFreeGifts(int OrderId, int Customerid)
 Console.WriteLine("(4) AwordFreeGifts");
 Console.WriteLine("Regular Customer. Pick up a gift");
 Console.WriteLine("Place the gift item in the Order for free");

//Processing Function 5
public void GetOrderConfirmation(int OrderId, int Customerid)
 Console.WriteLine("(5) GetOrderConfirmation");
 Console.WriteLine("Order confirmation screen shown to the User");
 Console.WriteLine("Order Confirmed");

Note, there is nothing more than the call to Console output functions. But, I hope you understand how these functions will be in real world applications.

3) This class has a Member function that accepts the Multicast delegate as parameter and then makes a call to the multicast delegate. The client will make the delegate chain based on the above five function and then calls this member function:

//001_3: Takes a multicase delegate and performs business logic                                   
public void ProcessOrderShipment(OrderProcessingMethods ProcessToFollow, int Orderid, int Customerid)
            ProcessToFollow(Orderid, Customerid);

Implementation of this class is completed now. Time to go for Delegate chaining.

Client Code

The client will process the order shipment differently for three types of customers. The customer types are:
Normal customer.
Regular customer who makes purchases monthly once or twice.
The VIP customer who has built up a good relation.

For Normal customer there is no discount and surprising gifts. The regular customer will have surprising gifts based on the order cost. And VIP customer has a discount as well as gifts. Now lets us go through how the client code makes use of the multicast delegate.

1) First the instance of OrderShipment class is created. Code is below:

//Client 001: Create Ordershipment Object
OrderShipment deliverorders = new OrderShipment();

2) Next, the delegate of type OrderProcessingMethods is declared. This delegate variable is used as multi cast delegate later.

//Client 002: Declare the delegate. We are going to use it as Multicast delegate
OrderShipment.OrderProcessingMethods orderprocess;

3) Five delegate instances are created and they points to one of the five methods implemented by the OrderShipment class.

//Client 003: Create Delegate Instances
OrderShipment.OrderProcessingMethods process1 =
            new OrderShipment.OrderProcessingMethods(deliverorders.GetShoppingCartItems);
OrderShipment.OrderProcessingMethods process2 =
            new OrderShipment.OrderProcessingMethods(deliverorders.CalculateOrderPrice);
OrderShipment.OrderProcessingMethods process3 =
            new OrderShipment.OrderProcessingMethods(deliverorders.CalculateDiscount);
OrderShipment.OrderProcessingMethods process4 =
            new OrderShipment.OrderProcessingMethods(deliverorders.AwordFreeGifts);
OrderShipment.OrderProcessingMethods process5 =
            new OrderShipment.OrderProcessingMethods(deliverorders.GetOrderConfirmation);

4) Before processing the order for normal customer, a delegate chain is formed by adding the delegate created on the previous step. Once the individual delegates are combined using the + operator, the result is stored in the orderprocess delegate. Now, the orderprocess delegate holds the delegate chain and we call it as Multicast delegate. The multicast delegate is ready, it is passed to the OrderShipment class member function ProcessOrderShipment. When a call is made on the multicast delegate, the delegate invokes all the function currently in the chain. So for the Normal customer we do not want provide gift and/or discounts. Hence, those corresponding functions are not part of the delegate chain. Also note that the chained functions are called in the same order they are added to the chain. Code and picture is given below:

//Client 004: Process Order for Normal Customer. Order Id: 1000. Customer id 1000.
Console.WriteLine("Process Normal Customer");
orderprocess = process1 + process2 + process5; //Note you can use += operator also

5) Next comes the VPI customer. As he is eligible for gift as well as discounts, we need to add the corresponding functions to the multicast delegate orderprocess. Note the current delegate order in the chain. Process5 delegate is Order confirmation, which should be moved last. So process5 delegate removed from the chain, then process3 and process4 delegates are added to the chain. And finally, process5 delegate is put back before making the call to ProcessOrderShipment. Note the usage of += operator. To add a delegate you can use += operator. And to remove a delegate from the chain, you can use -= operator.

//Client 005: Process Order for VIP Customer. VIP eligible for Gift and discounts
//Order Id: 1001. Customer id 1001.
Console.WriteLine("Process VIP Customer");
orderprocess -= process5;//Remove Order confirmation from chain. [It should be at location 5]
orderprocess += process3; //Add the Process 3 and 4
orderprocess += process4;
orderprocess += process5; //Put back the process 5. Because order confirmation should be the last step.

6) The last customer serviced is a regular customer. I hope no explanation is required now as you are familiar with multicast delegate or delegate chaining.

//Client 006: Process Order for Reguslar customer. Regular customer is not eligible for Gifts,
//but enjoy discounts. So revoke the gifting process
Console.WriteLine("Process Regular Customer");
orderprocess -= process4;

Note: The sample is created on Microsoft 2003 IDE. If you have latest version say yes to the convert dialog.
Source Code: Download

No comments:

Post a Comment

Leave your comment(s) here.

Like this site? Tell it to your Friend :)