Thursday, August 5, 2010

Universal USSD Menu Builder Using .NET

USSD or Unstructured Supplementary Service Data is a capability of all GSM phones. It is generally associated with real-time or instant messaging type phone services. Response times for interactive USSD-based services are generally quicker than SMS. Samples USSD service in Indonesia are the bill status services accessed by dialing *123#(XL) or *388#(IM3).
Some of the USSD applications that we use regularly are:

  • Changing various VAS services.
  • Recharging using prepaid vouchers.
  • Alerts About special offers and services.

The Menu Builder makes it simple to create USSD applications. It is fast, flexible and easy to use and solves many of the inherent problems of creating USSD applications like rapidly USSD development, prototyping and intelligent menu generation. The Menu Builder supports hierarchical menus and can automatically enable the application with forward and back navigation options.



using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;

using System.Configuration;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Security;

using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

using Extend.Lib.Common;
using Extend.Lib.Common.Umb;
using Umb.Lib.Data.Business;

namespace Umb.Handler.ContentEngine
{

public class UmbHttpInterfaceHandler : IHttpHandler
{
public enum UmbMenuState
{

Root = 91,
Branch = 92,
}

public struct StructUmbMenus
{

public int UmbMenuPK;
public string UmbHeaderText;
public string UmbMenuText;
public int? ParentUmbMenuFK;
public int UmbMenuLevel;
public short UmbMenuIndex;
public short? WebSvcMethodFK;
public string Content;
public bool IsSmsMT;
public string LineAge;
public string UmbMenuTypeID;
}

public struct StructUserInput
{
public string I1;
public string I2;
public string I3;
public string I4;
public string I5;
public string I6;
public string I7;
public string I8;
}

public void ProcessRequest(HttpContext context)
{

string _DefaultItemUrl = ConfigurationManager.AppSettings["DefaultItemUrl"].Trim();
string _SiteTitle = ConfigurationManager.AppSettings["SiteTitle"].Trim();

List<UmbXml.ItemMenu> items = null;
string qNextState = string.Empty;
int iqNextState = -1;
int iqUserInput = -1;
int iqParentMenuPK = -1;
int childMenuPK = -1;

StructUserInput qUIn = new StructUserInput();

string currentRawUrl = HttpContext.Current.Request.RawUrl;

string umbXmlResponse = string.Empty;

string querystring = string.Empty;

int iqs = currentRawUrl.IndexOf('?');
if (iqs >= 0)
{

querystring = (iqs < currentRawUrl.Length - 1) ? currentRawUrl.Substring(iqs + 1) : String.Empty;
}

NameValueCollection rxQueryStrings = System.Web.HttpUtility.ParseQueryString(querystring);

string qParentMenuPK = string.Empty;
int? iqParentMenuPKNullable = null;

string qMsgID = string.Empty;
string qDeliverMode = "0";
string qUserInput = string.Empty;
string qDateTime = string.Empty;
string qImsi = string.Empty;
string qMsisdn = string.Empty;
string qServiceCode = string.Empty;
string itemUrl = string.Empty;
string umbMenuTypeID = string.Empty;
int umbMenuLevel = 1;
string umbHeaderText = string.Empty;

qUIn.I1 = string.Empty;
qUIn.I2 = string.Empty;
qUIn.I3 = string.Empty;
qUIn.I4 = string.Empty;
qUIn.I5 = string.Empty;
qUIn.I6 = string.Empty;
qUIn.I7 = string.Empty;
qUIn.I8 = string.Empty;

if (rxQueryStrings["MSISDN"] != null)
{

qMsisdn = rxQueryStrings["MSISDN"].ToString();
if (string.Compare(StringHelper.SubstringSafe(qMsisdn, 1, 2), "62") == 0)
{

qMsisdn = string.Format("0{0}", StringHelper.SubstringSafe(qMsisdn, 3, qMsisdn.Length - 2));
}
}
if (rxQueryStrings["SERVICECODE"] != null) qServiceCode = rxQueryStrings["SERVICECODE"];
if (rxQueryStrings["USERINPUT"] != null) qUserInput = rxQueryStrings["USERINPUT"];
if (rxQueryStrings["DATETIME"] != null) qDateTime = rxQueryStrings["DATETIME"];
DateTime? dateTime = MiscHelper.ConvertStringToDateTimeWithoutSeparator(qDateTime);
if (rxQueryStrings["DELIVERMODE"] != null) qDeliverMode = rxQueryStrings["DELIVERMODE"];
if (rxQueryStrings["IMSI"] != null) qImsi = rxQueryStrings["IMSI"];
if (rxQueryStrings["MSGID"] != null) qMsgID = rxQueryStrings["MSGID"];

if (rxQueryStrings["NEXTSTATE"] != null) qNextState = rxQueryStrings["NEXTSTATE"];

if (rxQueryStrings["PARENTMENUPK"] != null) qParentMenuPK = rxQueryStrings["PARENTMENUPK"];

if (rxQueryStrings["UIN1"] != null) qUIn.I1 = rxQueryStrings["UIN1"];
if (rxQueryStrings["UIN2"] != null) qUIn.I2 = rxQueryStrings["UIN2"];
if (rxQueryStrings["UIN3"] != null) qUIn.I3 = rxQueryStrings["UIN3"];
if (rxQueryStrings["UIN4"] != null) qUIn.I4 = rxQueryStrings["UIN4"];
if (rxQueryStrings["UIN5"] != null) qUIn.I5 = rxQueryStrings["UIN5"];
if (rxQueryStrings["UIN6"] != null) qUIn.I6 = rxQueryStrings["UIN6"];
if (rxQueryStrings["UIN7"] != null) qUIn.I7 = rxQueryStrings["UIN7"];
if (rxQueryStrings["UIN8"] != null) qUIn.I8 = rxQueryStrings["UIN8"];

if (!string.IsNullOrEmpty(qNextState)) { Int32.TryParse(qNextState, out iqNextState); }

if (!string.IsNullOrEmpty(qParentMenuPK)) { Int32.TryParse(qParentMenuPK, out iqParentMenuPK); }
else { iqParentMenuPK = -1; }

if (iqParentMenuPK > 0) iqParentMenuPKNullable = iqParentMenuPK;

UmbMenus umbMenus = new UmbMenus();

switch (iqNextState)
{
case (int)UmbMenuState.Root:
items = MenuRoot(_DefaultItemUrl, ref qUIn);
umbXmlResponse = UmbXml.MenuPageDisplay(items, "NONE", "0", _SiteTitle);
break;
case (int)UmbMenuState.Branch:
umbMenus.GetChildUmbMenuTypeIDByParent(iqParentMenuPKNullable, ref umbMenuTypeID);
switch (umbMenuTypeID.ToUpper())
{

case "MULTIPLECHOICE":
iqUserInput = (qUserInput != null) && (qUserInput.Trim().Length != 0)
? Int32.Parse(qUserInput) : 0;
if ((iqUserInput) > 0)
umbMenus.GetChildUmbMenuPKByParentAndIndex(iqParentMenuPKNullable, iqUserInput, ref childMenuPK);
break;
case "TEXTANSWER":
umbMenus.GetChildUmbMenuPKByParent(iqParentMenuPKNullable, ref childMenuPK);
break;
case "CLOSING":
umbMenus.GetChildUmbMenuPKByParent(iqParentMenuPKNullable, ref childMenuPK);
break;
}

umbMenus.GetChildUmbMenuLevelByParent(iqParentMenuPKNullable, ref umbMenuLevel);
SetUserInput(qUserInput, umbMenuLevel, ref qUIn);
bool isHaveChilds = false;
umbMenus.IsHaveChilds(childMenuPK, ref isHaveChilds);
if (isHaveChilds)
{

umbMenus.GetChildUmbMenuTypeIDByParent(childMenuPK, ref umbMenuTypeID);
umbMenus.GetChildUmbHeaderTextByParent(childMenuPK, ref umbHeaderText);
switch (umbMenuTypeID.ToUpper())
{
case "MULTIPLECHOICE":
items = MenuMultipleChoice(_DefaultItemUrl, qUIn, childMenuPK);
umbXmlResponse = UmbXml.MenuPageDisplay(items, "NONE", "0", umbHeaderText);
break;
case "TEXTANSWER":
MenuTextAnswer(_DefaultItemUrl, qUIn, childMenuPK, ref itemUrl, ref umbHeaderText);
umbXmlResponse = UmbXml.InputPageDisplay(umbHeaderText, itemUrl);
break;
case "CLOSING":
umbMenus.GetChildUmbHeaderTextByParent(childMenuPK, ref umbHeaderText);
umbMenus.Process(childMenuPK, qMsisdn, qUIn.I1, qUIn.I2, qUIn.I3, qUIn.I4, qUIn.I5,
qUIn.I6, qUIn.I7, qUIn.I8);
umbXmlResponse = UmbXml.ResultPageDisplay(umbHeaderText);

break;
}

}

break;

default:
itemUrl = string.Format(
@"{0}?&NEXTSTATE={1}&PARENTMENUPK={2}", _DefaultItemUrl,
((int)UmbMenuState.Root), string.Empty);
umbXmlResponse = UmbXml.InputPageDisplay("Masukkan kode server :", itemUrl);
break;
}

context.Response.Write(umbXmlResponse);
}


private void SetUserInput(string qUserInput, int? level, ref StructUserInput qUIn)
{

switch (level)
{
case 1:
qUIn.I1 = qUserInput;
break;
case 2:
qUIn.I2 = qUserInput;
break;
case 3:
qUIn.I3 = qUserInput;
break;
case 4:
qUIn.I4 = qUserInput;
break;
case 5:
qUIn.I5 = qUserInput;
break;
case 6:
qUIn.I6 = qUserInput;
break;
case 7:
qUIn.I7 = qUserInput;
break;
case 8:
qUIn.I8 = qUserInput;
break;
}

}



private List<UmbXml.ItemMenu> MenuRoot(string defaultItemUrl, ref StructUserInput qSUIn)
{

string itemUrl = string.Empty;
string umbMenuTypeID = string.Empty;
UmbMenuState umbMenuState = UmbMenuState.Branch;

DataTable dt = null;
List<UmbXml.ItemMenu> items = null;
UmbXml.ItemMenu itemMenu;
items = new List<UmbXml.ItemMenu>();

UmbMenus umbMenus = new UmbMenus();
dt = umbMenus.GetAllRoot();

StructUmbMenus s = new StructUmbMenus();

if (dt != null)
{

foreach (DataRow row in dt.Rows)
{

GetRow(row, true, ref s);

umbMenus.GetChildUmbMenuTypeIDByParent(s.UmbMenuPK, ref umbMenuTypeID);

switch (umbMenuTypeID.Trim().ToUpper())
{

case "MULTIPLECHOICE":
umbMenuState = UmbMenuState.Branch;
break;
case "TEXTANSWER":
umbMenuState = UmbMenuState.Branch;
break;
case "CLOSING":
umbMenuState = UmbMenuState.Branch;
break;
}


itemUrl = string.Format(
@"{0}?UIN1={1}&UIN2={2}&UIN3={3}&UIN4={4}&UIN5={5}&UIN6={6}&UIN7={7}&UIN8={8}&NEXTSTATE={9}&PARENTMENUPK={10}",
defaultItemUrl, qSUIn.I1, qSUIn.I2, qSUIn.I3, qSUIn.I4, qSUIn.I5,
qSUIn.I6, qSUIn.I7, qSUIn.I8, ((int)umbMenuState), string.Empty);

itemMenu = new UmbXml.ItemMenu(s.UmbMenuIndex.ToString(), "NONE", "0", itemUrl, "0", s.UmbMenuText);
items.Add(itemMenu);
}

}

return items;
}


private List<UmbXml.ItemMenu> MenuMultipleChoice(string defaultItemUrl, StructUserInput qSUIn, int? umbMenuPK)
{

string itemUrl = string.Empty;
string umbMenuTypeID = string.Empty;
UmbMenuState umbMenuState = UmbMenuState.Branch;

DataTable dt = null;
List<UmbXml.ItemMenu> items = null;
UmbXml.ItemMenu itemMenu;
items = new List<UmbXml.ItemMenu>();

UmbMenus umbMenus = new UmbMenus();
dt = umbMenus.ListMyChildsOnelevel(umbMenuPK);

StructUmbMenus s = new StructUmbMenus();

string strUmbMenuPK = string.Empty;
if (umbMenuPK != null) strUmbMenuPK = umbMenuPK.ToString().Trim();
else strUmbMenuPK = null;

if (dt != null)
{

foreach (DataRow row in dt.Rows)
{
GetRow(row, true, ref s);

umbMenus.GetChildUmbMenuTypeIDByParent(s.UmbMenuPK, ref umbMenuTypeID);

switch (umbMenuTypeID.Trim().ToUpper())
{

case "MULTIPLECHOICE":
umbMenuState = UmbMenuState.Branch;
break;
case "TEXTANSWER":
umbMenuState = UmbMenuState.Branch;
break;
case "CLOSING":
umbMenuState = UmbMenuState.Branch;
break;
}


itemUrl = string.Format(
@"{0}?UIN1={1}&UIN2={2}&UIN3={3}&UIN4={4}&UIN5={5}&UIN6={6}&UIN7={7}&UIN8={8}&NEXTSTATE={9}&PARENTMENUPK={10}",
defaultItemUrl, qSUIn.I1, qSUIn.I2, qSUIn.I3, qSUIn.I4, qSUIn.I5,
qSUIn.I6, qSUIn.I7, qSUIn.I8, ((int)umbMenuState), strUmbMenuPK);

itemMenu = new UmbXml.ItemMenu(s.UmbMenuIndex.ToString(), "NONE", "0", itemUrl, "0", s.UmbMenuText);
items.Add(itemMenu);
}

}

return items;
}


private string MenuTextAnswer(string defaultItemUrl, StructUserInput qSUIn, int? umbMenuPK,
ref string itemUrl, ref string umbHeaderText)
{

itemUrl = string.Empty;
umbHeaderText = string.Empty;
UmbMenus umbMenus = new UmbMenus();
umbMenus.GetChildUmbHeaderTextByParent(umbMenuPK, ref umbHeaderText);

itemUrl = string.Format(
@"{0}?UIN1={1}&UIN2={2}&UIN3={3}&UIN4={4}&UIN5={5}&UIN6={6}&UIN7={7}&UIN8={8}&NEXTSTATE={9}&PARENTMENUPK={10}",
defaultItemUrl, qSUIn.I1, qSUIn.I2, qSUIn.I3, qSUIn.I4, qSUIn.I5,
qSUIn.I6, qSUIn.I7, qSUIn.I8, ((int)UmbMenuState.Branch), umbMenuPK);

return itemUrl;
}


public void GetRow(DataRow row, bool isconvertnull, ref StructUmbMenus s)
{

s.UmbMenuPK = Convert.ToInt32(row["UmbMenuPK"]);
if (isconvertnull) s.UmbHeaderText = row.IsNull("UmbHeaderText") ? null : Convert.ToString(row["UmbHeaderText"]);
else s.UmbHeaderText = row.IsNull("UmbHeaderText") ? string.Empty : Convert.ToString(row["UmbHeaderText"]);
s.UmbMenuText = Convert.ToString(row["UmbMenuText"]);
if (isconvertnull) s.ParentUmbMenuFK = row.IsNull("ParentUmbMenuFK") ? null : (int?)Convert.ToInt32(row["ParentUmbMenuFK"]);
else s.ParentUmbMenuFK = row.IsNull("ParentUmbMenuFK") ? 0 : (int?)Convert.ToInt32(row["ParentUmbMenuFK"]);
s.UmbMenuLevel = Convert.ToInt32(row["UmbMenuLevel"]);
s.UmbMenuIndex = Convert.ToInt16(row["UmbMenuIndex"]);
if (isconvertnull) s.WebSvcMethodFK = row.IsNull("WebSvcMethodFK") ? null : (short?)Convert.ToInt16(row["WebSvcMethodFK"]);
else s.WebSvcMethodFK = row.IsNull("WebSvcMethodFK") ? 0 : (short?)Convert.ToInt16(row["WebSvcMethodFK"]);
if (isconvertnull) s.Content = row.IsNull("Content") ? null : Convert.ToString(row["Content"]);
else s.Content = row.IsNull("Content") ? string.Empty : Convert.ToString(row["Content"]);
s.IsSmsMT = Convert.ToBoolean(row["IsSmsMT"]);
if (isconvertnull) s.LineAge = row.IsNull("LineAge") ? null : Convert.ToString(row["LineAge"]);
else s.LineAge = row.IsNull("LineAge") ? string.Empty : Convert.ToString(row["LineAge"]);
}

private bool RedirectIsValid(string redir, Uri currentUri)
{
String val1 = redir.ToLower();
String url = currentUri.AbsoluteUri.ToLower();
String host = currentUri.Host.ToLower();

if (val1 == url) { return false; }

if (val1 == ("http://" + host)) { return false; }
if (val1 == ("http://" + host + "/")) { return false; }

if (val1 == host) { return false; }
if (val1 == (host + "/")) { return false; }

return true;
}

public bool IsReusable
{

get { return false; }
}

}

}

