Click here to Skip to main content
15,896,278 members
Articles / Desktop Programming / Windows Forms

Trigger Based Rule Engine

Rate me:
Please Sign up or sign in to vote.
4.60/5 (4 votes)
17 Jun 2009CPOL3 min read 46.5K   838   38  
Simple Rule Engine with Triggers to apply the rule
using System;
using System.Windows;
using System.Windows.Data;

namespace SimpleRulesEngine.Trigger
{
    /// <summary>
    /// Trigger
    /// </summary>
	public class Trigger : DependencyObject, IDisposable
	{
		#region ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="Trigger"/> class.
        /// </summary>
        /// <param name="triggerSource">The obj trigger source.</param>
        /// <param name="propertyName">Name of the STR property.</param>
        /// <param name="triggerCondition">The obj trigger condition.</param>
        /// <param name="triggerAction">The obj trigger action.</param>
        /// <param name="triggerElseAction">The obj trigger else action.</param>
		public Trigger(object objTriggerSource, string strPropertyName, ConditionBase objTriggerCondition, TriggerAction objTriggerAction, TriggerAction objTriggerElseAction)
		{
			this.triggerSource = objTriggerSource;
			this.triggerCondition = objTriggerCondition;
			this.triggerAction = objTriggerAction;
			this.propertyName = strPropertyName;
			this.triggerElseAction = objTriggerElseAction;

			if (null == objTriggerCondition)
			{
				DoBinding();
			}
			else
			{
				objTriggerCondition.Trigger = this;
			}
		}

		#endregion

		#region private fields

		/// <summary>
		/// Is this instance disposed
		/// </summary>
		private bool isDisposed;

		/// <summary>
		/// Trigger Condition
		/// </summary>
		private readonly ConditionBase triggerCondition;

        /// <summary>
        /// Trigger Action
        /// </summary>
		private TriggerAction triggerAction;

		/// <summary>
		/// Trigger Action
		/// </summary>
		private TriggerAction triggerElseAction;

		/// <summary>
		/// Property Name
		/// </summary>
		private string propertyName;

		/// <summary>
		/// Source which triggers the action
		/// </summary>
		private object triggerSource;

		#endregion

		#region propdp

		/// <summary>
		/// Gets or sets the fire trigger.
		/// </summary>
		/// <value>The fire trigger.</value>
		public object FireTrigger
		{
			get
			{
				return GetValue(FireTriggerProperty);
			}
			set
			{
				SetValue(FireTriggerProperty, value);
			}
		}

		// Using a DependencyProperty as the backing store for TriggerProperty.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty FireTriggerProperty =
			DependencyProperty.Register("FireTrigger", typeof(object), typeof(Trigger), new UIPropertyMetadata(null, TriggerCallBack));

		/// <summary>
		/// Call back method when the trigger fires.
		/// </summary>
		/// <param name="obj">The obj.</param>
		/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
		private static void TriggerCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
		{
			((Trigger) obj).Execute();
		}

		/// <summary>
		/// Execute the trigger code.
		/// </summary>
		private void Execute()
		{
			bool blnIsConditionSatisfied = true;
			if (null != triggerCondition)
			{
				blnIsConditionSatisfied = triggerCondition.IsConditionSatisfied();
			}

			if (blnIsConditionSatisfied)
			{
				triggerAction.Action();
			}
			else if (null != triggerElseAction)
			{
				triggerElseAction.Action();
			}
		}
		
		#endregion

		#region prop

		/// <summary>
		/// Gets or sets the trigger source.
		/// </summary>
		/// <value>The trigger source.</value>
		public object TriggerSource
		{
			get
			{
				return triggerSource;
			}
			set
			{
				triggerSource = value;
				if (null == triggerCondition)
				{
					DoBinding();
				}
			}
		}

		/// <summary>
		/// Gets or sets the trigger action.
		/// </summary>
		/// <value>The trigger action.</value>
		public TriggerAction TriggerAction
		{
			get
			{
				return triggerAction;
			}
			set
			{
				triggerAction = value;
			}
		}

		/// <summary>
		/// Gets or sets the trigger action.
		/// </summary>
		/// <value>The trigger action.</value>
		public TriggerAction TriggerElseAction
		{
			get
			{
				return triggerElseAction;
			}
			set
			{
				triggerElseAction = value;
			}
		}

		/// <summary>
		/// Gets or sets the name of the poperty.
		/// </summary>
		/// <value>The name of the poperty.</value>
		public string PopertyName
		{
			get
			{
				return propertyName;
			}
			set
			{
				propertyName = value;
				DoBinding();
			}
		}

		#endregion

		#region methods

		/// <summary>
		/// Does the binding.
		/// </summary>
		private void DoBinding()
		{
			ClearBinding();
			var binding = new Binding
			                  {
			                      Source = triggerSource,
			                      Path = new PropertyPath(propertyName),
			                      Mode = BindingMode.TwoWay
			                  };
		    BindingOperations.SetBinding(this, FireTriggerProperty, binding);
		}

		/// <summary>
		/// Clears the binding.
		/// </summary>
		private void ClearBinding()
		{
			BindingOperations.ClearBinding(this, FireTriggerProperty);
		}

		/// <summary>
		/// Requeries this instance.
		/// </summary>
		public void RequeryTriggerCondition()
		{
			Execute();
		}

		#endregion

		#region dtor

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="Trigger"/> is reclaimed by garbage collection.
        /// </summary>
		~Trigger()
		{
			Dispose(false);
		}

		#endregion

		#region IDisposable Members

		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
		}

		/// <summary>
		/// Releases unmanaged and - optionally - managed resources
		/// </summary>
		/// <param name="blnDispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
		private void Dispose(bool blnDispose)
		{
			if (!isDisposed && blnDispose)
			{
				BindingOperations.ClearBinding(this, FireTriggerProperty);

				if (null != triggerCondition)
				{
                    triggerCondition.Dispose();
				}

				isDisposed = true;

				GC.SuppressFinalize(this);
			}
		}

		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions