I think you are misleading ASP.NET (incorrect) use of events with simple event handling.
We will start with simple event handling. Events are another way to perform "Open [for expansion] / Closed [for modification]". When your class provides an event, it allows external classes (perhaps not yet thought-out classes, much less built ones) to have the code executed by your class. This is a fairly powerful extension mechanism, and it does not require your class to be modified in any way.
As an example, consider a web server that knows how to accept a request but does not know how to process the file (I will use bidirectional events here, where the handler can pass data back to the event source. Some say itโs not kosher, but this is the first example that came to mind):
class WebServer { public event EventHandler<RequestReceivedEventArgs> RequestReceived; void ReceiveRequest() {
Without changing the source code of this class โ perhaps in a third-party library โ I can add a class that knows how to read a file from disk:
class FileRequestProcessor { void WebServer_RequestReceived(object sender, EventArgs e) { e.Response = File.ReadAllText(e.Request); } }
Or maybe the ASP.NET compiler:
class AspNetRequestProcessor { void WebServer_RequestReceived(object sender, EventArgs e) { var p = Compile(e.Request); e.Response = p.Render(); } }
Or maybe I'm just curious to know that the event happened without affecting it at all. Let's say for registration:
class LogRequestProcessor { void WebServer_RequestReceived(object sender, EventArgs e) { File.WriteAllText("log.txt", e.Request); } }
All of these classes basically โinjectโ code in the middle of WebServer.OnRequestReceived .
Now, for the ugly part. ASP.NET has this annoying little habit of writing event handlers to handle your own events. So, the class inherited from ( System.Web.UI.Page ) has an event called Load :
abstract class Page { public event EventHandler Load; virtual void OnLoad(EventArgs e) { var h = this.Load; if (h != null) h(e); } }
and you want to run the code when the page loads. Following the Open / Closed principle, we can either inherit or override:
class MyPage : Page { override void OnLoad(EventArgs e) { base.OnLoad(e); Response.Write("Hello World!"); } }
or use eventing:
class MyPage : Page { MyPage() { this.Load += Page_Load; } void Page_Load(EventArgs e) { Response.Write("Hello World!"); } }
For some reason, Visual Studio and ASP.NET prefer an event-based approach. I suppose you can have several handlers for the Load event, and they will all fire automatically, but I never see anyone doing this. Personally, I prefer a redefinition approach - I think it is a little clearer and you will never have the question "why did I subscribe to my own events?".