HomeGuidesAPI Reference
Submit Documentation FeedbackJoin Developer CommunityOptimizely GitHubOptimizely NuGetLog In

Implementing a custom event provider

The following example shows a simple pseudo code for writing an event provider based on file with options.

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

This code is provided as an example of implementing an event provider for an external system and should not be used 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 recieve listners 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
  }

Configuring 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>