diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs b/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs index 6bfc3a77..43f4d0d9 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/SimpleInstantiationStrategy.cs @@ -1,5 +1,5 @@ -#region License - +#region License + /* * Copyright © 2002-2005 the original author or authors. * @@ -14,294 +14,297 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ - -#endregion - -#region Imports - -using System; -using System.Globalization; -using System.Reflection; - -using Common.Logging; -using Spring.Core; -using Spring.Core.TypeResolution; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Support -{ - /// - /// Simple object instantiation strategy for use in - /// implementations. - /// - /// - ///

- /// Does not support method injection, although it provides hooks for subclasses - /// to override to add method injection support, for example by overriding methods. - ///

- ///
- /// Rod Johnson - /// Rick Evans (.NET) - /// - [Serializable] - public class SimpleInstantiationStrategy : IInstantiationStrategy - { - /// - /// The shared instance for this class (and derived classes). - /// - protected static readonly ILog log = - LogManager.GetLogger(typeof (SimpleInstantiationStrategy)); - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory) - { - AssertUtils.ArgumentNotNull(definition, "definition"); - AssertUtils.ArgumentNotNull(factory, "factory"); - if (definition.HasMethodOverrides) - { - return InstantiateWithMethodInjection(definition, name, factory); - } - else - { - Type objectType = definition.HasObjectType - ? definition.ObjectType - : TypeResolutionUtils.ResolveType(definition.ObjectTypeName); - ConstructorInfo constructor = GetZeroArgConstructorInfo(objectType); - return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); - } - } - - /// - /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. - /// - /// The type. - /// Zero argument ConstructorInfo - /// - /// If the type does not have a zero-arg constructor. - /// - private ConstructorInfo GetZeroArgConstructorInfo(Type type) - { - const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.Instance | BindingFlags.DeclaredOnly; - - ConstructorInfo constructor = type.GetConstructor(flags, null, Type.EmptyTypes, null); - if (constructor == null) - { - throw new FatalReflectionException(string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a no-argument constructor [{0}].", type)); - } - return constructor; - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - ConstructorInfo constructor, object[] arguments) - { - if (definition.HasMethodOverrides) - { - return InstantiateWithMethodInjection(definition, name, factory, constructor, arguments); - } - else - { - return ObjectUtils.InstantiateType(constructor, arguments); - } - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied . - /// - /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to get the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - public virtual object Instantiate( - RootObjectDefinition definition, string name, IObjectFactory factory, - MethodInfo factoryMethod, object[] arguments) - { - object instance = null; - object target = null; - if (StringUtils.HasText(definition.FactoryObjectName)) - { - target = factory[definition.FactoryObjectName]; - } - try - { - // the target will be null if using a static factory method - instance = factoryMethod.Invoke(target, arguments); - } - catch (TargetInvocationException ex) - { - string msg = string.Format( - CultureInfo.InvariantCulture, - "Factory method '{0}' threw an Exception.", factoryMethod); - - #region Instrumentation - - if (log.IsWarnEnabled) - { - log.Warn(msg, ex.InnerException); - } - - #endregion - - throw new ObjectDefinitionStoreException(msg, ex.InnerException); - } - catch (Exception ex) - { - throw new ObjectDefinitionStoreException(string.Format( - CultureInfo.InvariantCulture, - "Factory method '{0}' threw an Exception.", factoryMethod), ex); - } - return instance; - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - ///

- /// The default implementation of this method is to throw a - /// . - ///

- ///

- /// Derived classes can override this method if they can instantiate an object - /// with the Method Injection specified in the supplied - /// . Instantiation should use a no-arg constructor. - ///

- ///
- /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be a - /// or zero length string if we're autowiring an object that - /// doesn't belong to the supplied . - /// - /// - /// The owning - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - protected virtual object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory) - { - throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); - } - - /// - /// Instantiate an instance of the object described by the supplied - /// from the supplied , - /// injecting methods as appropriate. - /// - /// - ///