Tuesday, December 11, 2007

Generic Decorator Pattern


using System;
using 
System.Collections.Generic;

//Decorator pattern is very powerful pattern which can be used for supplementing the inheritance relationship with 
//composition based relationship. The basic idea is Attaching additional responsibilities to an object dynamically. 
//Decorators provide a flexible alternative to subclassing for extending functionality and it can be implemented 
//on several different ways. 
//This sample program presented here show that it can be done through Generic and Interface. 

//The classes and/or objects participating in this pattern are:
//1. Generic Abstract Decorator
//2. Generic Concrete Decorator
//3. Abstract Component
//4. Concrete Component


namespace Generic.DecoratorPattern
{
    
    // Generic Abstract Decorator 
    
abstract class Decorator<T> : ComputerItem  where T : ComputerItem, new() 
    {
        
protected readonly T computerItem = new T();

        
// Constructor 
        
public Decorator(T computerItem)
        {
            
this.computerItem computerItem;
        
}

        
public override void DisplayReport()
        {
            computerItem.DisplayReport()
;
        
}

    }

    
// Generic Concrete Decorator 
    
class Saleable<T> :  Decorator<T> where T : ComputerItem, new()
    {
        
protected List<string> Buyers = new List<string>();

        
// Constructor 
        
public Saleable(T computerItem) : base(computerItem)
        {
        }

        
public void SaleItem(string name)
        {
            Buyers.Add(name)
;
            
computerItem.NumStocks--;
        
}

        
public void ReturnItem(string name)
        {
            Buyers.Remove(name)
;
            
computerItem.NumStocks++;
        
}

        
public override void DisplayReport()
        {
            
base.DisplayReport();

            foreach 
(string buyer in Buyers)
            {
                Console.WriteLine(
" Buyer: " + buyer);
            
}
        }
    }

    
interface IComputerItem
    {
        
void DisplayReport();
    
}

    
// Abstract Component 
    
abstract class ComputerItem : IComputerItem
    {
        
private string brand;

