Click here to Skip to main content
15,893,588 members
Articles / Database Development / SQL Server

Ready-to-use Mass Emailing Functionality with C#, .NET 2.0, and Microsoft® SQL Server 2005 Service Broker

Rate me:
Please Sign up or sign in to vote.
4.84/5 (40 votes)
7 Sep 200613 min read 298.6K   4.6K   210  
This paper demonstrates an extensible mass emailing framework (Smart Mass Email SME). The demo implementation uses cutting edge .NET technologies available today such as C#, .NET 2.0, Microsoft® SQL Server 2005 Service Broker, MS Provider Pattern, Enterprise Library January 2006 etc.
using System;
using System.Text;

using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;

using System.Runtime.Serialization;
using System.Xml.Serialization;


namespace SmartMassEmail.Entities
{
   /// <summary>
   /// A generic collection for the nettiers entities that are generated from views. 
   /// Supports filtering, databinding, searching and sorting.
   /// </summary>
   [Serializable]
   public class VList<T> : ListBase<T>
   {

      /// <summary>
      /// Initializes a new instance of the <see cref="T:VList{T}"/> class.
      /// </summary>
      public VList()
      {
      }

      #region BindingList overrides

      /// <summary>
      /// Inserts the specified item in the list at the specified index.
      /// </summary>
      /// <param name="index">The zero-based index where the item is to be inserted.</param>
      /// <param name="item">The item to insert in the list.</param>
      protected override void InsertItem(int index, T item)
      {
         base.InsertItem(index, item);
      }

      /// <summary>
      /// Removes the item at the specified index.
      /// </summary>
      /// <param name="index">The zero-based index of the item to remove.</param>
      protected override void RemoveItem(int index)
      {
         base.RemoveItem(index);
      }

      #endregion

      #region ICloneable

      ///<summary>
      /// Creates an exact copy of this VList{T} instance.
      ///</summary>
      ///<returns>The VList{T} object this method creates, cast as an object.</returns>
      ///<implements><see cref="ICloneable.Clone"/></implements>
      public override object Clone()
      {
         return this.Copy();
      }

      ///<summary>
      /// Creates an exact copy of this VList{T} object.
      ///</summary>
      ///<returns>A new, identical copy of the VList{T}.</returns>
      public virtual VList<T> Copy()
      {
         VList<T> copy = new VList<T>();
         foreach (T item in this)
         {
            T itemCopy = (T)MakeCopyOf(item);
            copy.Add(itemCopy);
         }
         return copy;
      }
      #endregion ICloneable

      #region Added Functionality

      /// <summary>
      /// Performs the specified action on each element of the specified array.
      /// </summary>
      /// <param name="list">The list.</param>
      /// <param name="action">The action.</param>
      public static void ForEach<U>(VList<U> list, Action<U> action)
      {
         list.ForEach(action);
      }     

      #endregion	Added Functionality

      #region Find

      ///<summary>
      /// Finds a collection of objects in the current list matching the search criteria.
      ///</summary>
      /// <param name="column">Property of the object to search, given as a value of the 'Entity'Columns enum.</param>
      /// <param name="value">Value to find.</param>
      public virtual VList<T> FindAll(System.Enum column, object value)
      {
         return FindAll(column.ToString(), value, true);
      }

      ///<summary>
      /// Finds a collection of objects in the current list matching the search criteria.
      ///</summary>
      /// <param name="column">Property of the object to search, given as a value of the 'Entity'Columns enum.</param>
      /// <param name="value">Value to find.</param>
      /// <param name="ignoreCase">A Boolean indicating a case-sensitive or insensitive comparison (true indicates a case-insensitive comparison).  String properties only.</param>
      public virtual VList<T> FindAll(System.Enum column, object value, bool ignoreCase)
      {
         return FindAll(column.ToString(), value, ignoreCase);
      }

      ///<summary>
      /// Finds a collection of objects in the current list matching the search criteria.
      ///</summary>
      /// <param name="propertyName">Property of the object to search.</param>
      /// <param name="value">Value to find.</param>
      public virtual VList<T> FindAll(string propertyName, object value)
      {
         return FindAll(propertyName, value, true);
      }

      ///<summary>
      /// Finds a collection of objects in the current list matching the search criteria.
      ///</summary>
      /// <param name="propertyName">Property of the object to search.</param>
      /// <param name="value">Value to find.</param>
      /// <param name="ignoreCase">A Boolean indicating a case-sensitive or insensitive comparison (true indicates a case-insensitive comparison).  String properties only.</param>
      public virtual VList<T> FindAll(string propertyName, object value, bool ignoreCase)
      {
         PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
         PropertyDescriptor searchBy = props.Find(propertyName, true);

         VList<T> result = new VList<T>();

         int index = 0;

         while (index > -1)
         {
            index = this.FindCore(searchBy, value, index, ignoreCase);

            if (index > -1)
            {
				result.Add(this[index]);               

               	//Increment the index to start at the next item
               	index++;
            }
         }

         return result;
      }

		#region Find All By

        ///<summary>
        /// Finds a collection of <see cref="IEntity" /> objects in the current list matching the search criteria.
        ///</summary>
        /// <param name="findAllByType"><see cref="FindAllByType" /> Type to easily search by</param>
        /// <param name="column">Property of the object to search, given as a value of the 'Entity'Columns enum.</param>
        /// <param name="value">Value to find.</param>
        public virtual VList<T> FindAllBy(FindAllByType findAllByType, System.Enum column, object value)
        {
            return FindAllBy(findAllByType, column.ToString(), value, true);
        }

