1 // ****************************************************************
2 // This is free software licensed under the NUnit license. You
3 // may obtain a copy of the license as well as information regarding
4 // copyright ownership at http://nunit.org/?p=license&r=2.4.
5 // ****************************************************************
8 using System
.Reflection
;
9 using System
.Collections
;
14 /// Helper methods for inspecting a type by reflection.
16 /// Many of these methods take a MemberInfo as an argument to avoid
17 /// duplication, even though certain attributes can only appear on
18 /// specific types of members, like MethodInfo or Type.
20 /// In the case where a type is being examined for the presence of
21 /// an attribute, interface or named member, the Reflect methods
22 /// operate with the full name of the member being sought. This
23 /// removes the necessity of the caller having a reference to the
24 /// assembly that defines the item being sought and allows the
25 /// NUnit core to inspect assemblies that reference an older
26 /// version of the NUnit framework.
33 /// Check presence of attribute of a given type on a member.
35 /// <param name="member">The member to examine</param>
36 /// <param name="attrName">The FullName of the attribute type to look for</param>
37 /// <param name="inherit">True to include inherited attributes</param>
38 /// <returns>True if the attribute is present</returns>
39 public static bool HasAttribute( MemberInfo member
, string attrName
, bool inherit
)
41 object[] attributes
= member
.GetCustomAttributes( inherit
);
42 foreach( Attribute attribute
in attributes
)
43 if ( IsInstanceOfType( attrName
, attribute
) )
49 /// Get attribute of a given type on a member. If multiple attributes
50 /// of a type are present, the first one found is returned.
52 /// <param name="member">The member to examine</param>
53 /// <param name="attrName">The FullName of the attribute type to look for</param>
54 /// <param name="inherit">True to include inherited attributes</param>
55 /// <returns>The attribute or null</returns>
56 public static System
.Attribute
GetAttribute(MemberInfo member
, string attrName
, bool inherit
)
58 object[] attributes
= member
.GetCustomAttributes(inherit
);
59 foreach (Attribute attribute
in attributes
)
60 if ( IsInstanceOfType( attrName
, attribute
) )
66 /// Get attribute of a given type on an assembly. If multiple attributes
67 /// of a type are present, the first one found is returned.
69 /// <param name="assembly">The assembly to examine</param>
70 /// <param name="attrName">The FullName of the attribute type to look for</param>
71 /// <param name="inherit">True to include inherited attributes</param>
72 /// <returns>The attribute or null</returns>
73 public static System
.Attribute
GetAttribute(Assembly assembly
, string attrName
, bool inherit
)
75 object[] attributes
= assembly
.GetCustomAttributes(inherit
);
76 foreach (Attribute attribute
in attributes
)
77 if ( IsInstanceOfType(attrName
, attribute
) )
83 /// Get all attributes of a given type on a member.
85 /// <param name="member">The member to examine</param>
86 /// <param name="attrName">The FullName of the attribute type to look for</param>
87 /// <param name="inherit">True to include inherited attributes</param>
88 /// <returns>The attribute or null</returns>
89 public static System
.Attribute
[] GetAttributes( MemberInfo member
, string attrName
, bool inherit
)
91 object[] attributes
= member
.GetCustomAttributes( inherit
);
92 ArrayList result
= new ArrayList();
93 foreach( Attribute attribute
in attributes
)
94 if ( IsInstanceOfType( attrName
, attribute
) )
95 result
.Add( attribute
);
96 return (System
.Attribute
[])result
.ToArray( typeof( System
.Attribute
) );
100 /// Get all attributes on a member.
102 /// <param name="member">The member to examine</param>
103 /// <param name="inherit">True to include inherited attributes</param>
104 /// <returns>The attribute or null</returns>
105 public static System
.Attribute
[] GetAttributes(MemberInfo member
, bool inherit
)
107 object[] attributes
= member
.GetCustomAttributes(inherit
);
108 System
.Attribute
[] result
= new System
.Attribute
[attributes
.Length
];
110 foreach (Attribute attribute
in attributes
)
111 result
[n
++] = attribute
;
116 /// Get all attributes on an assembly.
118 /// <param name="assembly">The assembly to examine</param>
119 /// <param name="inherit">True to include inherited attributes</param>
120 /// <returns>The attributes or null</returns>
121 public static System
.Attribute
[] GetAttributes(Assembly assembly
, bool inherit
)
123 object[] attributes
= assembly
.GetCustomAttributes(inherit
);
124 System
.Attribute
[] result
= new System
.Attribute
[attributes
.Length
];
126 foreach (Attribute attribute
in attributes
)
127 result
[n
++] = attribute
;
136 /// Check to see if a type implements a named interface.
138 /// <param name="fixtureType">The type to examine</param>
139 /// <param name="interfaceName">The FullName of the interface to check for</param>
140 /// <returns>True if the interface is implemented by the type</returns>
141 public static bool HasInterface( Type fixtureType
, string interfaceName
)
143 foreach( Type type
in fixtureType
.GetInterfaces() )
144 if ( type
.FullName
== interfaceName
)
152 //SHMARYA: [ 10/12/2005 ]
154 /// Checks to see if a type inherits from a named type.
156 /// <param name="type">The type to examine</param>
157 /// <param name="parentType">The FullName of the inherited type to look for</param>
158 /// <returns>True if the type inherits from the named type.</returns>
159 public static bool InheritsFrom( Type type
, string typeName
)
161 for( Type current
= type
; current
!= typeof( object ); current
= current
.BaseType
)
162 if( current
.FullName
== typeName
)
168 public static bool InheritsFrom( object obj
, string typeName
)
170 return InheritsFrom( obj
.GetType(), typeName
);
173 public static bool IsInstanceOfType( string typeName
, Attribute attr
)
175 Type type
= attr
.GetType();
176 return type
.FullName
== typeName
|| InheritsFrom( type
, typeName
);
180 #region Get Methods of a type
183 /// Find the default constructor on a type
185 /// <param name="fixtureType"></param>
186 /// <returns></returns>
187 public static ConstructorInfo
GetConstructor( Type fixtureType
)
189 return fixtureType
.GetConstructor( Type
.EmptyTypes
);
193 /// Find the default constructor on a type
195 /// <param name="fixtureType"></param>
196 /// <returns></returns>
197 public static ConstructorInfo
GetConstructor( Type fixtureType
, Type
[] types
)
199 return fixtureType
.GetConstructor( types
);
203 /// Examine a fixture type and return a method having a particular attribute.
204 /// In the case of multiple methods, the first one found is returned.
206 /// <param name="fixtureType">The type to examine</param>
207 /// <param name="attributeName">The FullName of the attribute to look for</param>
208 /// <param name="bindingFlags">BindingFlags to use in looking for method</param>
209 /// <returns>A MethodInfo or null</returns>
210 public static MethodInfo
GetMethodWithAttribute( Type fixtureType
, string attributeName
, BindingFlags bindingFlags
, bool inherit
)
212 foreach(MethodInfo method
in fixtureType
.GetMethods( bindingFlags
) )
214 if( HasAttribute( method
, attributeName
, inherit
) )
222 /// Examine a fixture type and return a count of the methods having a
223 /// particular attribute.
225 /// <param name="fixtureType">The type to examine</param>
226 /// <param name="attributeName">The FullName of the attribute to look for</param>
227 /// <param name="bindingFlags">BindingFlags to use in looking for method</param>
228 /// <returns>The number of such methods found</returns>
229 public static int CountMethodsWithAttribute( Type fixtureType
, string attributeName
, BindingFlags bindingFlags
, bool inherit
)
233 foreach(MethodInfo method
in fixtureType
.GetMethods( bindingFlags
) )
235 if( HasAttribute( method
, attributeName
, inherit
) )
243 /// Examine a fixture type and get a method with a particular name.
244 /// In the case of overloads, the first one found is returned.
246 /// <param name="fixtureType">The type to examine</param>
247 /// <param name="methodName">The name of the method</param>
248 /// <param name="bindingFlags">BindingFlags to use in the search</param>
249 /// <returns>A MethodInfo or null</returns>
250 public static MethodInfo
GetNamedMethod(Type fixtureType
, string methodName
, BindingFlags bindingFlags
)
252 foreach (MethodInfo method
in fixtureType
.GetMethods(bindingFlags
))
254 if (method
.Name
== methodName
)
262 /// Examine a fixture type and get a method with a particular name and list
263 /// of arguments. In the case of overloads, the first one found is returned.
265 /// <param name="fixtureType">The type to examine</param>
266 /// <param name="methodName">The name of the method</param>
267 /// <param name="argTypes">The full names of the argument types to search for</param>
268 /// <param name="bindingFlags">BindingFlags to use in the search</param>
269 /// <returns>A MethodInfo or null</returns>
270 public static MethodInfo
GetNamedMethod(Type fixtureType
, string methodName
,
271 string[] argTypes
, BindingFlags bindingFlags
)
273 foreach (MethodInfo method
in fixtureType
.GetMethods(bindingFlags
))
275 if (method
.Name
== methodName
)
277 ParameterInfo
[] parameters
= method
.GetParameters();
278 if (parameters
.Length
== argTypes
.Length
)
281 for (int i
= 0; i
< argTypes
.Length
; i
++)
282 if (parameters
[i
].ParameterType
.FullName
!= argTypes
[i
])
299 #region Get Properties of a type
302 /// Examine a type and return a property having a particular attribute.
303 /// In the case of multiple methods, the first one found is returned.
305 /// <param name="fixtureType">The type to examine</param>
306 /// <param name="attributeName">The FullName of the attribute to look for</param>
307 /// <param name="bindingFlags">Binding flags to use in searching</param>
308 /// <returns>A PropertyInfo or null</returns>
309 public static PropertyInfo
GetPropertyWithAttribute( Type fixtureType
, string attributeName
, BindingFlags bindingFlags
)
311 foreach(PropertyInfo property
in fixtureType
.GetProperties( bindingFlags
) )
313 if( HasAttribute( property
, attributeName
, true ) )
321 /// Examine a type and get a property with a particular name.
322 /// In the case of overloads, the first one found is returned.
324 /// <param name="type">The type to examine</param>
325 /// <param name="bindingFlags">BindingFlags to use</param>
326 /// <returns>A PropertyInfo or null</returns>
327 public static PropertyInfo
GetNamedProperty( Type type
, string name
, BindingFlags bindingFlags
)
329 return type
.GetProperty( name
, bindingFlags
);
333 /// Get the value of a named property on an object using binding flags of Public and Instance
335 /// <param name="obj">The object for which the property value is needed</param>
336 /// <param name="name">The name of a non-indexed property of the object</param>
337 /// <returns></returns>
338 public static object GetPropertyValue( object obj
, string name
)
340 return GetPropertyValue( obj
, name
, BindingFlags
.Public
| BindingFlags
.Instance
);
344 /// Get the value of a named property on an object
346 /// <param name="obj">The object for which the property value is needed</param>
347 /// <param name="name">The name of a non-indexed property of the object</param>
348 /// <param name="bindingFlags">BindingFlags for use in determining which properties are needed</param>param>
349 /// <returns></returns>
350 public static object GetPropertyValue( object obj
, string name
, BindingFlags bindingFlags
)
352 PropertyInfo property
= GetNamedProperty( obj
.GetType(), name
, bindingFlags
);
353 if ( property
!= null )
354 return property
.GetValue( obj
, null );
359 /// Set the value of a named property on an object
361 /// <param name="obj">The object for which the property value is to be set</param>
362 /// <param name="name">The name of a non-indexed property of the object</param>
363 /// <param name="val">The value to which the property is to be set</param>
364 /// <param name="bindingFlags">BindingFlags for use in determining which properties are needed</param>param>
365 public static void SetPropertyValue( object obj
, string name
, object val
, BindingFlags bindingFlags
)
367 PropertyInfo property
= GetNamedProperty( obj
.GetType(), name
, bindingFlags
);
368 if ( property
!= null )
369 property
.SetValue( obj
, val
, null );
374 #region Invoke Methods
377 /// Invoke the default constructor on a type
379 /// <param name="type">The type to be constructed</param>
380 /// <returns>An instance of the type</returns>
381 public static object Construct( Type type
)
383 ConstructorInfo ctor
= GetConstructor( type
);
385 throw new InvalidTestFixtureException(type
.FullName
+ " does not have a valid constructor");
387 return ctor
.Invoke( Type
.EmptyTypes
);
391 /// Invoke a parameterless method returning void on an object.
393 /// <param name="method">A MethodInfo for the method to be invoked</param>
394 /// <param name="fixture">The object on which to invoke the method</param>
395 public static void InvokeMethod( MethodInfo method
, object fixture
)
397 InvokeMethod( method
, fixture
, null );
401 /// Invoke a method returning void, converting any TargetInvocationException
402 /// to an NUnitException
404 /// <param name="method">A MethodInfo for the method to be invoked</param>
405 /// <param name="fixture">The object on which to invoke the method</param>
406 public static void InvokeMethod( MethodInfo method
, object fixture
, params object[] args
)
412 method
.Invoke( fixture
, args
);
414 catch(TargetInvocationException e
)
416 Exception inner
= e
.InnerException
;
417 throw new NUnitException("Rethrown",inner
);
424 #region Private Constructor for static-only class
426 private Reflect() { }