        public string 
Brand
        {
            
get return brand}
            
set { brand = value; }
        }

        
private string type;

        public string 
Type
        {
            
get return type}
            
set { type = value; }
        }

        
private int numStocks;

        public int 
NumStocks
        {
            
get return numStocks}
            
set { numStocks = value; }
        }

        
public abstract void DisplayReport();
    
}

    
// Concrete Component 
    
class Desktop : ComputerItem
    {
        
public Desktop()
        { }

        
public Desktop(string brand, string type, int numStocks)
        {
            
this.Brand brand;
            this
.Type type;
            this
.NumStocks numStocks;
        
}

        
public override void DisplayReport()
        {
            Console.WriteLine(
"\n----- Desktop ----- ");
            
Console.WriteLine(" Brand: {0}", Brand);
            
Console.WriteLine(" Type: {0}", Type);
            
Console.WriteLine(" # Stocks: {0}", NumStocks);
        
}
    }

    
// Concrete Component 
    
class Laptop : ComputerItem
    {
        
public Laptop()
        { }

        
public Laptop(string brand, string type, int numStocks)
        {
            
this.Brand brand;
            this
.Type type;
            this
.NumStocks numStocks;
        
}

        
public override void DisplayReport()
        {
            Console.WriteLine(
"\n----- Laptop ----- ");
            
Console.WriteLine(" Brand: {0}", Brand);
            
Console.WriteLine(" Type: {0}", Type);
            
Console.WriteLine(" # Stocks: {0}", NumStocks);
        
}
    }

    
