HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Implement a custom event provider

Shows a simple pseudo-code for writing an event provider based on file with options.

You can find more providers, such as the Amazon and Azure providers, in the Optimizely NuGet feed.

This code is an example of implementing an event provider for an external system. Do not use it in production.

using EPiServer.Events;
using EPiServer.Events.Providers;
using EPiServer.Framework.Configuration;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Web;
using EPiServer.Web.Hosting;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MSMQEventProvider {
  #region msmq
  public class MSMQEventProvider: EventProvider {
    private
    const string EPiServerQueueName = "private$\\episerverevents";
    MessageQueue _sendQueue;
    private static object _sendLock = new object();
    IList < Timer > _receiveTimers = new List < Timer > ();
    TimeSpan _waitTimeout = new TimeSpan(0, 0, 0, 0, 10);

    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) {
      base.Initialize(name, config);

      //Get all existing EPiServer queues
      var queues = MessageQueue.GetPrivateQueuesByMachine(Environment.MachineName)
        .Where(q => q.QueueName.StartsWith(EPiServerQueueName));
      _sendQueue = queues.SingleOrDefault(q => q.QueueName.EndsWith(CurrentApplicationId));

      if (_sendQueue == null) {
        string queuePath = ".\\" + EPiServerQueueName + CurrentApplicationId;
        _sendQueue = MessageQueue.Create(queuePath);
        _sendQueue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
        _sendQueue.Formatter = new BinaryMessageFormatter();
      }

      //Set up receive listeners for all other queues
      foreach(var queue in queues.Where(q => !q.QueueName.EndsWith(CurrentApplicationId))) {
        queue.Formatter = new BinaryMessageFormatter();
        _receiveTimers.Add(new Timer(new TimerCallback(Receive), queue, 0, 1000));
      }
    }

    public override void Uninitialize() {
      base.Uninitialize();
      foreach(var timer in _receiveTimers) {
        timer.Dispose();
      }
      _sendQueue.Dispose();
    }

    public override void SendMessage(EventMessage message) {
      lock(_sendLock) {
        _sendQueue.Send(message);
      }
    }

    private void Receive(object state) {
      MessageQueue queue = state as MessageQueue;
      Message message = null;
      //Receive throws for empty queue therefore the check with enumerator
      while (!IsQueueEmpty(queue)) {
        message = queue.Receive(_waitTimeout);
        OnMessageReceived(new EventMessageEventArgs(message.Body as EventMessage));
      }
    }

    private bool IsQueueEmpty(MessageQueue queue) {
      using(MessageEnumerator enumerator = queue.GetMessageEnumerator2()) {
        return !enumerator.MoveNext();
      }
    }

    private string CurrentApplicationId {
      get {
        return GenericHostingEnvironment.Instance.ApplicationID.Replace('/', '_').ToLower();
      }
    }

  }
  #endregion
}

Configure an event provider

To add a custom event provider, add the provider configuration to the event element in the <episerver.framework> section of the web.config as the following example shows:

<event defaultProvider="msmq">
  <providers>
    <add name="msmq" 
         type="MSMQEventProvider.MSMQEventProvider, MSMQEventProvider" />
  </providers>
</event>