Reflection and Type.GetType

  • Thread starter Thread starter Andrew Ducker
  • Start date Start date
A

Andrew Ducker

Is there any way to use Type.GetType to return a type that's in an
Assembly loaded from disk?

I sadly _have_ to use Type.GetType, as it's in framework code I can't
change.

At the moment, I'm loading the Assembly from disk (which works fine)
and adding it to the current AppDomain (just to be on the safe side),
but even when I do that, Type.GetType fails to find it.

Any suggestions?

Andy D
 
Are you passing in the fully qualified name to Type.GetType("MyNameSpace.MyClass") ?
i.e Namespace.Class

Kalpesh
 
Are you passing in the fully qualified name to Type.GetType("MyNameSpace.MyClass") ?
i.e Namespace.Class

You have to include the assembly name as well to get a truly FQ type
name.


Mattias
 
Andrew Ducker said:
Is there any way to use Type.GetType to return a type that's in an
Assembly loaded from disk?

I sadly _have_ to use Type.GetType, as it's in framework code I can't
change.

At the moment, I'm loading the Assembly from disk (which works fine)
and adding it to the current AppDomain (just to be on the safe side),
but even when I do that, Type.GetType fails to find it.

Any suggestions?

Yes - specify the assembly name in the call to Type.GetType. For
instance:

using System;

public class Test
{
static void Main()
{
Type type = Type.GetType("System.Data.SqlClient.SqlCommand, " +
"System.Data, "+
"Version=1.0.5000.0, "+
"Culture=neutral, "+
"PublicKeyToken=b77a5c561934e089");
Console.WriteLine (type);
}
}
 
Jon,

What if the assembly (not signed) is loaded form filesystem (not from GAC) ?

How does one still find the type in such assembly ?
(except Assembly.Get.... methods())

How can I use Type.GetType with this kind of assembly ?

Kalpesh
 
Hi Jon,

The MSDN Doc says (for Type.GetType)
"GetType only works on assemblies loaded from disk"

So, in order to get a class, this is the naming scheme - it should use
TopNamespace.SubNameSpace.ContainingClass+NestedClass,MyAssembly

Right?

Kalpesh
 
The MSDN Doc says (for Type.GetType)
"GetType only works on assemblies loaded from disk"

So, in order to get a class, this is the naming scheme - it should use
TopNamespace.SubNameSpace.ContainingClass+NestedClass,MyAssembly

Yes, that's right.
 
Hmm, in which case this should work - but doesn't:

OpenFileDialog fd = new OpenFileDialog();
fd.ShowDialog(this);
Assembly a = Assembly.LoadFile(fd.FileName);
Type t= a.GetType("TestClass.FirstTestClass");
MessageBox.Show(t.AssemblyQualifiedName);
Type t2 = Type.GetType(t.AssemblyQualifiedName);
MessageBox.Show(t2.AssemblyQualifiedName);

In fact, the a.GetType works (providing you've created a class called
FirstTestClass in the Namespace TestClass), but the Type.GetType
doesn't.

Any ideas why?

Andy D
 
Andrew Ducker said:
Hmm, in which case this should work - but doesn't:

OpenFileDialog fd = new OpenFileDialog();
fd.ShowDialog(this);
Assembly a = Assembly.LoadFile(fd.FileName);
Type t= a.GetType("TestClass.FirstTestClass");
MessageBox.Show(t.AssemblyQualifiedName);
Type t2 = Type.GetType(t.AssemblyQualifiedName);
MessageBox.Show(t2.AssemblyQualifiedName);

In fact, the a.GetType works (providing you've created a class called
FirstTestClass in the Namespace TestClass), but the Type.GetType
doesn't.

Any ideas why?

Yes - Type.GetType looks for assemblies in the "normal" places - it
doesn't know where to find "other" assemblies loaded from elsewhere on
the disk. I'm slightly surprised that it doesn't look at all the
assemblies loaded in the current AppDomain first, but that's life, I
guess...
 
Well, at least that means it can't be done, so I can stop trying.

I've found an alternative to GetType that should work in this case:

foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
Type t2 = assembly.GetType(TypeName);
if (t2 != null)
MessageBox.Show(t2.AssemblyQualifiedName);
}

So I'll pass that onto the framework people and see if they can
incorporate it.

Andy D
 
Well, I dont know - whether how good this is & applicable ?

How about AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap ?
(this will load assembly from filesystem & create an instance of the type that you specify)

This will get you an instance of the class & you can call .GetType() on it

Does this help ?

Kalpesh
 
Any ideas why?
Type.GetType expects a typeName parameter which, in it full form,
includes all the necessary info where to locate the type. Thus, when
you omit the assembly spec in typeName, the method makes use of
"defaults", and searches the calling assembly, then mscorlib.dll. The
reason it does not search other loaded assemblies is that it would
violate that parameter's semantics.

Thi
http://thith.blogspot.com
 
However, with dynamically loaded Types, it can't find them, no matter
what you pass in as the TypeName (see my example code a few entries
up).

Andy D
 
Hi Andy,

It does not matter whether you loaded the assembly or not. Type.GetType
uses some specific rules to look for the assembly (these rules are in
..NET documentation, search google for ""How the Runtime Locates
Assemblies"").

Thi - http://thith.blogspot.com
 
Cheers for that. It's a shame that Type.GetType can't do what I want -
thankfully iterating through the
CurrentDomain.Assemblies.GetType(ClassName) calls does the trick.

Andy D
 
Back
Top