- /// The default implementation of this method is to throw a - /// . - ///

- ///

- /// Derived classes can override this method if they can instantiate an object - /// with the Method Injection specified in the supplied - /// . Instantiation should use the supplied - /// and attendant . - ///

- ///
- /// - /// The definition of the object that is to be instantiated. - /// - /// - /// The name associated with the object definition. The name can be the null - /// or zero length string if we're autowiring an object that doesn't belong - /// to the supplied . - /// - /// - /// The owning - /// - /// - /// The to be used to instantiate - /// the object. - /// - /// - /// Any arguments to the supplied . May be null. - /// - /// - /// An instance of the object described by the supplied - /// from the supplied . - /// - protected virtual object InstantiateWithMethodInjection( - RootObjectDefinition definition, string objectName, IObjectFactory factory, - ConstructorInfo constructor, object[] arguments) - { - throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); - } - } + */ + +#endregion + +#region Imports + +using System; +using System.Globalization; +using System.Reflection; + +using Common.Logging; +using Spring.Core; +using Spring.Core.TypeResolution; +using Spring.Util; + +#endregion + +namespace Spring.Objects.Factory.Support +{ + /// + /// Simple object instantiation strategy for use in + /// implementations. + /// + /// + ///

+ /// Does not support method injection, although it provides hooks for subclasses + /// to override to add method injection support, for example by overriding methods. + ///

+ ///
+ /// Rod Johnson + /// Rick Evans (.NET) + /// + [Serializable] + public class SimpleInstantiationStrategy : IInstantiationStrategy + { + /// + /// The shared instance for this class (and derived classes). + /// + protected static readonly ILog log = + LogManager.GetLogger(typeof(SimpleInstantiationStrategy)); + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory) + { + AssertUtils.ArgumentNotNull(definition, "definition"); + AssertUtils.ArgumentNotNull(factory, "factory"); + + if (log.IsTraceEnabled) log.Trace(string.Format("instantiating object '{0}'", name)); + + if (definition.HasMethodOverrides) + { + return InstantiateWithMethodInjection(definition, name, factory); + } + else + { + Type objectType = definition.HasObjectType + ? definition.ObjectType + : TypeResolutionUtils.ResolveType(definition.ObjectTypeName); + ConstructorInfo constructor = GetZeroArgConstructorInfo(objectType); + return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); + } + } + + /// + /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. + /// + /// The type. + /// Zero argument ConstructorInfo + /// + /// If the type does not have a zero-arg constructor. + /// + private ConstructorInfo GetZeroArgConstructorInfo(Type type) + { + const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Instance | BindingFlags.DeclaredOnly; + + ConstructorInfo constructor = type.GetConstructor(flags, null, Type.EmptyTypes, null); + if (constructor == null) + { + throw new FatalReflectionException(string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a no-argument constructor [{0}].", type)); + } + return constructor; + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + ConstructorInfo constructor, object[] arguments) + { + if (definition.HasMethodOverrides) + { + return InstantiateWithMethodInjection(definition, name, factory, constructor, arguments); + } + else + { + return ObjectUtils.InstantiateType(constructor, arguments); + } + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied . + /// + /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to get the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + public virtual object Instantiate( + RootObjectDefinition definition, string name, IObjectFactory factory, + MethodInfo factoryMethod, object[] arguments) + { + object instance = null; + object target = null; + if (StringUtils.HasText(definition.FactoryObjectName)) + { + target = factory[definition.FactoryObjectName]; + } + try + { + // the target will be null if using a static factory method + instance = factoryMethod.Invoke(target, arguments); + } + catch (TargetInvocationException ex) + { + string msg = string.Format( + CultureInfo.InvariantCulture, + "Factory method '{0}' threw an Exception.", factoryMethod); + + #region Instrumentation + + if (log.IsWarnEnabled) + { + log.Warn(msg, ex.InnerException); + } + + #endregion + + throw new ObjectDefinitionStoreException(msg, ex.InnerException); + } + catch (Exception ex) + { + throw new ObjectDefinitionStoreException(string.Format( + CultureInfo.InvariantCulture, + "Factory method '{0}' threw an Exception.", factoryMethod), ex); + } + return instance; + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + ///

+ /// The default implementation of this method is to throw a + /// . + ///

+ ///

+ /// Derived classes can override this method if they can instantiate an object + /// with the Method Injection specified in the supplied + /// . Instantiation should use a no-arg constructor. + ///

+ ///
+ /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be a + /// or zero length string if we're autowiring an object that + /// doesn't belong to the supplied . + /// + /// + /// The owning + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + protected virtual object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory) + { + throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); + } + + /// + /// Instantiate an instance of the object described by the supplied + /// from the supplied , + /// injecting methods as appropriate. + /// + /// + ///

+ /// The default implementation of this method is to throw a + /// . + ///

+ ///

+ /// Derived classes can override this method if they can instantiate an object + /// with the Method Injection specified in the supplied + /// . Instantiation should use the supplied + /// and attendant . + ///

+ ///
+ /// + /// The definition of the object that is to be instantiated. + /// + /// + /// The name associated with the object definition. The name can be the null + /// or zero length string if we're autowiring an object that doesn't belong + /// to the supplied . + /// + /// + /// The owning + /// + /// + /// The to be used to instantiate + /// the object. + /// + /// + /// Any arguments to the supplied . May be null. + /// + /// + /// An instance of the object described by the supplied + /// from the supplied . + /// + protected virtual object InstantiateWithMethodInjection( + RootObjectDefinition definition, string objectName, IObjectFactory factory, + ConstructorInfo constructor, object[] arguments) + { + throw new InvalidOperationException("Method Injection not supported in SimpleInstantiationStrategy"); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Util/ObjectUtils.cs b/src/Spring/Spring.Core/Util/ObjectUtils.cs index 8d6141fe..aff8494f 100644 --- a/src/Spring/Spring.Core/Util/ObjectUtils.cs +++ b/src/Spring/Spring.Core/Util/ObjectUtils.cs @@ -1,5 +1,5 @@ -#region License - +#region License + /* * Copyright © 2002-2005 the original author or authors. * @@ -14,478 +14,486 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ - -#endregion - -#region Imports - -using System; -using System.Collections; -using System.Globalization; -using System.Reflection; -using System.Runtime.Remoting; -using Spring.Objects; - -#endregion - -namespace Spring.Util -{ - /// - /// Helper methods with regard to objects, types, properties, etc. - /// - /// - ///

- /// Not intended to be used directly by applications. - ///

- ///
- /// Rod Johnson - /// Juergen Hoeller - /// Rick Evans (.NET) - public sealed class ObjectUtils - { - #region Constants - - /// - /// An empty object array. - /// - public static readonly object[] EmptyObjects = new object[] {}; - - #endregion - - #region Constructor (s) / Destructor - - // CLOVER:OFF - - /// - /// Creates a new instance of the class. - /// - /// - ///

- /// This is a utility class, and as such exposes no public constructors. - ///

- ///
- private ObjectUtils() - { - } - - // CLOVER:ON - - #endregion - - #region Methods - - /// - /// Instantiates the type using the assembly specified to load the type. - /// - /// This is a convenience in the case of needing to instantiate a type but not - /// wanting to specify in the string the version, culture and public key token. - /// The assembly. - /// Name of the type. - /// - /// - /// If the or is - /// - /// - /// If cannot load the type from the assembly or the call to InstantiateType(Type) fails. - /// - public static object InstantiateType(Assembly assembly, string typeName) - { - AssertUtils.ArgumentNotNull(assembly, "assembly"); - AssertUtils.ArgumentNotNull(typeName, "typeName"); - Type resolvedType = assembly.GetType(typeName, false, false); - if (resolvedType == null) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot load type named [{0}] from assembly [{1}].", typeName, assembly)); - } - return InstantiateType(resolvedType); - } - /// - /// Convenience method to instantiate a using - /// its no-arg constructor. - /// - /// - ///

