One of the simplest ways to inject code into Community Server is through the use of a CS module. Using a CS module, you register a method with Community Server such that the method is called when a an event occurs, such as the creation of a new user.
In the same way that you can implement a module for a Community Server event, you can create a module for an event that occurs within Four Roads Commerce. For example, if you need to notify your accounting system when an order is successfully completed, you can have a shop module register an event handler for the event. The event handler can execute whatever code is suitable for the situation.
This blog post shows you how to set up a basic shop module.
Compatibility
This article contains technical details that are specific to Four Roads Commerce for Community Server 2007. I'll add a separate article in the near future supporting Commerce for Community Server 2008.
Quick and Dirty Set up
To create your shop module, you need to take a few, quick actions. Please do the following:
-
Create a new class library project to hold your shop module implementation.
-
In your new project, add a reference to the FourRoads.Shop.Core assembly.
-
Create a new class file to hold your module.
-
In the class file, add a using clause for the FourRoads.CsShop.Core.Components namespace.
-
In the class file, create a class that implements the IShopModule interface.
-
In the CommunityServer_Override.config file, find the ShopModules element. This element contains one or more child elements for each shop module registered with Commerce. A default Commerce installation will already have some modules registered such as the AutoCompleteOrder module. Add an entry for your own shop module. For example:
<ShopModules>
<add name="OrderHandling" type="Your.Namespace.OrderHandlingModule, Your.AssemblyName" />
...
</ShopModules>
Register Your Event Handler
The IShopModule interface defines a single method named Init. Your module uses the Init method to register one or more event handlers with Commerce. The signature of the Init method is as follows:
void Init(EventManager em, XmlNode node);
In Commerce, the EventManager class is responsible for managing the shop modules and calling event handlers based upon the modules' event registrations. When the EventManager reads the list of registered shop modules, it calls the Init method of each module.The EventManager passes to the Init method a reference to itself and the XML node for the module from the CommunityServer_Override.config. Note that you can store custom attributes on the <add> element for a shop module and read the values of those attributes in the module's Init method.
The main purpose of the module's Init method is to register an event handler. In a CS module, you register an event handler for a specific event such as PreRenderPost. In a Commece shop module, you register an event handler for an object type. For example, if you want to capture events related to subscriptions then you associate the event handler with the SubscriptionEvent class.
To register an event handler, use the EventManager's AddShopEvent method. In the next example, a module registers an event handler for subscription events:
public class SubscriptionHandlingModule : IShopModule
{
public void Init(EventManager em, System.Xml.XmlNode node)
{
em.AddShopEvent(typeof(SubscriptionEvent), new ShopEventHandler(em_SubscriptionMessage));
}
...
}
Implement the Event Handler
Your event handler will be passed two arguments:
-
A parameter of type object. This object is the focus of the event and it will be of the same type for which your Init method registered the event handler. For example, if you registered an event handler for SubscriptionEvent then this parameter will be of type SubscriptionEvent. If your handler registered itself for Orders then the object will be of type Order.
-
A parameter of type ShopEventArgs. This parameter contains information associated with the event.
When your event handler is called, it should first verify it is being passed the correct type of object. It must then look at relevant information on the event object or the ShopEventArgs instance to determine what action is to be taken by the event handler. The following example verifies the object is a SubscriptionEvent and then uses a switch statement to react to the RequestEventType property of the SubscriptionEvent instance.
protected virtual void em_SubscriptionMessage(object eventObj, ShopEventArgs e)
{
SubscriptionEvent se = eventObj as SubscriptionEvent;
if (se != null)
{
switch (se.RequestEventType)
{
case SubscriptionEvent.EventType.Expired:
// Do something here when a subscription has expired.
break;
case SubscriptionEvent.EventType.PendingRenewal:
// Do something here when it is time to
// notify a member their subscription must be renewed
break;
case SubscriptionEvent.EventType.RenewFailed:
// Do something here when a subscription renewal has failed.
break;
}
}
}
ShopEventArgs
The ShopEventArgs provides you with the following properties:
- ApplicationType - This property is always set to the value ApplicationType.Shop (numeric value 4120) where ApplicationType is located in the namespace FourRoads.CsShop.Core.Components.
- State - This is a value from the EventAction enumeration. The EventAction enumeration is located in namespace FourRoads.CsShop.Core.
- Type - This is a value from the EventType enumeration that is also located in the FourRoads.CsShop.Core namespace.
Use the Type property to determine if the event handler is being called before or after an event. Possible values include:
-
Pre - The event handler is being just before an event will occur.
-
Post - The event handler is being called after an event has occurred.
-
None - It is irrelevant as to whether the event handler is being called before or after the event.
Use the State property to determine why the event is happening. Possible values include:
- Create - The object of the event is being created.
- Update - The object of the event is being updated.
- Delete - The object of the event is being deleted.
- Unknown - The action being taken is defined via the object of the event. Read the Eventful Object Types section to get an overview of the objects that identify the reason for an event.
- View - This action is not currently used by Commerce.
- Send - This action is not currently used by Commerce.
Eventful Object Types
Four Roads Commerce raises events for several classes. You may register an event handler for each of them. The following sections talk about each class and its events.
Cart
When a shopping cart is updated, the Cart class raises an event with EventAction.Update both before and after the cart is updated.
CartItem
When a shopping cart is updated, the CartItem class raises an event with State = EventAction.Update both before and after the cart item is serialized.
Order
The Order class raises an event under the following conditions:
- Before and after an order is created.
- Before and after an existing order is updated in the database.
- Before and after an existing order is deleted.
OrderEvent
Use this class when you need to know when payment has been received for an order or when a payment failure occurred. The OrderEvent instance contains a reference to the order, available via its Order property. The OrderEvent instance also has a property named RequestEventType. It is set to value OrderEvent.EventType.PaymentReceived when a payment is successful. It is set to value OrderEvent.EventType.PaymentFailed when the transaction could not be completed.
The following code snippet shows you how to write an event handler that looks for successful and failed payments:
public void Init(EventManager em, System.Xml.XmlNode node)
{
em.AddShopEvent(typeof(OrderEvent), new ShopEventHandler(em_OrderHandler));
}
protected virtual void em_OrderHandler(object eventObj, ShopEventArgs e)
{
OrderEvent orderEvent = eventObj as OrderEvent;
if (orderEvent != null && orderEvent.RequestEventType == OrderEvent.EventType.PaymentReceived)
{
Order order = orderEvent.Order;
if (order != null)
{
// Do something with the order.
}
}
}
OrderItem
The OrderItem class raises an event both before and after an OrderItem is created and updated.
Subscription
The Subscription class raises an event before a subscription is deleted and both before and after a subscription is created or updated.
SubscriptionEvent
Use the SubscriptionEvent class to detect situations such as a subscription expiring. The SubscriptionEvent instance provides a reference to the subscription via its Subscription property. It describes the reason for the event via its RequestEventType property. Values for RequestEventType are as follows:
- SubscriptionEvent.EventType.PendingRenewal - A subscription is nearing the time when it must be renewed and the member is to be notified.
- SubscriptionEvent.EventType.RenewFailed - A subscription could not be renewed due to a payment failure.
- SubscriptionEvent.EventType.Expired - A subscription was not renewed and has expired.
Summary
In this post, you learned about the Four Roads Commerce event system. You created a shop module and integrated it into your solution. You learned the classes for which Commerce raises an event and the types of events you can expect for those classes. You saw how to registered an event handler for a class and how to implement the event hander.
If you have any questions or recommendations for the Commerce event system, please leave a comment on this blog post or tell us about it in the Commerce support forums.