Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Application Framework to plug components - Part II - Notify Events

0.00/5 (No votes)
15 Jun 2005 1  
This article describes how to fire events to a framework from a component plugged into it.

Sample Image - FrameworkEvents.gif

Introduction

Application Framework to plug components - Part I has already explained how to build pluggable components to a framework and invoke methods in such a component. In a typical component, the component itself has to initiate and invoke methods in its framework. This article describes how to use interfaces in calling back functions in the framework.

How it works....

As I described in my previous article, a proxy DLL contains interfaces which build the bridge between the framework and component. To deal with events, the proxy DLL has to declare an interface which describes all possible events that the framework should get notified of. This interface which describes the callback functions in a framework is implemented and instantiated in the application framework. And a reference to this object instance is passed to the relevant component using .NET reflection. Having a reference to an object instance in the framework, the component could invoke any method in that object instance which resides in the application framework.

Using the code

The demo project implements simple mathematical operations on two integers with interfaces. An event gets fired in an attempt to divide a number by zero, and at the same time, there is a button on a form which could simulate an event on the component.

MathProxy.dll consists of two interfaces, namely IMath and IMathEvent. As the name implies, IMathEvent describes the function prototypes of events that get invoked in the application framework. Here, the CalcErrorEvent is the only function in the interface and it just passes a string to the framework.

public interface IMath
{
    int CalcValues(int iValue1, int iValue2);
}

public interface IMathEvent
{
    void CalcErrorEvent(string s);
}

The IMathEvent interface is implemented in the application framework as the MathEvent class. MathEvent has a member from the parent class which is the central location for application the framework. This is only to access the framework from the event interface. Here goes the class implementation:

public class MathEvents : IMathEvent
{
    public frmIntfDemo m_form;
    void IMathEvent.CalcErrorEvent(string s)
    {
        m_form.txtEventMsg.Text = s;
    }
}

frmIntfDemo is the application framework at this point and it has a member of type MathEvent. The MathEvent class gets instantiated at the constructor of frmIntfDemo and a reference to the startup module is saved in the MathEvent class.

m_mathEvent = new MathEvents();
m_mathEvent.m_form = this;

Now, let's have a look at how the component gets created. Here I have used CreateEx instead of Create just to differentiate this implementation from the previous article's implementation. The CreateIntf has three static members namely m_MathEvent, m_div and m_ComponentUI. These members hold references to the MathEvent instance created in the application framework, the Div class instance which implements the IMath interface and a form instance which is used to simulate events by the component respectively. (Here the frmComponentUI's sole purpose is to initiate an event with user interaction.)

public class CreateIntf
{
    static IMathEvent m_MathEvent;
    static Div m_div;
    static frmComponentUI m_ComponentUI;
    static public IMath CreateEx(IMathEvent mathEvent)
    {
        m_MathEvent = mathEvent;
        m_div = new Div();
        m_div.m_Events = m_MathEvent;

        m_ComponentUI = new frmComponentUI();
        m_ComponentUI.m_mathEvent = m_MathEvent;
        m_ComponentUI.Show();
        return m_div;
    }
}

The Div class implements the IMath interface and has a reference to the IMathEvent implementation (MathEvent) in the application framework as well. If we take a closer look on the CalcValues implementation, you can see that, when the denominator is zero, the function calls CalcErrorEvent of the IMathEvent interface. This notifies the application framework for a divide by zero error.

public class Div : IMath
{
    public IMathEvent m_Events;
    int IMath.CalcValues(int iValue1,int iValue2)
    {
        int iRes=0;
        if ( iValue2 == 0 )
            m_Events.CalcErrorEvent( "Device by Zero Error" );
        else
            iRes = iValue1 / iValue2;

        return iRes;
    }
}

In the frmComponentUI, btnSimulate_Click has code to simulate a CalcErrorEvent.

private void btnSimulate_Click(object sender, System.EventArgs e)
{
    m_mathEvent.CalcErrorEvent( "Error event simulate by Component UI" );
}

Conclusion

This article along with Application Framework to plug components - Part I describes how to build a simple application framework which could plug components at runtime using .NET reflection and interfaces.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here