- /// As this method doesn't try to instantiate s - /// by name, it should avoid loading issues. - ///

- ///
- /// - /// The to instantiate* - /// - /// A new instance of the . - /// - /// If the is - /// - /// - /// If the is an abstract class, an interface, - /// an open generic type or does not have a public no-argument constructor. - /// - public static object InstantiateType(Type type) - { - AssertUtils.ArgumentNotNull(type, "type"); - - ConstructorInfo constructor = GetZeroArgConstructorInfo(type); - return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); - } - - /// - /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. - /// - /// The type. - /// Zero argument ConstructorInfo - /// - /// If the type is an interface, abstract, open generic type, or does not have a zero-arg constructor. - /// - public static ConstructorInfo GetZeroArgConstructorInfo(Type type) - { - IsInstantiable(type); - ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); - if (constructor == null) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a public no-argument constructor [{0}].", type)); - } - return constructor; - } - - /// - /// Determines whether the specified type is instantiable, i.e. not an interface, abstract class or contains - /// open generic type parameters. - /// - /// The type. - public static void IsInstantiable(Type type) - { - if (type.IsInterface) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", type)); - } - if (type.IsAbstract) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", type)); - } -#if NET_2_0 - if (type.ContainsGenericParameters) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", type)); - } -#endif - } - - /// - /// Convenience method to instantiate a using - /// the given constructor. - /// - /// - ///

- /// As this method doesn't try to instantiate s - /// by name, it should avoid loading issues. - ///

- ///
- /// - /// The constructor to use for the instantiation. - /// - /// - /// The arguments to be passed to the constructor. - /// - /// A new instance. - /// - /// If the is - /// - /// - /// If the 's declaring type is an abstract class, - /// an interface, an open generic type or does not have a public no-argument constructor. - /// - public static object InstantiateType(ConstructorInfo constructor, object[] arguments) - { - AssertUtils.ArgumentNotNull(constructor, "constructor"); - - if (constructor.DeclaringType.IsInterface) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", constructor.DeclaringType)); - } - if (constructor.DeclaringType.IsAbstract) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", constructor.DeclaringType)); - } -#if NET_2_0 - if (constructor.DeclaringType.ContainsGenericParameters) - { - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", constructor.DeclaringType)); - } -#endif - try - { - return constructor.Invoke(arguments); - } - catch (Exception ex) - { - Type ctorType = constructor.DeclaringType; - throw new FatalReflectionException( - string.Format( - CultureInfo.InvariantCulture, - "Cannot instantiate Type [{0}] using ctor [{1}] : '{2}'", - constructor.DeclaringType, constructor, ex.Message), - ex); - } - } - - /// - /// Checks whether the supplied is not a transparent proxy and is - /// assignable to the supplied . - /// - /// - ///

- /// Neccessary when dealing with server-activated remote objects, because the - /// object is of the type TransparentProxy and regular is testing for assignable - /// types does not work. - ///

- ///

- /// Transparent proxy instances always return when tested - /// with the 'is' operator (C#). This method only checks if the object - /// is assignable to the type if it is not a transparent proxy. - ///

- ///
- /// The target to be checked. - /// The value that should be assigned to the type. - /// - /// if the supplied is not a - /// transparent proxy and is assignable to the supplied . - /// - public static bool IsAssignableAndNotTransparentProxy(Type type, object instance) - { - if (!RemotingServices.IsTransparentProxy(instance)) - { - return IsAssignable(type, instance); - } - return false; - } - - /// - /// Determine if the given is assignable from the - /// given value, assuming setting by reflection. - /// - /// - ///

- /// Considers primitive wrapper classes as assignable to the - /// corresponding primitive types. - ///

- ///

- /// For example used in an object factory's constructor resolution. - ///

