How do I load a generic type containing nested types from dynamically loaded assemblies?

After following a lead from an MSDN forum posting I was able to put together a general solution for loading arbitrary generic types from assemblies loaded at runtime. I hope this helps some people (and maybe Microsoft will put something equivalent into . NET 4.0?) public static class TypeHelpers { /// /// Gets the System.

Type with the specified name, performing a case-sensitive search. /// /// The assembly-qualified name of the type to get. See System.Type.

AssemblyQualifiedName. /// Whether or not to throw an exception or return null if the type was not found. /// Whether or not to perform a case-insensitive search.

/// The System. Type with the specified name. /// /// This method can load types from dynamically loaded assemblies as long as the referenced assembly /// has already been loaded into the current AppDomain.

/// public static Type GetType(string typeName, bool throwOnError, bool ignoreCase) { if(string. IsNullOrEmpty(typeName)) throw new ArgumentNullException("typeName"); // handle the trivial case Type type; if((type = Type. GetType(typeName, false, ignoreCase))!

= null) return type; // otherwise, perform the recursive search try { return GetTypeFromRecursive(typeName, ignoreCase); } catch(Exception e) { if(throwOnError) throw; } return null; } #region Private Static Helper Methods private static Type GetTypeFromRecursive(string typeName, bool ignoreCase) { int startIndex = typeName. IndexOf(''); int endIndex = typeName. LastIndexOf(''); if(startIndex == -1) { // try to load the non-generic type (e.g. System.

Int32) return TypeHelpers. GetNonGenericType(typeName, ignoreCase); } else { // determine the cardinality of the generic type int cardinalityIndex = typeName. IndexOf('`', 0, startIndex); string cardinalityString = typeName.

Substring(cardinalityIndex + 1, startIndex - cardinalityIndex - 1); int cardinality = int. Parse(cardinalityString); // get the FullName of the non-generic type (e.g. System.Collections.Generic. List`1) string fullName = typeName.

Substring(0, startIndex); if(typeName. Length - endIndex - 1 > 0) fullName += typeName. Substring(endIndex + 1, typeName.

Length - endIndex - 1); // parse the child type arguments for this generic type (recursive) List list = new List(); string typeArguments = typeName. Substring(startIndex + 1, endIndex - startIndex - 1); foreach(string item in EachAssemblyQualifiedName(typeArguments, cardinality)) { Type typeArgument = GetTypeFromRecursive(item, ignoreCase); list. Add(typeArgument); } // construct the generic type definition return TypeHelpers.

GetNonGenericType(fullName, ignoreCase). MakeGenericType(list.ToArray()); } } private static IEnumerable EachAssemblyQualifiedName(string s, int count) { Debug. Assert(count!

= 0); Debug. Assert(string. IsNullOrEmpty(s) == false); Debug.

Assert(s. Length > 2); // e.g. "System. String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" // e.g. "System.

String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089,System. DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" // e.g. "System.Collections.Generic. KeyValuePair`2System.

Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089,System. DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" int startIndex = 0; int bracketCount = 0; while(count > 0) { bracketCount = 0; for(int I = startIndex; I >>> obj = new Dictionary>>>(); string typeName = obj.GetType(). FullName; Type type = TypeHelpers.

GetType(typeName, true, false); Assert. IsTrue(type. Equals(obj.GetType())); } Note: You should comment out the trivial handler when trying to use this test, otherwise Type.GetType() will be called instead of the actual parsing code.

After following a lead from an MSDN forum posting, I was able to put together a general solution for loading arbitrary generic types from assemblies loaded at runtime. I hope this helps some people (and maybe Microsoft will put something equivalent into . NET 4.0?) public static class TypeHelpers { /// /// Gets the System.

Type with the specified name, performing a case-sensitive search. /// /// The assembly-qualified name of the type to get. See System.Type.

AssemblyQualifiedName. /// Whether or not to throw an exception or return null if the type was not found. /// Whether or not to perform a case-insensitive search.

/// The System. Type with the specified name. /// /// This method can load types from dynamically loaded assemblies as long as the referenced assembly /// has already been loaded into the current AppDomain.

/// public static Type GetType(string typeName, bool throwOnError, bool ignoreCase) { if(string. IsNullOrEmpty(typeName)) throw new ArgumentNullException("typeName"); // handle the trivial case Type type; if((type = Type. GetType(typeName, false, ignoreCase))!

= null) return type; // otherwise, perform the recursive search try { return GetTypeFromRecursive(typeName, ignoreCase); } catch(Exception e) { if(throwOnError) throw; } return null; } #region Private Static Helper Methods private static Type GetTypeFromRecursive(string typeName, bool ignoreCase) { int startIndex = typeName. IndexOf(''); int endIndex = typeName. LastIndexOf(''); if(startIndex == -1) { // try to load the non-generic type (e.g. System.

Int32) return TypeHelpers. GetNonGenericType(typeName, ignoreCase); } else { // determine the cardinality of the generic type int cardinalityIndex = typeName. IndexOf('`', 0, startIndex); string cardinalityString = typeName.

Substring(cardinalityIndex + 1, startIndex - cardinalityIndex - 1); int cardinality = int. Parse(cardinalityString); // get the FullName of the non-generic type (e.g. System.Collections.Generic. List`1) string fullName = typeName.

Substring(0, startIndex); if(typeName. Length - endIndex - 1 > 0) fullName += typeName. Substring(endIndex + 1, typeName.

Length - endIndex - 1); // parse the child type arguments for this generic type (recursive) List list = new List(); string typeArguments = typeName. Substring(startIndex + 1, endIndex - startIndex - 1); foreach(string item in EachAssemblyQualifiedName(typeArguments, cardinality)) { Type typeArgument = GetTypeFromRecursive(item, ignoreCase); list. Add(typeArgument); } // construct the generic type definition return TypeHelpers.

GetNonGenericType(fullName, ignoreCase). MakeGenericType(list.ToArray()); } } private static IEnumerable EachAssemblyQualifiedName(string s, int count) { Debug. Assert(count!

= 0); Debug. Assert(string. IsNullOrEmpty(s) == false); Debug.

Assert(s. Length > 2); // e.g. "System. String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" // e.g. "System.

String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089,System. DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" // e.g. "System.Collections.Generic. KeyValuePair`2System.

Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089,System. DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" int startIndex = 0; int bracketCount = 0; while(count > 0) { bracketCount = 0; for(int I = startIndex; I >>> obj = new Dictionary>>>(); string typeName = obj.GetType(). FullName; Type type = TypeHelpers.

GetType(typeName, true, false); Assert. IsTrue(type. Equals(obj.GetType())); } Note: You should comment out the trivial handler when trying to use this test, otherwise Type.GetType() will be called instead of the actual parsing code.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions