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.
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.
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;
AppDomain.CurrentDomain.GetAssemblies()
only returns the loaded assemblies. So you need to load that referenced assembly if it has not been loaded already.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With