Click here to Skip to main content
15,896,269 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 548.7K   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.
// ======================================================== TypeEx.cs
namespace Kerosene.Tools
{
	using System;
	using System.Reflection;
	using System.Runtime.CompilerServices;

	// ==================================================== 
	/// <summary>
	/// Helpers and extensions for working with <see cref="System.Type"/> instances.
	/// </summary>
	public static class TypeEx
	{
		/// <summary>
		/// Returns the C#-alike name of the type.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <param name="depth">The depth of the declaring chain to be included in the name of
		/// tye type:
		/// <para>- 0: only to include the name of the type.</para>
		/// <para>- 1: to also include the name of the namespace or type where it is declared.</para>
		/// <para>- n: include to the nth-level the names in the declaring chain.</para>
		/// <para>- Use 'int.MaxValue' to assure the full path is included.</para>
		/// </param>
		/// <param name="genericNames">True to include the names of the generic type arguments, if
		/// any, or false to leave them blank.</param>
		/// <returns>The C#-alike name of the given type.</returns>
		public static string EasyName(this Type type, int depth = 0, bool genericNames = false)
		{
			if (type == null) throw new NullReferenceException("Type cannot be null.");
			if (depth < 0) depth = -1 * depth;
			if (depth >= int.MaxValue) depth = int.MaxValue - 2;

			var str = type.FullName;
			if (str == null) str = genericNames ? type.Name : string.Empty;

			var i = str.IndexOf('[');
			if (i >= 0) str = str.Substring(0, i); // CLR decoration not C# compliant...

			var args = type.GetGenericArguments();
			var index = 0;
			var parts = str.Split(".+".ToCharArray()); for (int k = 0; k < parts.Length; k++)
			{
				i = parts[k].IndexOf('`'); if (i >= 0)
				{
					var temps = parts[k].Split("`".ToCharArray());
					parts[k] = temps[0] + "<";

					var num = int.Parse(temps[1]); for (int j = 0; j < num; j++)
					{
						if (j != 0) parts[k] += ",";

						var arg = args[index++];
						var name = arg.EasyName(depth, genericNames);

						if (name != string.Empty)
						{
							if (j != 0) parts[k] += " ";
							parts[k] += name;
						}
					}
					parts[k] += ">";
				}
			}

			int start = parts.Length - 1 - depth; if (start < 0) start = 0;
			int count = parts.Length - start;
			return string.Join(".", parts, start, count);
		}

		/// <summary>
		/// Returns whether the given type is nullable or not.
		/// </summary>
		/// <param name="type">The type to test.</param>
		/// <returns>True if the type is nullable, false otherwise.</returns>
		public static bool IsNullableType(this Type type)
		{
			if (type == null) throw new NullReferenceException("Type cannot be null.");

			if (type.IsClass) return true;

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

			return false;
		}

		/// <summary>
		/// Gets whether the given type is an anonymous one or not.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <returns>True if the given type is an anonymous one.</returns>
		public static bool IsAnonymousType(this Type type)
		{
			if (type == null) throw new NullReferenceException("Type cannot be null.");

			return type.IsNotPublic && Attribute.IsDefined(
				type,
				typeof(CompilerGeneratedAttribute),
				false);
		}

		/// <summary>
		/// Binding flags for elements that are public and hidden.
		/// </summary>
		public const BindingFlags PublicAndHidden = BindingFlags.Public | BindingFlags.NonPublic;

		/// <summary>
		/// Binding flags for instance elements that are public and hidden.
		/// </summary>
		public const BindingFlags InstancePublicAndHidden = BindingFlags.Instance | PublicAndHidden;

		/// <summary>
		/// Binding flags for instance and static elements.
		/// </summary>
		public const BindingFlags InstanceAndStatic = BindingFlags.Instance | BindingFlags.Static;
	}
}
// ======================================================== 

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