Click here to Skip to main content
15,892,298 members
Articles / Hosted Services / Azure

Kerosene ORM: a dynamic, configuration-less and self-adaptive ORM for POCO objects supporting a SQL-like syntax from C#

Rate me:
Please Sign up or sign in to vote.
4.96/5 (71 votes)
1 Mar 2015CPOL35 min read 546.3K   4.6K   212  
The seventh version of the dynamic, configuration-less and self-adaptive Kerosene ORM library, that provides full real support for POCO objects, natural SQL-like syntax from C#, and advanced capabilities while being extremely easy to use.
// ======================================================== 
namespace Kerosene.Tools
{
	using System;
	using System.Reflection;

	// ==================================================== 
	/// <summary>
	/// Helpers and extensions for working with 'Type' objects and reflection.
	/// </summary>
	public static class TypeHelper
	{
		/// <summary>
		/// Returns a string with the C#-alike name of the given type.
		/// </summary>
		/// <param name="type">The type to get its easy name from.</param>
		/// <param name="withParentType">True to include the names from its parents' chain.</param>
		public static string EasyName(this Type type, bool withParentType = false)
		{
			if (type == null) throw new ArgumentNullException("type", "Type cannot be null.");

			var str = type.FullName; if (str == null) str = type.Name;
			var i = str.IndexOf('['); if (i >= 0) str = str.Substring(0, i);

			if (!withParentType)
			{
				i = str.LastIndexOf('.');
				if (i >= 0) str = str.Substring(i + 1);
			}

			str = str.Replace('+', '.'); // nested types

			i = str.IndexOf('`'); if (i >= 0) // generics
			{
				str = str.Substring(0, i);
				str += '<';

				var types = type.GetGenericArguments(); bool first = true; foreach (var temp in types)
				{
					if (first) first = false; else str += ", ";
					str += temp.EasyName(withParentType);
				}
				str += '>';
			}

			return str;
		}

		public const BindingFlags InstancePublicAndHidden = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
		public const BindingFlags PublicAndHidden = BindingFlags.Public | BindingFlags.NonPublic;
		public const BindingFlags Inherited = BindingFlags.FlattenHierarchy;
		public const BindingFlags InstanceAndStatic = BindingFlags.Instance | BindingFlags.Static;

		/// <summary>
		/// Non-exhaustive list of characters that cannot be used with multipart member names.
		/// </summary>
		public static char[] InvalidMultipartMemberChars
		{
			get { return _InvalidMultipartMemberChars.ToCharArray(); }
		}
		static readonly string _InvalidMultipartMemberChars = " /^%[]{}()!\"\\&=?¿+-*";

		/// <summary>
		/// Non-exhaustive list of characters that cannot be used with member names.
		/// </summary>
		public static char[] InvalidMemberChars
		{
			get { return _InvalidMemberChars.ToCharArray(); }
		}
		static readonly string _InvalidMemberChars = "." + _InvalidMultipartMemberChars;

		/// <summary>
		/// Returns whether this type is a nullable one or not.
		/// </summary>
		/// <param name="type">This type.</param>
		public static bool IsNullableType(this Type type)
		{
			if (type == null) throw new ArgumentNullException("type", "Type cannot be null.");

			Type generic = type.IsGenericType ? type.GetGenericTypeDefinition() : null;
			if (generic != null && generic.Equals(typeof(Nullable<>))) return true;

			if (type.IsClass) return true;
			if (type.IsValueType) return false;
			return false;
		}

		/// <summary>
		/// Returns, if possible, a cloned instance of the one given, or otherwise returns the original instance.
		/// </summary>
		/// <param name="source">The instance to clone.</param>
		/// <param name="tryExtended">True to try a parameterless 'Clone()' method even if the type is not ICloneable.</param>
		public static object TryClone(this object source, bool tryExtended = false)
		{
			if (source == null) return null;
			if (source is ICloneable) return ((ICloneable)source).Clone();

			if (tryExtended)
			{
				MethodInfo method = source.GetType().GetMethod("Clone", Type.EmptyTypes); if (method != null)
				{
					if (method.ReturnType == typeof(void)) return source;
					return method.Invoke(source, null);
				}
			}
			return source;
		}
	}
}
// ======================================================== 

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
Spain Spain
mbarbac has worked in start-ups, multinational tech companies, and consulting ones, serving as CIO, CTO, SW Development Director, and Consulting Director, among many other roles.

Solving complex puzzles and getting out of them business value has ever been among his main interests - and that's why he has spent his latest 25 years trying to combine his degree in Theoretical Physics with his MBA... and he is still trying to figure out how all these things can fit together.

Even if flying a lot across many countries, along with the long working days that are customary in IT management and Consultancy, he can say that, after all, he lives in Spain (at least the weekends).

Comments and Discussions