Event Bus Documentation

Topics: Writing modules
Sep 26, 2011 at 3:43 PM

Hi,

I'm looking for documentation (if any) and/or examples of how to development against the Orchard event bus.

An example of what I'm looking for is when a user completes his/her profile, I want to raise an even, such as "ProfileCompleteEvent" and then have an event listener that subscribes to that even and does something with it, like sends an email and/or changes the user's role.

Thank you.

 - Matt

Coordinator
Sep 26, 2011 at 4:34 PM

There are a lot of examples in the code. Here is a quick summary:

To define a new set of events, create an interface itself inheriting from IEventHandler. Each method will be an event. e.g., Orchard.Users.Events.IUserEventHandler.

To trigger those events, in your class, take a dependency on this interface, then call the methods on the injected dependency. e.g., Orchard.Users.Services.MembershipService implements IUserEventHandler, and uses it in CreateUser().

To register to those events, implement the event handler interface.

Sep 30, 2011 at 2:01 PM

Thank you. That's what I was looking for.

Dec 5, 2011 at 4:35 AM
sebastienros wrote:

There are a lot of examples in the code. Here is a quick summary:

To define a new set of events, create an interface itself inheriting from IEventHandler. Each method will be an event. e.g., Orchard.Users.Events.IUserEventHandler.

To trigger those events, in your class, take a dependency on this interface, then call the methods on the injected dependency. e.g., Orchard.Users.Services.MembershipService implements IUserEventHandler, and uses it in CreateUser().

To register to those events, implement the event handler interface.

Hi sebastienros,

I have run out idea get the events to be registered in my own module. do you mind share a piece of code? the event just not show.

Dec 5, 2011 at 2:57 PM

Can you show the code you are trying to use?

Feb 27, 2012 at 3:46 AM

I am also having a problem with the event bus.  I am trying to loosely follow along on the great tutorial from Skywalker Software (http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-part-1) and cannot seem to get the event bus to register my service provider.

 

Interface:

using Orchard.Events;

namespace ThorTech.ThorStore.Extensibility
{
    public interface IPaymentServiceProvider : IEventHandler
    {
        void RequestPayment(PaymentRequest e);
        void ProcessResponse(PaymentResponse e);
    }
}

 

Target Implementation:

    [OrchardFeature("ThorTech.ThorStore.SimulatedPSP")]
    class SimulatedPaymentServiceProvider : IPaymentServiceProvider
    {
        public void RequestPayment(PaymentRequest e)
        {

           ...

          }

}

 

Caller:

    public class OrderController : Controller
    {
        private readonly dynamic _shapeFactory;
        private readonly IOrderService _orderService;
        private readonly IAuthenticationService _authenticationService;
        private readonly ICart _shoppingCart;
        private readonly ICustomerService _customerService;
        private readonly IEnumerable<IPaymentServiceProvider> _paymentServiceProviders;
        private readonly Localizer _t;

        public OrderController(IShapeFactory shapeFactory, IOrderService orderService, IAuthenticationService authenticationService, ICart shoppingCart, ICustomerService customerService, IEnumerable<IPaymentServiceProvider> paymentServiceProviders)
        {
            _shapeFactory = shapeFactory;
            _orderService = orderService;
            _authenticationService = authenticationService;
            _shoppingCart = shoppingCart;
            _customerService = customerService;
            _paymentServiceProviders = paymentServiceProviders;
            _t = NullLocalizer.Instance;
        }

        [Themed, HttpPost]
        public ActionResult Create()
        {
           <snip>
          
            // Fire the PaymentRequest event
            var paymentRequest = new PaymentRequest(order);

            foreach (var handler in _paymentServiceProviders)
            {
                handler.RequestPayment(paymentRequest);

                // If the handler responded, it will set the action result
                if (paymentRequest.WillHandlePayment)
                {
                    return paymentRequest.ActionResult;
                }
            }


            // If we got here, no PSP handled the OrderCreated event, so we'll just display the order.
             <snip>

       }

 

The ThorTech.ThorStore.SimulatedPSP feature is enabled in the Modules inteface and exists in the [Settings_ShellFeatureStateRecord] table. 

It looks like it is wired up correctly, but the target (SimulatedPaymentServiceProvider) never gets called.

Where is my disconnect? 

 

 

Coordinator
Feb 27, 2012 at 4:46 AM

Make SimulatedPaymentServiceProvider public.

Feb 27, 2012 at 5:36 AM

Duh!  Yes, that was it.  Thanks for the quick response!

Oct 23, 2012 at 1:20 PM
Edited Oct 23, 2012 at 1:22 PM

I'm wondering which purpose the EventBus and the IEventHandler interface serve - what's the gain over simply doing the following, omitting the Event stuff altogether?

public interface IMyHandler : IDependency {
    void React();
}

public class MyHandler : IMyHandler {
    public void React() {
        // do something
    }
}

public class MyTrigger {
    private IMyHandler _handler;
    
    public MyTrigger(IMyHandler handler) {
        _handler = handler;
    }

    public void SomeAction() {
        _handler.React();
    }
}

Would really like to know.

Developer
Oct 23, 2012 at 2:48 PM

IEventHandler hooks directly in to the Orchard pipeline. Creating your own IMyHandler would mean that you sit outside of said pipeline.

Take a look at DefaultOrchardEventBus.cs

Oct 25, 2012 at 10:22 AM

Also, as I understand it, if you were to call React on an IEnumerable of IMyHandler, then any exception thrown would be passed to your MyTrigger, whereas if you .Invoke an IEnumerable of IEventHandler, then exceptions will be caught and logged.  If you're depending on the behaviour of the dependency, then perhaps IDependency is a better fit as you'll know how it worked out.  However, if you're just notifying interested subscribers, then you don't necessarily want to fail just because a subscriber has.