class Program
    {
        
static void Main()
        {
            
// Create desktop 
            
Desktop desktop = new Desktop("HPP""XM600"32);
            
desktop.DisplayReport();

            
// Create laptop 
            
Laptop laptop = new Laptop("ASUSS""F3MAP0"9);
            
laptop.DisplayReport();

            
Console.WriteLine("\nMaking laptop saleable:");

            
Saleable<Laptop> saleLaptop = new Saleable<Laptop>(laptop);
            
saleLaptop.SaleItem("Customer #1");
            
saleLaptop.SaleItem("Customer #2");
            
saleLaptop.SaleItem("Customer #3");

            
saleLaptop.DisplayReport();

            
Console.Read();
        
}
    }
}

Tuesday, December 4, 2007

Design Event Using Generic Delegate And Generic Interface

//When you design an event you have to do 3 steps

//1. Declare a private member for the event
//private event EventHandler<MyEventType> _EventName;

//2. Declare public accessors for adding and removing handlers
//public event EventHandler<MyEventType> EventName
//{
//      add    { _EventName += value; }
//      remove { _EventName -= value; }
//}

//3. Provide a virtual OnEventName method
//virtual void OnEventName(MyEventType e)
//{
//      if(_EventName != null)
//      {
//            try
//            {
//                  _EventName(this,e);
//            }
//            catch(Exception e)
//            {
//                  //your code here
//            }
//      }
//}