- ///
- /// The target . - /// The value that should be assigned to the type. - /// True if the type is assignable from the value. - public static bool IsAssignable(Type type, object obj) - { - return (type.IsInstanceOfType(obj) || - (!type.IsPrimitive && obj == null) || - (type.Equals(typeof (bool)) && obj is Boolean) || - (type.Equals(typeof (byte)) && obj is Byte) || - (type.Equals(typeof (char)) && obj is Char) || - (type.Equals(typeof (sbyte)) && obj is SByte) || - (type.Equals(typeof (int)) && obj is Int32) || - (type.Equals(typeof (short)) && obj is Int16) || - (type.Equals(typeof (long)) && obj is Int64) || - (type.Equals(typeof (float)) && obj is Single) || - (type.Equals(typeof (double)) && obj is Double)); - } - - /// - /// Check if the given represents a - /// "simple" property, - /// i.e. a primitive, a , a - /// , or a corresponding array. - /// - /// - ///

- /// Used to determine properties to check for a "simple" dependency-check. - ///

- ///
- /// - /// The to check. - /// - public static bool IsSimpleProperty(Type type) - { - return type.IsPrimitive - || type.Equals(typeof (string)) - || type.Equals(typeof (string[])) - || IsPrimitiveArray(type) - || type.Equals(typeof (Type)) - || type.Equals(typeof (Type[])); - } - - /// - /// Check if the given class represents a primitive array, - /// i.e. boolean, byte, char, short, int, long, float, or double. - /// - public static bool IsPrimitiveArray(Type type) - { - return typeof (bool[]).Equals(type) - || typeof (sbyte[]).Equals(type) - || typeof (char[]).Equals(type) - || typeof (short[]).Equals(type) - || typeof (int[]).Equals(type) - || typeof (long[]).Equals(type) - || typeof (float[]).Equals(type) - || typeof (double[]).Equals(type); - } - - /// - /// Determine if the given objects are equal, returning - /// if both are respectively - /// if only one is . - /// - /// The first object to compare. - /// The second object to compare. - /// - /// if the given objects are equal. - /// - public static bool NullSafeEquals(object o1, object o2) - { - return (o1 == o2 || (o1 != null && o1.Equals(o2))); - } - - /// - /// Returns the first element in the supplied . - /// - /// - /// The to use to enumerate - /// elements. - /// - /// - /// The first element in the supplied . - /// - /// - /// If the supplied did not have any elements. - /// - public static object EnumerateFirstElement(IEnumerator enumerator) - { - return ObjectUtils.EnumerateElementAtIndex(enumerator, 0); - } - - /// - /// Returns the first element in the supplied . - /// - /// - /// The to use to enumerate - /// elements. - /// - /// - /// The first element in the supplied . - /// - /// - /// If the supplied did not have any elements. - /// - /// - /// If the supplied is . - /// - public static object EnumerateFirstElement(IEnumerable enumerable) - { - AssertUtils.ArgumentNotNull(enumerable, "enumerable"); - return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), 0); - } - - /// - /// Returns the element at the specified index using the supplied - /// . - /// - /// - /// The to use to enumerate - /// elements until the supplied is reached. - /// - /// - /// The index of the element in the enumeration to return. - /// - /// - /// The element at the specified index using the supplied - /// . - /// - /// - /// If the supplied was less than zero, or the - /// supplied did not contain enough elements - /// to be able to reach the supplied . - /// - public static object EnumerateElementAtIndex(IEnumerator enumerator, int index) - { - if (index < 0) - { - throw new ArgumentOutOfRangeException(); - } - object element = null; - int i = 0; - while (enumerator.MoveNext()) - { - element = enumerator.Current; - if (++i > index) - { - break; - } - } - if (i < index) - { - throw new ArgumentOutOfRangeException(); - } - return element; - } - - /// - /// Returns the element at the specified index using the supplied - /// . - /// - /// - /// The to use to enumerate - /// elements until the supplied is reached. - /// - /// - /// The index of the element in the enumeration to return. - /// - /// - /// The element at the specified index using the supplied - /// . - /// - /// - /// If the supplied was less than zero, or the - /// supplied did not contain enough elements - /// to be able to reach the supplied . - /// - /// - /// If the supplied is . - /// - public static object EnumerateElementAtIndex(IEnumerable enumerable, int index) - { - AssertUtils.ArgumentNotNull(enumerable, "enumerable"); - return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), index); - } - - #endregion - - /// - /// Gets the qualified name of the given method, consisting of - /// fully qualified interface/class name + "." method name. - /// - /// The method. - /// qualified name of the method. - public static string GetQualifiedMethodName(MethodInfo method) - { - AssertUtils.ArgumentNotNull(method,"method", "MethodInfo must not be null"); - return method.DeclaringType.FullName + "." + method.Name; - } - } + */ + +#endregion + +#region Imports + +using System; +using System.Collections; +using System.Globalization; +using System.Reflection; +using System.Runtime.Remoting; +using Common.Logging; +using Spring.Objects; + +#endregion + +namespace Spring.Util +{ + /// + /// Helper methods with regard to objects, types, properties, etc. + /// + /// + ///

