Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a type from a referenced assembly via reflection

Tags:

c#

reflection

Suppose I have a factory method, which wants to construct an instance of a type chosen at run-time via reflection. Suppose further that my factory method is generic code that doesn't directly reference the assembly that contains the specified type, though it will be run from within an application that has the necessary assembly referenced.

How do I go about writing code that can find this type? If I do the following

public object CreateInstance(string typeName)
{
    Type desiredType = Assembly.GetExecutingAssembly().GetType(typename);

    // Instantiate the type...
}

this appears to fail because the type isn't defined in the executing assembly. If I could get all the assemblies available at runtime, I could iterate over them and find which one contains the type I want. But I can't see a way to do that. AppDomain.CurrentDomain.GetAssemblies() looks promising, but doesn't return all assemblies that I've referenced in my project.

Edit: Several people have pointed out that I need to load the assembly. The trouble is, this piece of code doesn't know which assembly it should load, since I'm attempting to write this code in such a way that it does not depend on the other assemblies.

I deliberately left out the details of typeName, since the mapping from string to type is actually more complicated in my real code. In fact, the type is identified by a custom attribute that contains the specified string, but if I can get hold of a list of types, I don't have a problem with restricting the list to the desired type.

like image 463
Tim Martin Avatar asked Feb 18 '10 18:02

Tim Martin


3 Answers

You could use GetReferencedAssemblies and loop through all the types until you find the type you're looking for.

var t = Assembly
   .GetExecutingAssembly()
   .GetReferencedAssemblies()
   .Select(x => Assembly.Load(x))
   .SelectMany(x => x.GetTypes()).First(x => x.FullName == typeName);

Although it might not be the most performant. Then again, you are using reflection.

like image 88
David Morton Avatar answered Nov 08 '22 19:11

David Morton


The call to AppDomain.CurrentDomain.GetAssemblies() only returns the set of DLL's that are currently loaded into the AppDomain. DLL's are loaded into a CLR process on demand; hence it won't include all of the DLL's referenced in your project until one is actually used.

What you could do though, is force the assembly into the process by using a typeof expression. For example

var force1 = typeof(SomeTypeInTheProject).Assembly;
var force2 = typeof(SomeTypeInProject2).Assembly;
like image 29
JaredPar Avatar answered Nov 08 '22 17:11

JaredPar


AppDomain.CurrentDomain.GetAssemblies() only returns the loaded assemblies. So you need to load that referenced assembly if it has not been loaded already.

like image 40
leppie Avatar answered Nov 08 '22 18:11

leppie