using System;

namespace 
Lab
{
    
    
interface IEventNum
    {
        
int EventNum
        {
            
get; set;
        
}
    }

    
//Define an interface that can perform operations on a generic type parameter
    
interface ITEventNum<T>
    {
        T EventNum
        {
            
get;
            set;
        
}
    }

    
//Create a type that inherits from EventArgs if the event is going to propagate event specific data.
    
public class MyEventArgs1 : EventArgs, IEventNum
    {
        
public int _EventNum;

        public int 
EventNum
        {
            
get return  _EventNum}
            
set { _EventNum = value; }
        }

    }

    
//Create a delegate signature for the event. 
    
public delegate void MyEventHandler(object source, MyEventArgs1 arg);

    class 
MyEvent1
    {
        
private static int count 0;

        
// Declare an event of delegate type MyEventHandler of MyEventArgs1.
        // Implicit Registration
        
public event MyEventHandler SomeEvent;

        
//Create a method on the type that will raise the event.
        
public virtual void OnSomeEvent()
        {
            MyEventArgs1 arg 
= new MyEventArgs1();

            
// Copy to a temporary variable to be thread-safe.
            
MyEventHandler temp SomeEvent;
            if 
(SomeEvent != null)
            {
                
try
                
{
                    arg.EventNum 
count++;
                    
temp(this, arg);
                
}
                
catch (Exception e)
                {
                    Console.WriteLine(e.Message)
;
                
}
            }
        }
    }

    
