How to establish event-listener communication in ASP.NET MVC 5?
Asked Answered
C

0

6

I have a project that is written with c# on the top of ASP.NET MVC 5 framework. I set up an IoC using Unity-container to handle dependency injections.

I need to establish some kind of communication capabilities where any part of my application can listen to an event then perform specific logic.

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.

// 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<T> 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<T>(T _event) where T : Event
    {
        // Get all listeners
        var listeners = Container.ResolveAll<Listener<T>>();

        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);
                }
            }
        }
    }
}

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.

// 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<UserWasCreated>
{
    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<UserWasCreated>
{
    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);
    }
}

Question: Is there a better approach to creating event/listener in ASP.NET MVC 5 project? What are the issues with the above setup?

Combatant answered 17/10, 2018 at 21:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.