Click here to Skip to main content
15,881,092 members
Articles / Programming Languages / C#
Tip/Trick

Use of delegates for form reusability- Dependency injection principle

Rate me:
Please Sign up or sign in to vote.
3.75/5 (3 votes)
21 Dec 2010CPOL2 min read 15.2K   5   2
We may come across situations where a form may be called from many other forms but business logic it has to execute may be different. How can we handle it?

In enterprise applications, we may use a common form in many places, but the result from that form needs to be used in different business logic. The form cannot return a result. So the question would be how we can reuse a common form in different scenarios. For example, a custom confirmation dialog form or in a POS application, there will be a common tender form for sales receipt and invoice, but the business logic involved using the tender data will be different in sales receipt and invoice. As the form can't return anything, it has to call two different types of logic which makes this form tightly coupled and not reusable.


Dependency injection principle is design pattern that helps in this situation. For more details about dependency injection, refer to Dependency Injection for Loose Coupling


Here we inject a delegate to make the form decoupled and reusable. For the demo, I have a form (form1) with two buttons (button1 and button2) and two labels (label1 and label2). I have a second form with two buttons (button1 and button2) and a static label whichever text is in it. When I click each button, the form2 will be opened. Clicking the form2 buttons it calls function which it knows only at RUNTIME. So the form doesn't know anything it is going to do in design time, it only shares its data but not knowing the logic to execute. For this decopupling, we can use delegate. In the form, one declares a delegate.


C#
public delegate void invokeConfirmationCallback();

Once declared, the delegate instantiates the delegate with the desirable function it has to point.


C#
invokeConfirmationCallback confirmCallback = new invokeConfirmationCallback(handleButton1Confirmation);

In the form2, declare a variable of the wrapper class Delegate.


C#
private Delegate confirmDelegate;

Assign the instantiated delegate in the form1 to form2's delegate variable.


C#
confirmForm = new Form2();
            confirmForm.setConfirmHandler(confirmCallback);

Invoke the delegate in the form2 events.


C#
confirmDelegate.DynamicInvoke();

In this way, we can tell form2 at runtime which business logic it has to execute and reuse it anywhere in the application.


The complete source dump of form1 is as follows:


C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace EventDelegates_Demo
{
    public partial class Form1 : Form
    {
        public delegate void invokeConfirmationCallback();
        private Form2 confirmForm;
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void button1_Click(object sender, EventArgs e)
        {
            invokeConfirmationCallback confirmCallback = new invokeConfirmationCallback(handleButton1Confirmation);
            invokeConfirmationCallback rejectCallback = new invokeConfirmationCallback(handleButton1Reject);
            confirmForm = new Form2();
            confirmForm.setConfirmHandler(confirmCallback);
            confirmForm.setRejectHandler(rejectCallback);
            confirmForm.Show();
        }
        private void handleButton1Confirmation()
        {
            confirmForm.Close();
            label2.Text = "Action 1 Request Confirmed";
            
        }
        private void handleButton1Reject()
        {
            confirmForm.Close();
            label2.Text = "Action 1 Request Rejected";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            invokeConfirmationCallback confirmCallback = new invokeConfirmationCallback(handleButton2Confirmation);
            invokeConfirmationCallback rejectCallback = new invokeConfirmationCallback(handleButton2Reject);
            confirmForm = new Form2();
            confirmForm.setConfirmHandler(confirmCallback);
            confirmForm.setRejectHandler(rejectCallback);
            confirmForm.Show();
        }
        private void handleButton2Confirmation()
        {
            confirmForm.Close();
            label2.Text = "Action 2 Request Confirmed";
        }
        private void handleButton2Reject()
        {
            confirmForm.Close();
            label2.Text = "Action 2 Request Rejected";
        }
    }
}

The complete source code of Form2 is as shown below:


C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace EventDelegates_Demo
{
    public partial class Form2 : Form
    {
        private Delegate confirmDelegate;
        private Delegate rejectDelegate;
        public Form2()
        {
            InitializeComponent();
        }
        private void Form2_Load(object sender, EventArgs e)
        {
        }
        public void setConfirmHandler(Delegate confirmDelegate)
        {
            this.confirmDelegate = confirmDelegate;
        }
        public void setRejectHandler(Delegate rejectDelegate)
        {
            this.rejectDelegate = rejectDelegate;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            confirmDelegate.DynamicInvoke();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            rejectDelegate.DynamicInvoke();
        }
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
I am developer in .Net and GIS. albin_gis@yahoo.com

Comments and Discussions

 
GeneralReason for my vote of 4 Well explained. Pin
dmjm-h27-Dec-10 5:11
dmjm-h27-Dec-10 5:11 
GeneralThanks, this is a good reminder. Pin
Dr.Walt Fair, PE21-Dec-10 15:52
professionalDr.Walt Fair, PE21-Dec-10 15:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.