//Create a type that inherits from EventArgs if the event is going to propagate event specific data.
    
public class MyEventArgs2 : EventArgs, IEventNum
    {
        
public int _EventNum;

        public int 
EventNum
        {
            
get return _EventNum}
            
set { _EventNum = value; }
        }
    }

    
class MyEvent2
    {
        
private static int count 0;

        
//Generic EventHandler<T> delegate to declare an event bound to the specific EventArgs derivative 
        //Implicit Registration
        
public event EventHandler<MyEventArgs2> SomeEvent;

        
//Create a method on the type that will raise the event.
        
public virtual void OnSomeEvent()
        {
            MyEventArgs2 arg 
= new MyEventArgs2();

            
// Copy to a temporary variable to be thread-safe.
            
EventHandler<MyEventArgs2> temp SomeEvent;
            if 
(temp != null)
            {
                
try
                
{
                    arg.EventNum 
count++;
                    
temp(this, arg);
                
}
                
catch (Exception e)
                {
                    Console.WriteLine(e.Message)
;
                
}
            }
        }
    }


    
//Create a type that inherits from EventArgs if the event is going to propagate event specific data.
    //When you implement a generic interface, the supporting type specifies the placeholder type
    
public class MyEventArgs3<T> : EventArgs, ITEventNum<T>
    {
        
public T _EventNum;
        
        public T 
EventNum
        {
            
get return  _EventNum}
            
set { _EventNum = value; }
        }

    }

    
    
