Events
A mechanism for communication between objects. Events are used in building loosely coupled applications so that object components are not tightly coupled (Highly dependent on one another). Events makes it easier to extend the application without breaking.
In the example, Document Creator does not know anything Mail Service. When there is any change in MailService (subscriber), DocumentCreator (Publisher) doesn’t need to be recompiled. Compilation time reduced by adding new classes.
Implementing Eventing mechanism
Public class DocumentCreator
{
Public void Create(Document document)
{
// Invoke a method in publisher to notify the subscribers
OnDocumentCreated();
}
}
How does class know what method to call? An agreement/contract is needed between publishers and subscribers. Agreement is formed as a method with a specific signature.
Example of a method called in a subscriber (Ex of EventHandler):
Public void OnDocumentCreated(object source, EventArgs e)
{
// When the time event is rised, you can do desired action here.
}
Publisher (DocumentCreator) class does not know anything about subscribers (MailService). It is decoupled from them. All it knows is a method.
Create an Event and a Delegate
Class Program
{
Static void Main(string[] args)
{
var document = Document() { Title = “Document 1” };
var documentCreator = new DocumentCreator();
documentCreator.Create(document)
}
}
Public class Document
{
Public string Title { get; set; }
}
// Publisher class
Public class DocumentCreator
{
Console.WriteLine(“Creating … ”);
// define a delegate
Public delegate void DocumentCreatedEventHandler(object source, EventArgs args);
// define an event based on that delegate
Public event DocumentCreatedEventHandler DocumentCreated;
Public void Create(Document document)
{
OnDocumentCreated();
}
// Event method
Protected virtual void OnDocumentCreated()
{
// Raise the event
if(DocumentCreated != null)
{ DocumentCreated(this, EventArgs.Empty); }
}
}
Event methods name has to start with “On” keyword and continue with event name. It should be protected and abstract.
// Subscriber class
Public class MailService
{
// Event method in subscriber
Public void OnDocumentCreated (object source, EventArgs e)
{
Console.WriteLine(“Mail Service : Sending email … ”);
}
}
Lets subscribe mail service to the event of publisher:
class Program
{
Static void Main(string[] args)
{
var document = new Document() { Title= “DOC”}
var documentCreator = new DocumentCreator(); // publisher
var mailService = new MailService(); // subscriber
// register the handler (A reference to the method) for the event
documentCreator.DocumentCreated += mailService.OnDocumentCreated;
documentCreator.Create(document);
}
}
You can add as much subscriber as you want. You can do it without changing the publisher code.
If you change the publisher code, you don’t need to deploy it again.
Instead of EventArgs you can use any type of class that is derived from EventArgs. All you need to do is to add it into the publisher class.
Public class DocumentEventArgs : EventArgs
{
Public Document document { get; set; }
}
Microsoft allows two built-in delegates that you can use in defining events:
public delegate void EventHandler(object sender, EventArgs e);
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
Second delegate allows you return one or more values to the event handler method. You need to create a class that is derived from EventArgs class.
In order to use EventHandler delegate, we need to do following modifications :
class Program
{
Static void Main(string[] args)
{
var document = new Document() { Title= “DOC”}
var documentCreator = new DocumentCreator(); // publisher
var mailService = new MailService(); // subscriber
// register the handler (A reference to the method) for the event
documentCreator.OnDocumentCreated += mailService.OnDocumentCreated;
documentCreator.Create(document);
}
}
// Publisher class
Public class DocumentCreator
{
Console.WriteLine(“Creating … ”);
// define an event
Public event EventHandler< DocumentEventArgs > OnDocumentCreated;
Public void Create(Document document)
{
OnDocumentCreated(this, new DocumentEventArgs() );
}
// Event method
Protected virtual void OnDocumentCreated(object sender, DocumentEventArgs e)
{
// Raise the event
if(DocumentCreated != null)
{ DocumentCreated(this, e); }
}
}
// EventArg class
Public class DocumentEventArgs : EventArgs
{ Public Document document { get; set; } }
// Subscriber class
Public class MailService
{
// Event method in subscriber
Public void OnDocumentCreated (object source, DocumentEventArgs e)
{
Console.WriteLine(“Mail Service : Sending email … ”);
}
}
Author
İsmail Erdem Sırma
Senior Software Engineer