+ /// Not intended to be used directly by applications. + ///

+ ///
+ /// Rod Johnson + /// Juergen Hoeller + /// Rick Evans (.NET) + public sealed class ObjectUtils + { + /// + /// The instance for this class. + /// + private static readonly ILog log = LogManager.GetLogger(typeof(ObjectUtils)); + + #region Constants + + /// + /// An empty object array. + /// + public static readonly object[] EmptyObjects = new object[] { }; + + #endregion + + #region Constructor (s) / Destructor + + // CLOVER:OFF + + /// + /// Creates a new instance of the class. + /// + /// + ///

+ /// This is a utility class, and as such exposes no public constructors. + ///

+ ///
+ private ObjectUtils() + { + } + + // CLOVER:ON + + #endregion + + #region Methods + + /// + /// Instantiates the type using the assembly specified to load the type. + /// + /// This is a convenience in the case of needing to instantiate a type but not + /// wanting to specify in the string the version, culture and public key token. + /// The assembly. + /// Name of the type. + /// + /// + /// If the or is + /// + /// + /// If cannot load the type from the assembly or the call to InstantiateType(Type) fails. + /// + public static object InstantiateType(Assembly assembly, string typeName) + { + AssertUtils.ArgumentNotNull(assembly, "assembly"); + AssertUtils.ArgumentNotNull(typeName, "typeName"); + Type resolvedType = assembly.GetType(typeName, false, false); + if (resolvedType == null) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot load type named [{0}] from assembly [{1}].", typeName, assembly)); + } + return InstantiateType(resolvedType); + } + /// + /// Convenience method to instantiate a using + /// its no-arg constructor. + /// + /// + ///

+ /// As this method doesn't try to instantiate s + /// by name, it should avoid loading issues. + ///

+ ///
+ /// + /// The to instantiate* + /// + /// A new instance of the . + /// + /// If the is + /// + /// + /// If the is an abstract class, an interface, + /// an open generic type or does not have a public no-argument constructor. + /// + public static object InstantiateType(Type type) + { + AssertUtils.ArgumentNotNull(type, "type"); + + ConstructorInfo constructor = GetZeroArgConstructorInfo(type); + return ObjectUtils.InstantiateType(constructor, ObjectUtils.EmptyObjects); + } + + /// + /// Gets the zero arg ConstructorInfo object, if the type offers such functionality. + /// + /// The type. + /// Zero argument ConstructorInfo + /// + /// If the type is an interface, abstract, open generic type, or does not have a zero-arg constructor. + /// + public static ConstructorInfo GetZeroArgConstructorInfo(Type type) + { + IsInstantiable(type); + ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); + if (constructor == null) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate a class that does not have a public no-argument constructor [{0}].", type)); + } + return constructor; + } + + /// + /// Determines whether the specified type is instantiable, i.e. not an interface, abstract class or contains + /// open generic type parameters. + /// + /// The type. + public static void IsInstantiable(Type type) + { + if (type.IsInterface) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", type)); + } + if (type.IsAbstract) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", type)); + } +#if NET_2_0 + if (type.ContainsGenericParameters) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", type)); + } +#endif + } + + /// + /// Convenience method to instantiate a using + /// the given constructor. + /// + /// + ///

