//******************************************************************************************************// FastObjectFactory.cs - Gbtc//// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may// not use this file except in compliance with the License. You may obtain a copy of the License at://// http://www.opensource.org/licenses/eclipse-1.0.php//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 01/25/2010 - James R. Carroll// Generated original version of source code.// 10/8/2012 - Danyelle Gilliam// Modified Header////****************************************************************************************************** using System;using System.Collections.Concurrent;using System.Reflection;using System.Reflection.Emit; namespace GSF{ /// <summary> /// Quickly creates new objects based on specified type. /// </summary> /// <typeparam name="T">Type of object to create quickly.</typeparam> /// <remarks> /// You can use the alternate <see cref="FastObjectFactory"/> implementation if you only have the <see cref="Type"/> of /// an object available (such as when you are using reflection). /// </remarks> public static class FastObjectFactory<T> where T : class, new() { // Static object creation delegate specific to type T - one instance will be created per type by the compiler private static Func<T> s_createObjectFunction; static FastObjectFactory() { // This is markedly faster than using Activator.CreateInstance Type type = typeof(T); DynamicMethod dynMethod = new DynamicMethod("ctor$" + type.Name, type, null, type); ILGenerator ilGen = dynMethod.GetILGenerator(); ilGen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); ilGen.Emit(OpCodes.Ret); s_createObjectFunction = (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>)); } /// <summary> /// Gets delegate that quickly creates new instance of the specfied type. /// </summary> public static Func<T> CreateObjectFunction { get { return s_createObjectFunction; } } } /// <summary> /// Quickly creates new objects based on specified type. /// </summary> /// <remarks> /// <see cref="FastObjectFactory"/> should be used when you only have the <see cref="Type"/> of an object available (such as when you are /// using reflection), otherwise you should use the generic <see cref="FastObjectFactory{T}"/>. /// </remarks> public static class FastObjectFactory { // We cache object creation functions by type so they are only created once private static ConcurrentDictionary<Type, Delegate> s_createObjectFunctions = new ConcurrentDictionary<Type, Delegate>(); /// <summary> /// Gets delegate that creates new instance of the <paramref name="type"/>. /// </summary> /// <param name="type">Type of object to create quickly.</param> /// <returns>Delegate to use to quickly create new objects.</returns> /// <exception cref="InvalidOperationException"><paramref name="type"/> does not support parameterless public constructor.</exception> public static Func<object> GetCreateObjectFunction(Type type) { return GetCreateObjectFunction<object>(type); } /// <summary> /// Gets delegate of specified return type that creates new instance of the <paramref name="type"/>. /// </summary> /// <param name="type">Type of object to create quickly.</param> /// <typeparam name="T">Type of returned object function used to create objects quickly.</typeparam> /// <returns>Delegate to use to quickly create new objects.</returns> /// <exception cref="InvalidOperationException"> /// <paramref name="type"/> does not support parameterless public constructor -or- /// <paramref name="type"/> is not a subclass or interface implementation of function type definition. /// </exception> /// <remarks> /// This function will validate that <typeparamref name="T"/> is related to <paramref name="type"/>. /// </remarks> public static Func<T> GetCreateObjectFunction<T>(Type type) { // Since user can call this function with any type, we verify that it is related to the return type. If return type // is a class, see if type derives from it, else if return type is an interface, see if type implements it. if (!type.IsAbstract && ( (typeof(T).IsClass && type.IsSubclassOf(typeof(T))) || (typeof(T).IsInterface && (object)type.GetInterface(typeof(T).Name) != null)) ) { return (Func<T>)s_createObjectFunctions.GetOrAdd(type, (objType) => { // Get parameterless constructor for this type ConstructorInfo typeCtor = objType.GetConstructor(Type.EmptyTypes); if ((object)typeCtor == null) throw new InvalidOperationException("Specified type parameter does not support parameterless public constructor"); // This is markedly faster than using Activator.CreateInstance DynamicMethod dynMethod = new DynamicMethod("ctor_type$" + objType.Name, objType, null, objType); ILGenerator ilGen = dynMethod.GetILGenerator(); ilGen.Emit(OpCodes.Newobj, typeCtor); ilGen.Emit(OpCodes.Ret); return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>)); }); } else throw new InvalidOperationException("Specified type parameter is not a subclass or interface implementation of function type definition"); } }}
//******************************************************************************************************
// FastObjectFactory.cs - Gbtc
//
// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 01/25/2010 - James R. Carroll
// Generated original version of source code.
// 10/8/2012 - Danyelle Gilliam
// Modified Header
//
//******************************************************************************************************
using System;
using System.Collections.Concurrent;
using System.Reflection;
using System.Reflection.Emit;
namespace GSF
{
/// <summary>
/// Quickly creates new objects based on specified type.
/// </summary>
/// <typeparam name="T">Type of object to create quickly.</typeparam>
/// <remarks>
/// You can use the alternate <see cref="FastObjectFactory"/> implementation if you only have the <see cref="Type"/> of
/// an object available (such as when you are using reflection).
/// </remarks>
public static class FastObjectFactory<T> where T : class, new()
{
// Static object creation delegate specific to type T - one instance will be created per type by the compiler
private static Func<T> s_createObjectFunction;
static FastObjectFactory()
{
// This is markedly faster than using Activator.CreateInstance
Type type = typeof(T);
DynamicMethod dynMethod = new DynamicMethod("ctor$" + type.Name, type, null, type);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
ilGen.Emit(OpCodes.Ret);
s_createObjectFunction = (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));
}
/// <summary>
/// Gets delegate that quickly creates new instance of the specfied type.
/// </summary>
public static Func<T> CreateObjectFunction
{
get
{
return s_createObjectFunction;
}
}
}
/// <summary>
/// Quickly creates new objects based on specified type.
/// </summary>
/// <remarks>
/// <see cref="FastObjectFactory"/> should be used when you only have the <see cref="Type"/> of an object available (such as when you are
/// using reflection), otherwise you should use the generic <see cref="FastObjectFactory{T}"/>.
/// </remarks>
public static class FastObjectFactory
{
// We cache object creation functions by type so they are only created once
private static ConcurrentDictionary<Type, Delegate> s_createObjectFunctions = new ConcurrentDictionary<Type, Delegate>();
/// <summary>
/// Gets delegate that creates new instance of the <paramref name="type"/>.
/// </summary>
/// <param name="type">Type of object to create quickly.</param>
/// <returns>Delegate to use to quickly create new objects.</returns>
/// <exception cref="InvalidOperationException"><paramref name="type"/> does not support parameterless public constructor.</exception>
public static Func<object> GetCreateObjectFunction(Type type)
{
return GetCreateObjectFunction<object>(type);
}
/// <summary>
/// Gets delegate of specified return type that creates new instance of the <paramref name="type"/>.
/// </summary>
/// <param name="type">Type of object to create quickly.</param>
/// <typeparam name="T">Type of returned object function used to create objects quickly.</typeparam>
/// <returns>Delegate to use to quickly create new objects.</returns>
/// <exception cref="InvalidOperationException">
/// <paramref name="type"/> does not support parameterless public constructor -or-
/// <paramref name="type"/> is not a subclass or interface implementation of function type definition.
/// </exception>
/// <remarks>
/// This function will validate that <typeparamref name="T"/> is related to <paramref name="type"/>.
/// </remarks>
public static Func<T> GetCreateObjectFunction<T>(Type type)
{
// Since user can call this function with any type, we verify that it is related to the return type. If return type
// is a class, see if type derives from it, else if return type is an interface, see if type implements it.
if (!type.IsAbstract &&
(
(typeof(T).IsClass && type.IsSubclassOf(typeof(T))) ||
(typeof(T).IsInterface && (object)type.GetInterface(typeof(T).Name) != null))
)
{
return (Func<T>)s_createObjectFunctions.GetOrAdd(type, (objType) =>
{
// Get parameterless constructor for this type
ConstructorInfo typeCtor = objType.GetConstructor(Type.EmptyTypes);
if ((object)typeCtor == null)
throw new InvalidOperationException("Specified type parameter does not support parameterless public constructor");
// This is markedly faster than using Activator.CreateInstance
DynamicMethod dynMethod = new DynamicMethod("ctor_type$" + objType.Name, objType, null, objType);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, typeCtor);
ilGen.Emit(OpCodes.Ret);
return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));
});
}
else
throw new InvalidOperationException("Specified type parameter is not a subclass or interface implementation of function type definition");
}
}
}