class MyEvent3
    {
        
private static int count 0;

        
// Declare an event of delegate type EventHandler of MyEventArgs3.
        // Implicit Registration
        // public event EventHandler<MyEventArgs3<int>> SomeEvent;

        // Explicit registration
        
private EventHandler<MyEventArgs3<int>> _SomeEvent;
        public event 
EventHandler<MyEventArgs3<int>> SomeEvent
        {
            
add    { _SomeEvent += value; }
            
remove { _SomeEvent -= value; }
        }
        
        
//Create a method on the type that will raise the event.
        
public virtual void OnSomeEvent()
        {
            MyEventArgs3<
int> arg = new MyEventArgs3<int>();

            
// Copy to a temporary variable to be thread-safe.
            
EventHandler<MyEventArgs3<int>> temp _SomeEvent;
            if 
(temp != null)
            {
                
try
                
{
                    arg.EventNum 
count++;
                    
temp(this, arg);   
                
}
                
catch(Exception e)
                {
                    Console.WriteLine(e.Message)
;
                
}
                
            }
        }
    }

    
class EventDemo1 : MyEvent1
    {
        
public void TestMain()
        {
            Test1 test1 
= new Test1();

            
MyEvent1 evt;

            
evt = new EventDemo1();
            
MyEventArgs1 arg = new MyEventArgs1();

            
// Add handler() to the event list.
            
evt.SomeEvent += new MyEventHandler(test1.handler);

            
// Fire the event.
            
evt.OnSomeEvent();
            
evt.OnSomeEvent();

        
}

        
public override void OnSomeEvent()
        {
            
base.OnSomeEvent();
            
Console.WriteLine("Override");
        
}
    }

    
class EventDemo2 : MyEvent2
    {
        
public void TestMain()
        {
            Test2 test2 
= new Test2();
            
MyEvent2 evt;

            
evt = new EventDemo2();
            
MyEventArgs2 arg = new MyEventArgs2();

            
// Add Handler() to the event list.
            
evt.SomeEvent += new EventHandler<MyEventArgs2>(test2.Handler);

            
// Fire the event.
            
evt.OnSomeEvent();
            
evt.OnSomeEvent();

        
}

        
public override void OnSomeEvent()
        {
            
base.OnSomeEvent();
            
Console.WriteLine("Override");
        
}

    }


    
class EventDemo3 : MyEvent3
    {
        
public void TestMain()
        {
            Test3 test3 
= new Test3();
            
            
MyEvent3 evt;
            
            
evt = new EventDemo3();
            
MyEventArgs3<int> arg = new MyEventArgs3<int>();

            
// Add Handler() to the event list.
            
evt.SomeEvent += new EventHandler<MyEventArgs3<int>>(test3.Handler);
           
            
// Fire the event.
            
evt.OnSomeEvent();
            
evt.OnSomeEvent();

        
}

        
public override void OnSomeEvent()
        {
            
base.OnSomeEvent();
            
Console.WriteLine("Override");
        
}

    }


    
class Test1
    {
        
public void handler(object source, MyEventArgs1 arg)
        {
            
if (source == nullthrow new ArgumentNullException("source");
            
Result.Write(source, arg);
        
}
    }

    
class Test2
    {
        
public void Handler(object source, MyEventArgs2 arg)
        {
            
if (source == nullthrow new ArgumentNullException("source");
            
Result.Write(source, arg);
        
}
    }

    
class Test3
    {
        
public void Handler(object source, MyEventArgs3<int> arg)
        {
            
if (source == nullthrow new ArgumentNullException("source");
            
Result.Write(source, arg);
        
}

    }

    
class Result
    {
        
public static void Write(object source, IEventNum arg)
        {
            Console.WriteLine(
"Event {0} received by an Test object.", arg.EventNum);
            
Console.WriteLine("Source is " + source);
        
}

        
public static void Write(object source, ITEventNum<int> arg)
        {
            Console.WriteLine(
"Event {0} received by an Test object.", arg.EventNum);
            
Console.WriteLine("Source is " + source);
        
}
    }
   
    
class program
    {
        
public static void Main()
        {
            EventDemo1 evt1 
= new EventDemo1();
            
evt1.TestMain();

            
EventDemo2 evt2 = new EventDemo2();
            
evt2.TestMain();

            
EventDemo3 evt3 = new EventDemo3();
            
evt3.TestMain();

            
Console.Read();
        
}
    }
}
Indonesia To Blog -Top Site
SEO - search engine submission and optimisation