Monday, December 17, 2012

Practical Use of Delegate in real time Application

In This article  we are going to discuss how we can use a delegate in a real time application to build dynamic components.

Introduction

Below are two important features in delegate which helps to make a component dynamic.
1-      1. It allows to inject code by the client
2-      2. Multi-casting

Inject functions by client code.

One important use of delegate is with the help of delegate  we can develop a component which client can use and inject their functionality to it. In the below example I have shown a UserRegistration Component. Client will call this component to register a user ,however it entirely depends on the client  to implement how they want to notify users about their registration via email or via SMS .

namespace RegistrationModule
{ 
    public delegate void NotifyUser(ContactDetail objContact); 
    class RegisterUser    {
        public void Register(Userinfo objUser, NotifyUser myFunc)        {
            //code to save the user details to the database
            // 
            myFunc(objUser.objContact);
        } 
    }

    class Userinfo    {
        public string name;        public int age;        public ContactDetail objContact;    }
    class ContactDetail    {
        public string email;        public string mobNo;    }
}

Client Code:
Lets say first client wants to send SMS to notify their user.So below will be their implementation.
I have given the comment to explain the code.
//Below function is having same signature as delegate NotifyUser and will be attached to the delegate.public void SendSMS(ContactDetail objContact)
        {
            string MobNo = objContact.mobNo;            //Add your code to send Registration success message to the user mobile number.
        }

        public void RegisterUser()
        {   //Create an Object of Userifo and fill the user details to it.            Userinfo obj = new Userinfo();           
            obj.name = "Sathish";
            obj.age = 27;
            ContactDetail objC = new ContactDetail();
            objC.mobNo = "9999999999";
            objC.email = "sathish.siri.1985@gmail.com";
            obj.objContact = objC;
   //Create a delegate instance and attach the SendSMS() to it.            NotifyUser sendSMS = new NotifyUser(SendSMS);
            RegisterUser objReg = new RegisterUser();
//Invoke the register function with the Delegate Instance sendSMS

            objReg.Register(obj, sendSMS); 
        }

Now lets say the second client wants to notify the user via email:
public void SendEmail(ContactDetail objContact)
        {            string strEmail = objContact. email;
            //Add your code to send Registration success email to the user email address.
        }

        public void RegisterUser()
        {
            Userinfo obj = new Userinfo();           
            obj.name = "Sathish";
            obj.age = 27;
            ContactDetail objC = new ContactDetail();
            objC.mobNo = "9999999999";
            objC.email = "sathish.siri.1985@gmail.com";
            obj.objContact = objC; 
            NotifyUser sendEmail = new NotifyUser(SendEmail); 
            RegisterUser objReg = new RegisterUser();
            objReg.Register(obj, sendEmail);
         }
That's it.Now client-1 user will get user registration success message as an SMS and client-2 will get user registration success message as an email.  Important thing to notice here is SendSMS and SendEmail is the code written by the client however it is invoked by the RegistrationModule what in other words we can say delegates allow us to inject functionality.

multi-casting 

In the above scenario let’s say the client wants to send the notification both via email and SMS, well below is the simple change he has to make.

usr.Notify = new NotifyUser(SendSMS);
usr.Notify += new NotifyUser(SendEmail);
usr.Register();

What is an Event?

Ø  Event provides a way for objects to notify state change or any action.
Ø  Technically events are delegate instance declared with event keyword.
Ex :

delegate void Print();
event Print OnStartPrint;


Why Events? Can not delegate do the same thing?

Yes delegate can do the same thing, but does not give abstraction. Means client can invoke the delegate where ever they want ,but event won’t allow that.

Show me a practical example showing difference between event and delegate?

Let’s consider our above example of user registration.

