views:

232

answers:

2

I need to create a type from its full name only Ex: "System.String" or "Tuple'2[string,Mytype]". there is no information about the assembly in the string. Here is what the code look like.

private static Type LoadType(string typeName)
{
    // try loading the type
    Type type = Type.GetType(typeName, false);

    if (type != null)
        return type;

    // if the loading was not successfull iterate all the referenced assemblies and try to load the type.
    Assembly asm = Assembly.GetEntryAssembly();
    AssemblyName[] referencedAssemblies = asm.GetReferencedAssemblies();
    foreach (AssemblyName referencedAssemblyName in referencedAssemblies)
    {
        type = referencedAssembly.GetType(typeName, false);
        if (type != null)
            return type;
    }
    throw new TypeLoadException(string.Format("Could not load the Type '{0}'",typeName));
}

this method works when the type is not generic. But for generic types iterating through the assemblies always fails because no assemblies contains all the definitions required to build the type.

Is there a way to provide multiples assemblies for type resolution when calling GetTypes ?

+1  A: 

Something like this....

Type.GetType("namespace.typename`1[[namespace.typename, assemblyname]], assemblyname");

e.g.

var type = Type.GetType("System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib");
var instance = Activator.CreateInstance(type);

or, as Eric says.. if you have the types in hand, just build it..

Type genericType = typeof(Dictionary<,>);
Type constructedType = genericType.MakeGenericType(new Type[] { typeof(String), typeof(String) });
Sky Sanders
*there is no information about the assembly in the string*
Yuriy Faktorovich
well then, unless the assembly is loaded or you can load it AND there are no ambiguous matches, you are out of luck. sorry.
Sky Sanders
is it possible to force the loading of the assemblies ?
Johnny Blaze
any one of the Assembly.Load methods. If you have to load the assemblies then you will have to munge up a string typename and create it. If you have the types already loaded, e.g. using xxx.xx, you can just build it using Type methods as shown and described by Eric
Sky Sanders
+3  A: 

You're going to have to do it the hard way I think. Fortunately it's not that hard. Pretty straightforward:

  • Parse the type name into the type definition and the generic type arguments.
  • Obtain the generic type definition object
  • Obtain the type objects for each generic type argument
  • Construct the generic type out of the generic type definition and the generic type arguments using the MakeGenericType method on the type definition object.
Eric Lippert
I thought about this solution but it's the last step i find difficult,let's say i parsed Tuple'2[System.String,MyNameSpace.MyType] and i'm able to get the three diffrents types (Tuple,String and MyType). How do i create the instance t of Type such as : t == typeof(Tuple<String,MyType>)
Johnny Blaze
Type genericType = typeof(Dictionary<,>); Type constructedType = genericType.MakeGenericType(new Type[] { typeof(String), typeof(String) });
Sky Sanders