+ /// As this method doesn't try to instantiate s + /// by name, it should avoid loading issues. + ///

+ ///
+ /// + /// The constructor to use for the instantiation. + /// + /// + /// The arguments to be passed to the constructor. + /// + /// A new instance. + /// + /// If the is + /// + /// + /// If the 's declaring type is an abstract class, + /// an interface, an open generic type or does not have a public no-argument constructor. + /// + public static object InstantiateType(ConstructorInfo constructor, object[] arguments) + { + AssertUtils.ArgumentNotNull(constructor, "constructor"); + + if (log.IsTraceEnabled) log.Trace(string.Format("instantiating type [{0}] using constructor [{1}]", constructor.DeclaringType, constructor)); + + if (constructor.DeclaringType.IsInterface) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an interface [{0}].", constructor.DeclaringType)); + } + if (constructor.DeclaringType.IsAbstract) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an abstract class [{0}].", constructor.DeclaringType)); + } +#if NET_2_0 + if (constructor.DeclaringType.ContainsGenericParameters) + { + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, "Cannot instantiate an open generic type [{0}].", constructor.DeclaringType)); + } +#endif + try + { + return constructor.Invoke(arguments); + } + catch (Exception ex) + { + Type ctorType = constructor.DeclaringType; + throw new FatalReflectionException( + string.Format( + CultureInfo.InvariantCulture, + "Cannot instantiate Type [{0}] using ctor [{1}] : '{2}'", + constructor.DeclaringType, constructor, ex.Message), + ex); + } + } + + /// + /// Checks whether the supplied is not a transparent proxy and is + /// assignable to the supplied . + /// + /// + ///

+ /// Neccessary when dealing with server-activated remote objects, because the + /// object is of the type TransparentProxy and regular is testing for assignable + /// types does not work. + ///

+ ///

+ /// Transparent proxy instances always return when tested + /// with the 'is' operator (C#). This method only checks if the object + /// is assignable to the type if it is not a transparent proxy. + ///

+ ///
+ /// The target to be checked. + /// The value that should be assigned to the type. + /// + /// if the supplied is not a + /// transparent proxy and is assignable to the supplied . + /// + public static bool IsAssignableAndNotTransparentProxy(Type type, object instance) + { + if (!RemotingServices.IsTransparentProxy(instance)) + { + return IsAssignable(type, instance); + } + return false; + } + + /// + /// Determine if the given is assignable from the + /// given value, assuming setting by reflection. + /// + /// + ///

+ /// Considers primitive wrapper classes as assignable to the + /// corresponding primitive types. + ///

+ ///

+ /// For example used in an object factory's constructor resolution. + ///

+ ///
+ /// The target . + /// The value that should be assigned to the type. + /// True if the type is assignable from the value. + public static bool IsAssignable(Type type, object obj) + { + return (type.IsInstanceOfType(obj) || + (!type.IsPrimitive && obj == null) || + (type.Equals(typeof(bool)) && obj is Boolean) || + (type.Equals(typeof(byte)) && obj is Byte) || + (type.Equals(typeof(char)) && obj is Char) || + (type.Equals(typeof(sbyte)) && obj is SByte) || + (type.Equals(typeof(int)) && obj is Int32) || + (type.Equals(typeof(short)) && obj is Int16) || + (type.Equals(typeof(long)) && obj is Int64) || + (type.Equals(typeof(float)) && obj is Single) || + (type.Equals(typeof(double)) && obj is Double)); + } + + /// + /// Check if the given represents a + /// "simple" property, + /// i.e. a primitive, a , a + /// , or a corresponding array. + /// + /// + ///