class Program
    {
        static void Main(string[] args)
        {
            User usr = new User();
            usr.Name = "sathish";
            usr.Age = 27;
            usr.Contact.Email = "sathish.siri.1985@gmail.com";
            usr.Contact.MobNo = "9999999999";
            usr.Notify = new NotifyUser(SendEmail);
            usr.Register();

            Console.Read();
        }
       
        static void SendEmail(ContactDetail objContact, string NotificationMsg)
        {
            string email = objContact.Email;
            //Add your code to send NotificationMsg to the user email.
            Console.WriteLine("email Sent to" + email);
        }    
   }

Looks good with delegate ,  but what if the client uses the below code.

class Program
    {
        static void Main(string[] args)
        {
            User usr = new User();
            usr.Name = "sathish";
            usr.Age = 27;
            usr.Contact.Email = "sathish.siri.1985@gmail.com";
            usr.Contact.MobNo = "9999999999";
usr.Notify = new NotifyUser(SendEmail);
usr.Notify(usr.Contact, "Your TPIN is 1234");
            //usr.Register();
            Console.Read();
        }


       
        static void SendEmail(ContactDetail objContact, string NotificationMsg)
        {
            string email = objContact.Email;
            //Add your code to send NotificationMsg to the user email.
            Console.WriteLine("email Sent to" + email);
        }    
   }

Output:

Now the SMS  is sent even though the user  is not registered.
 So now a question, should we allow the client to write the below line of code, ie should we give access to him to invoke the delegate?
usr.Notify(usr.Contact, "Your TPIN is 1234");
Off course NO,  in our case because only User.Register() method knows when userid  is created and when password is created ,so no one other than User class should be allowed to invoke the delegate.

So how do we fix this problem...simple use event. By declaring the Notify as event user will get compilation error if he attempts to invoke the event by below line

usr.Notify(usr.Contact, "Your TPIN is 1234");

So what changes we have to make in our program?

1.       Just add the event keyword before the delegate name NotifyUser in the RegistrationModule.User class as below.

      public event NotifyUser Notify;

2.       Use  +=  instead of  =  for initializing events i.e

usr.Notify += new NotifyUser(SendEmail);


Thursday, November 15, 2012

SQL Joins

In this article, we’ll see the basic concepts of SQL JOINs.The JOIN keyword is used in a SQL statement to query data from two or more tables based on a relationship between certain columns in these tables.
Inner JOIN
A JOIN that displays only rows that have a match in both the JOINed tables is known as inner JOIN. This
is the default type of JOIN in the Query and View Designer.


 
Outer JOIN
A JOIN that includes rows even if they do not have related rows in the joined table is an Outer JOIN. You
can create three different outer JOINs to specify the unmatched rows to be included:
Left Outer JOIN: In Left Outer JOIN, all rows in the first-named table, i.e. “left” table, which appears
leftmost in the JOIN clause, are included. Unmatched rows in the right table do not appear.


 

Right Outer JOIN: In Right Outer JOIN, all rows in the second-named table, i.e. “right” table, which
appears rightmost in the JOIN clause, are included. Unmatched rows in the left table are not included.


 
Full Outer JOIN: In Full Outer JOIN, all rows in all the joined tables are included, whether they are
matched or not.


 
Cross JOIN
A cross JOIN devoid of a WHERE clause produces the Cartesian product of the tables involved in the JOIN.
The size of a Cartesian product result set is the number of rows in the first table multiplied by the number
of rows in the second table. One common example is when a company lists all its products in a pricing
table to compare each product with others prices.


 

Self-JOIN
In this particular case, one table JOINs to itself with one or two aliases to stave off confusion. A self-JOIN
can be of any type, as long as the joined tables are the same. A self-JOIN is unique in the sense that it
involves a relationship with only one table. A common example is when a company has a hierarchal
reporting structure whereby a member of staff reports to another member. Self-JOIN can either be an
Outer JOIN or an Inner JOIN.


Note:
Before we continue further let me make it very clear that INNER JOIN should be used where it
cannot be used and simulating INNER JOIN using any other JOINs will degrade the performance. If there are scopes to convert any OUTER JOIN to INNER JOIN, it should be done with
priority.