        ///<summary>
        /// Finds a collection of <see cref="IEntity" /> objects in the current list matching the search criteria.
        ///</summary>
        /// <param name="findAllByType"><see cref="FindAllByType" /> Type to easily search by</param>
        /// <param name="column">Property of the object to search, given as a value of the 'Entity'Columns enum.</param>
        /// <param name="value">Value to find.</param>
        /// <param name="ignoreCase">A Boolean indicating a case-sensitive or insensitive comparison (true indicates a case-insensitive comparison).  String properties only.</param>
        public virtual VList<T> FindAllBy(FindAllByType findAllByType, System.Enum column, object value, bool ignoreCase)
        {
            return FindAllBy(findAllByType, column.ToString(), value, ignoreCase);
        }

        ///<summary>
        /// Finds a collection of <see cref="IEntity" /> objects in the current list matching the search criteria.
        ///</summary>
        /// <param name="findAllByType"><see cref="FindAllByType" /> Type to easily search by</param>
        /// <param name="propertyName">Property of the object to search.</param>
        /// <param name="value">Value to find.</param>
        public virtual VList<T> FindAllBy(FindAllByType findAllByType, string propertyName, object value)
        {
            return FindAllBy(findAllByType, propertyName, value, true);
        }

        ///<summary>
        /// Finds a collection of <see cref="IEntity" /> objects in the current list matching the search criteria.
        ///</summary>
        /// <param name="findAllByType"><see cref="FindAllByType" /> Type to easily search by</param>
        /// <param name="propertyName">Property of the object to search.</param>
        /// <param name="value">Value to find.</param>
        /// <param name="ignoreCase">A Boolean indicating a case-sensitive or insensitive comparison (true indicates a case-insensitive comparison).  String properties only.</param>
        public virtual VList<T> FindAllBy(FindAllByType findAllByType, string propertyName, object value, bool ignoreCase)
        {
            PropertyDescriptorCollection props = base.PropertyCollection;
            PropertyDescriptor searchBy = props.Find(propertyName, true);

            VList<T> result = new VList<T>();

            int index = 0;

            while (index > -1)
            {
                index = this.FindAllBy(findAllByType, searchBy, value, index, ignoreCase);

                if (index > -1)
                {
                    result.Add(this[index]);

                    //Increment the index to start at the next item
                    index++;
                }
            }

            return result;
        }
		
        /// <summary>
        /// Searches for the index of the item that has the specified property descriptor with the specified value.
        /// </summary>
        /// <param name="findAllByType"><see cref="FindAllByType" /> Type to easily search by</param>
        /// <param name="prop">The <see cref="PropertyDescriptor"> to search for.</see></param>
        /// <param name="key">The value of <i>property</i> to match.</param>
        /// <param name="start">The index in the list at which to start the search.</param>
        /// <param name="ignoreCase">Indicator of whether to perform a case-sensitive or case insensitive search (string properties only).</param>
        /// <returns>The zero-based index of the item that matches the property descriptor and contains the specified value. </returns>
        protected virtual int FindAllBy(FindAllByType findAllByType, PropertyDescriptor prop, object key, int start, bool ignoreCase)
        {
            // Simple iteration:
            for (int i = start; i < Count; i++)
            {

                T item = this[i];
                object temp = prop.GetValue(item);
                if ((key == null) && (temp == null))
                {
                    return i;
                }
                else if (temp is string)
                {
                    switch(findAllByType)
                    {
                        case FindAllByType.StartsWith:
                            {
                               if (temp.ToString().StartsWith(key.ToString(), ignoreCase == true ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture))
                                	return i;
                                break;
                            }
                        case FindAllByType.EndsWith:
                            {
                                if (temp.ToString().EndsWith(key.ToString(), ignoreCase == true ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture))
                                	return i;
                                break;
                            }
                        case FindAllByType.Contains:
                            {
                                if (temp.ToString().Contains(key.ToString()))
                                	return i;
                                break; 
                            }
                    }
                }
                else if (temp != null && temp.Equals(key))
                {
                    return i;
                }
            }
            return -1; // Not found
        }
	    
	    ///<summary>
	    /// Used to by FindAllBy method to all for easy searching.
	    /// </summary>
	    [Serializable]
	    public enum FindAllByType
	    {
	        /// <summary>
	        /// Starts with Value in List
	        /// </summary>
	        StartsWith,
	        
	        /// <summary>
	        /// Ends with Value in List
	        /// </summary>
	        EndsWith,
	        
	        /// <summary>
	        /// Contains Value in List
	        /// </summary>
	        Contains
	    }
        #endregion Find All By
      #endregion Find

   }
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Australia Australia
I have been awarded MVP (Visual C#) for year 2007, 2008, 2009. I am a Microsoft Certified Application Developer (C# .Net). I currently live in Melbourne, Australia. I am a co-founder and core developer of Pageflakes www.pageflakes.com and Founder of Simplexhub, a highly experienced software development company based in Melbourne Australia and Dhaka, Bangladesh. Simplexhub.
My BLOG http://www.geekswithblogs.net/shahed
http://msmvps.com/blogs/shahed/Default.aspx.

Comments and Discussions