+ /// Used to determine properties to check for a "simple" dependency-check. + ///

+ ///
+ /// + /// The to check. + /// + public static bool IsSimpleProperty(Type type) + { + return type.IsPrimitive + || type.Equals(typeof(string)) + || type.Equals(typeof(string[])) + || IsPrimitiveArray(type) + || type.Equals(typeof(Type)) + || type.Equals(typeof(Type[])); + } + + /// + /// Check if the given class represents a primitive array, + /// i.e. boolean, byte, char, short, int, long, float, or double. + /// + public static bool IsPrimitiveArray(Type type) + { + return typeof(bool[]).Equals(type) + || typeof(sbyte[]).Equals(type) + || typeof(char[]).Equals(type) + || typeof(short[]).Equals(type) + || typeof(int[]).Equals(type) + || typeof(long[]).Equals(type) + || typeof(float[]).Equals(type) + || typeof(double[]).Equals(type); + } + + /// + /// Determine if the given objects are equal, returning + /// if both are respectively + /// if only one is . + /// + /// The first object to compare. + /// The second object to compare. + /// + /// if the given objects are equal. + /// + public static bool NullSafeEquals(object o1, object o2) + { + return (o1 == o2 || (o1 != null && o1.Equals(o2))); + } + + /// + /// Returns the first element in the supplied . + /// + /// + /// The to use to enumerate + /// elements. + /// + /// + /// The first element in the supplied . + /// + /// + /// If the supplied did not have any elements. + /// + public static object EnumerateFirstElement(IEnumerator enumerator) + { + return ObjectUtils.EnumerateElementAtIndex(enumerator, 0); + } + + /// + /// Returns the first element in the supplied . + /// + /// + /// The to use to enumerate + /// elements. + /// + /// + /// The first element in the supplied . + /// + /// + /// If the supplied did not have any elements. + /// + /// + /// If the supplied is . + /// + public static object EnumerateFirstElement(IEnumerable enumerable) + { + AssertUtils.ArgumentNotNull(enumerable, "enumerable"); + return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), 0); + } + + /// + /// Returns the element at the specified index using the supplied + /// . + /// + /// + /// The to use to enumerate + /// elements until the supplied is reached. + /// + /// + /// The index of the element in the enumeration to return. + /// + /// + /// The element at the specified index using the supplied + /// . + /// + /// + /// If the supplied was less than zero, or the + /// supplied did not contain enough elements + /// to be able to reach the supplied . + /// + public static object EnumerateElementAtIndex(IEnumerator enumerator, int index) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException(); + } + object element = null; + int i = 0; + while (enumerator.MoveNext()) + { + element = enumerator.Current; + if (++i > index) + { + break; + } + } + if (i < index) + { + throw new ArgumentOutOfRangeException(); + } + return element; + } + + /// + /// Returns the element at the specified index using the supplied + /// . + /// + /// + /// The to use to enumerate + /// elements until the supplied is reached. + /// + /// + /// The index of the element in the enumeration to return. + /// + /// + /// The element at the specified index using the supplied + /// . + /// + /// + /// If the supplied was less than zero, or the + /// supplied did not contain enough elements + /// to be able to reach the supplied . + /// + /// + /// If the supplied is . + /// + public static object EnumerateElementAtIndex(IEnumerable enumerable, int index) + { + AssertUtils.ArgumentNotNull(enumerable, "enumerable"); + return ObjectUtils.EnumerateElementAtIndex(enumerable.GetEnumerator(), index); + } + + #endregion + + /// + /// Gets the qualified name of the given method, consisting of + /// fully qualified interface/class name + "." method name. + /// + /// The method. + /// qualified name of the method. + public static string GetQualifiedMethodName(MethodInfo method) + { + AssertUtils.ArgumentNotNull(method, "method", "MethodInfo must not be null"); + return method.DeclaringType.FullName + "." + method.Name; + } + } } \ No newline at end of file