Click here to Skip to main content
15,895,084 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.4K   838   38  
Simple Rule Engine with Triggers to apply the rule
using System;
using System.Windows.Data;
using System.Windows;
using SimpleRulesEngine.Utility;

namespace SimpleRulesEngine.Trigger
{
	/// <summary>
	/// Condition for the trigger to execute
	/// </summary>
	public class Condition : ConditionBase
	{
		#region ctor

		/// <summary>
		/// Initializes a new instance of the <see cref="TriggerCondition"/> class.
		/// </summary>
		/// <param name="source">The source.</param>
		/// <param name="propertyName">Name of the STR property.</param>
		/// <param name="value">The value.</param>
		/// <param name="@operator">The e operator.</param>
        public Condition(object source, string strPropertyName, object value, Operator eOperator, bool blnIsBindingDoneForRequeryTriggerCondition)
        {
            this.value = value;
            this.source = source;
            this.propertyName = strPropertyName;
            this.@operator = eOperator;

            if (blnIsBindingDoneForRequeryTriggerCondition)
            {
                var binding = new Binding
                {
                    Source = source,
                    Path = new PropertyPath(strPropertyName),
                    Mode = BindingMode.TwoWay
                };
                BindingOperations.SetBinding(this, RequeryTriggerConditionProperty, binding);
            }
        }

		#endregion

		#region private members

		/// <summary>
		/// Value
		/// </summary>
		private object value;

		/// <summary>
		/// Source object which has the property value.
		/// </summary>
		private object source;

		/// <summary>
		/// Name of the property
		/// </summary>
		private string propertyName;

		/// <summary>
		/// Conditional Operator
		/// </summary>
		private Operator @operator;

		/// <summary>
		/// Trigger to be fired
		/// </summary>
		private Trigger trigger;

		#endregion

		#region prop

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

		#endregion

		#region propdp

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

		// Using a DependencyProperty as the backing store for TriggerProperty.  This enables animation, styling, binding, etc...
		private static readonly DependencyProperty RequeryTriggerConditionProperty =
			DependencyProperty.Register("RequeryTriggerCondition", typeof(object), typeof(Condition), new UIPropertyMetadata(null, ConditionRequeryCallBack));

		/// <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 ConditionRequeryCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
		{
		    var objCondition = (obj as Condition);
            if (objCondition != null && null != objCondition.Trigger)
            {
                objCondition.Trigger.RequeryTriggerCondition();
            }
		}

	    #endregion

		#region methods

		/// <summary>
		/// Determines whether [is condition satisfied].
		/// </summary>
		/// <returns>
		/// 	<c>true</c> if [is condition satisfied]; otherwise, <c>false</c>.
		/// </returns>
		public override bool IsConditionSatisfied()
		{
			int difference;
			if (value is IComparable)
			{
                difference = ObjectUtility<object>.Compare(source, propertyName, value as IComparable);
			}
			else
			{
                difference = ObjectUtility<object>.Compare(source, propertyName, value);
			}
			bool isConditionSatisfied;
			if (@operator == Operator.Equal)
			{
				isConditionSatisfied = 0 == difference;
			}
			else if (@operator == Operator.NotEqual)
			{
				isConditionSatisfied = (0 != difference);
			}
			else if (@operator == Operator.GreaterThan)
			{
				isConditionSatisfied = (0 < difference);
			}
			else if (@operator == Operator.GreaterThanOrEqualTo)
			{
				isConditionSatisfied = (0 <= difference);
			}
			else if (@operator == Operator.LessThan)
			{
				isConditionSatisfied = (0 > difference);
			}
			else
			{
				isConditionSatisfied = (0 >= difference);
			}
			return isConditionSatisfied;
		}

		#endregion

		#region dtor

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

		#endregion

		#region IDisposable Members

		/// <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>
		protected override void Dispose(bool blnDispose)
		{
			if (!isDisposed && blnDispose)
			{
				BindingOperations.ClearBinding(this, RequeryTriggerConditionProperty);

				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