Click here to Skip to main content
15,887,267 members
Articles / Programming Languages / C#

Applied Use of LinFu/Cecil and Aspect-Oriented Programming Concepts - A Library

Rate me:
Please Sign up or sign in to vote.
4.88/5 (8 votes)
4 Sep 2008CPOL17 min read 35.1K   160   32  
A library of useful functionality using Aspect-Oriented Programming concepts, and implemented using the LinFu and Cecil.Mono projects/frameworks.
using System;
using System.Reflection;
using System.Drawing;
using System.Collections.Generic;
using System.IO;
using System.ComponentModel;
using System.Collections;
using System.Text;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;

using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC
{
	public static class Extensions
	{
		public static T2[] PlaceInArray<T1, T2>(this List<T1> list, TDelegatePlain<T1, T2> del) where T1 : class
		{
			T2[] results = new T2[list.Count];
			for (int n = 0; n < list.Count; n++)
			{
				T2 res = del(list[n]);
				results[n] = res;
			}
			return results;
		}

		public static T OnDemand<T>(ref T item) where T : class, new()
		{
			if (item == null)
				Interlocked.CompareExchange<T>(ref item, new T(), null);

			return item;
		}

		public static T1 PopulateIf<T1>(this T1 value, ref T1 varToCheck, TPopulate<T1> del)
		{
			if (value.Equals(varToCheck))
			{
				varToCheck = del();
			}
			return varToCheck;
		}
		
		public static TypeAndProperties GetTypeAndProperties(this Type t)
		{
			TypeAndProperties props = Lookups._typeAndPropertyMap[t];
			if (props == null)
			{
				props = new TypeAndProperties(t);
				Lookups._typeAndPropertyMap.AddOrSet(t, props);
			}
			return props;
		}

		public static PropInfo GetPropInfo(this Type t, string propertyName)
		{
			TypeAndProperties props = Lookups._typeAndPropertyMap[t];
			if (props == null)
			{
				props = new TypeAndProperties(t);
				Lookups._typeAndPropertyMap.AddOrSet(t, props);
			}
			return props.Lookup[propertyName];
		}

		public static void Apply<T>(this List<T> list, TDelegateGeneral<T> del) where T : class
		{
			for (int n = 0; n < list.Count; n++)
			{
				T entry = list[n];
				del(entry);
			}
		}

		public static string BuildList<T>(this List<T> items, StringBuilder sbReused, TDelegateGeneralString<T> del)
		{
			sbReused.Length = 0;
			if (items == null) return string.Empty;

			for (int n = 0; n < items.Count; n++)
			{
				if (n > 0) sbReused.Append(", ");
				string s = del(items[n]);
				if (!string.IsNullOrEmpty(s)) { sbReused.Append(s); }
			}
			return sbReused.ToString();
		}

		public static string BuildList<T>(this List<T> items, TDelegateGeneralString<T> del)
		{
			if (items == null) return string.Empty;
			StringBuilder sb = new StringBuilder();
			return items.BuildList(sb, del);
		}

		public static string BuildList<T>(this IEnumerable<T> items, TDelegateGeneralString<T> del) where T : class
		{
			if (items == null) return string.Empty;
			StringBuilder sb = new StringBuilder(1024);
			int n = 0;
			foreach (T item in items)
			{
				if (item == null) continue;
				if (n > 0) sb.Append(", ");
				string s = del(item);
				if (!string.IsNullOrEmpty(s)) { sb.Append(s); n++; }
			}
			return sb.ToString();
		}

		public static PropertyDescriptor IDProperty(this Type type)
		{
			string propName; PropertyDescriptor prop;
			if (Lookups._typeIDPropertyMap.TryGetValue(type, out prop)) { return prop; }
			propName = type.ReadPropertyValue<IDProperty, string>();
			prop = TypeDescriptor.GetProperties(type)[propName];
			Lookups._typeIDPropertyMap.AddOrSet(type, prop);
			return prop;
		}

		public static T CreateIfNull<T>(ref T item) where T : class, new()
		{
			if (item == null) { Interlocked.CompareExchange<T>(ref item, new T(), null); }
			return item;
		}

		public static T CreateIfNull<T>(ref T item, T value) where T : class
		{
			if (item == null) { Interlocked.CompareExchange<T>(ref item, value, null); }
			return item;
		}

		public static TInterface CreateIfNull<TInterface, TClass>(ref TInterface item)
			where TInterface : class
			where TClass : class, TInterface, new()
		{
			if (item == null) { Interlocked.CompareExchange<TInterface>(ref item, new TClass(), null); }
			return item;
		}

		public static bool ThrowIfFalse(this bool b)
		{
			if (!b) throw new Exception("Error - false");
			return true;
		}

		public static Thread CreateAndRunThread(this ThreadStart ts) { Thread t = CreateThread(ts); t.Start(); return t; }

		public static Thread CreateAndRunThread(this ThreadStart ts, bool isBackground) { Thread t = CreateThread(ts); t.IsBackground = isBackground; t.Start(); return t; }

		public static Thread CreateThread(this ThreadStart ts)
		{
			Thread t = new Thread(ts);
			t.TrySetApartmentState(ApartmentState.MTA);
			t.Priority = ThreadPriority.Normal;
			t.IsBackground = true;
			return t;
		}

		public static List<MethodInfo> ReadMethodInfoWithCustomAttribute<T1>(this Type t) where T1 : class, IReadableAttribute
		{
			// TODO: Cache this info?
			List<MethodInfo> results = new List<MethodInfo>();
			// TODO: private, etc?
			MethodInfo[] methods = t.GetMethods();
			foreach (MethodInfo method in methods)
			{
				T1[] attributes = method.ReadAttribute<T1>();

				if (attributes != null && attributes.Length > 0)
					results.Add(method);
			}

			return results;
		}

		public static List<PropertyInfo> ReadPropertyInfoWithCustomAttribute<T1>(this Type t) where T1 : class, IReadableAttribute
		{
			List<PropertyInfo> results = new List<PropertyInfo>();

			PropertyInfo[] props = t.GetProperties();
			foreach (PropertyInfo prop in props)
			{
				T1[] attributes = prop.ReadAttribute<T1>();

				if (attributes != null && attributes.Length > 0)
					results.Add(prop);
			}

			return results;
		}

		public static T1[] ReadAttribute<T1>(this MethodInfo t) where T1 : class, IReadableAttribute
		{
			ThreadSafeLookup<Type, object> lookup = Lookups.MethodInfoAttributeLookup.Get(t);
			Type t1Type = typeof(T1);

			object o;
			if (lookup.TryGetValue(t1Type, out o))
			{
				if (o == null)
					return null;

				return o as T1[];
			}

			object[] objs = t.GetCustomAttributes(typeof(T1), true);
			if (objs != null && objs.Length > 0)
			{
				T1[] results = new T1[objs.Length];

				for (int n = 0; n < objs.Length; n++)
					results[n] = objs[n] as T1;

				lookup.AddOrSet(t1Type, results);
				return results;
			}

			lookup.AddOrSet(t1Type, null);
			return null;
		}

		public static T1[] ReadAttribute<T1>(this PropertyInfo propInfo) where T1 : class, IReadableAttribute
		{
			ThreadSafeLookup<Type, object> lookup = Lookups.PropInfoAttributeLookup.Get(propInfo);
			Type t1Type = typeof(T1);

			object o;
			if (lookup.TryGetValue(t1Type, out o))
			{
				if (o == null)
					return null;

				return o as T1[];
			}

			object[] objs = propInfo.GetCustomAttributes(typeof(T1), true);
			if (objs != null && objs.Length > 0)
			{
				T1[] results = new T1[objs.Length];

				for (int n = 0; n < objs.Length; n++)
					results[n] = objs[n] as T1;

				lookup.AddOrSet(t1Type, results);
				return results;
			}

			lookup.AddOrSet(t1Type, null);
			return null;
		}

		public static T1[] ReadAttribute<T1>(this Type classType) where T1 : class, IReadableAttribute
		{
			ThreadSafeLookup<Type, object> lookup = Lookups.ClassInfoAttributeLookup.Get(classType);
			Type t1Type = typeof(T1);

			object o;
			if (lookup.TryGetValue(t1Type, out o))
			{
				if (o == null)
					return null;

				return o as T1[];
			}

			object[] objs = classType.GetCustomAttributes(typeof(T1), true);
			if (objs != null && objs.Length > 0)
			{
				T1[] results = new T1[objs.Length];

				for (int n = 0; n < objs.Length; n++)
					results[n] = objs[n] as T1;

				lookup.AddOrSet(t1Type, results);
				return results;
			}

			lookup.AddOrSet(t1Type, null);
			return null;
		}

		public static T2 ReadPropertyValue<T1, T2>(this Type t) where T1 : IReadableAttribute
		{
			object[] objs = t.GetCustomAttributes(typeof(T1), true);
			if (objs != null && objs.Length > 0)
			{
				T1 attr = (T1)objs[0];
				return (T2)attr.Value;
			}
			else { return default(T2); }
		}

		public static bool ContainsIgnoreCase(this List<string> list, string s)
		{
			for (int j = 0; j < list.Count; j++)
			{
				if (list[j].Equals(s, StringComparison.OrdinalIgnoreCase))
					return true;
			}
			return false;
		}
	}
}

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
Software Developer (Senior) Troppus Software
United States United States
Currently working as a Senior Silverlight Developer with Troppus Software in Superior, CO. I enjoy statistics, programming, new technology, playing the cello, and reading codeproject articles. Smile | :)

Comments and Discussions