title: How to establish event-listener communication in ASP.NET MVC 5?
body: <p>I have a project that is written with <code>c#</code> on the top of ASP.NET MVC 5 framework. I set up an <code>IoC</code> using <a href="https://code.msdn.microsoft.com/Dependency-Injection-in-11d54863" rel="nofollow noreferrer">Unity-container</a> to handle dependency injections.</p>
  
  <p>I need to establish some kind of communication capabilities where any part of my application can listen to an event then perform specific logic.</p>
  
  <p>The following is my first stab at building the event/listener but wondering if this is a good approach and if there is a better way to go about creating event/listeners.</p>
  
  <pre><code>// First we define a base class for the Events
  // This allows me tho identify Events. Perhaps this could be changed to interface instead of a base class
  public abstract class Event
  {
  
  }
  
  // Second we define a base class for our listener
  // each listener must provide a an event that it wish to listen to
  public abstract class Listener&lt;T&gt; where T : Event
  {
      // each listener will add to do logic inside the Handle() method
      public abstract void Handle(T _event);
  }
  
  // Here is my announcing service or event dispatcher
  // This class announces that an event took place for anyone that cares
  public class Announcer : IAnnouncer
  {
      private IUnityContainer Container;
  
      public Announcer(IUnityContainer container)
      {
          Container = container;
      }
  
      public void Announce&lt;T&gt;(T _event) where T : Event
      {
          // Get all listeners
          var listeners = Container.ResolveAll&lt;Listener&lt;T&gt;&gt;();
  
          foreach(var listener in listeners)
          {
              // here I may need to add a support to queue up the events or delay dispatching if needed
              try
              {
                  listener.Handle(_event);
  
                  if(listener is IHandleSuccess _listener)
                  {
                      _listener.Finished(_event, listener);
                  }
              }
              catch (Exception e)
              {
                  if (listener is IHandleFailed _listener)
                  {
                      _listener.Failed(_event, e);
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>Here is an example of how I would use the above code. Assume I want to send a welcome email and schedule an orientation to a user once a user is created.</p>
  
  <pre><code>// First, define a simple event called UserWasCreated
  public class UserWasCreated : Event
  {
      public User User { get; private set; }
  
      public UserWasCreated(User user)
      {
          User = user;
      }
  }
  
  // Listener Example 1, Now we have a listener that would listen for when a user is added 
  // This listener would simply send a welcome email to the new user
  public class SendWelcomeEmail : Listener&lt;UserWasCreated&gt;
  {
      public void Handle(UserWasCreated _event)
      {
          // here we can send an to the event.User....
      }
  }
  
  // Listener Example 2, Now we have a listener that would listen for when a user is added 
  // This listener would simply sign up the user for an orientation
  public class ScheduleOrientation : Listener&lt;UserWasCreated&gt;
  {
      public void Handle(UserWasCreated _event)
      {
          // here we can schedule the orientation
      }
  }
  
  // In the controller we make announcement that the event took place
  public UsersController : Controller
  {   
      private IUserMapper UserMapper;
      private IAnnouncer Announcer;
    private IUserService UserService;
  
      public UsersController(IUserMapper userMapper, IAnnouncer announcer, IUserService userService)
      {
          UserMapper = userMapper;
          Announcer = announcer;
           UserService = userService;
      }
  
      ...
  
      [HttpPost, ValidateAntiForgeryToken]
      public ActionResult Create(CreateUserViewModel viewModel)
      {
          if (ModelState.IsValid)
          {
              User user = UserMapper.Map(viewModel);
  
              UserService.Create(user);
  
              // Here we announce the the event UserWasCreated took place.
              Announcer.Announce(new UserWasCreated(user));
          }
  
          return View(viewModel);
      }
  }
  </code></pre>
  
  <p><strong>Question</strong>: Is there a better approach to creating event/listener in ASP.NET MVC 5 project? What are the issues with the above setup?</p>