G
Guest
I have been looking for a more powerful version of GetType(string) that will
find the Type no matter what, and will work even if only supplied
"{TypeName}", not the full "{TypeName},{AssemblyName}"
As far as I know yet -- hence this question -- there is no 'one solution
fits all', but instead there are several parts that have to be put together
to check.
What I have so far is, and would like as much feedback as possible to ensure
I've done the best job possible is:
Step 1: Find a Type in the calling Assembly, or fallback to mscorlib:
GetType() looks for a class by that name in the calling Assembly, and then
falls back to search in mscorlib.
As you can imagine, this doesn't get us far.
Step 2: Looking in other Assemblies already loaded:
If not in either of these two, you have to fall back to using
AppDomain.GetAssemblies(), and then loop through each individually to test
each one with assembly.GetType(string).
Step 3: Looking in Assemblies not already loaded:
But these only refer to assemblies already loaded -- and will fail if the
assembly has not loaded yet, so you then have to Assembly.Load(pathName) for
each assembly in the bin dir that ends with ".dll" and ".exe".
Step 4: Looking in the GAC:
The above solutions almost get us through everything, except there stilll is
missing one place to look, the GAC. How can I get a list of assemblies in the
GAC, to search through them as well?
Questions:
a) The Assembly.LoadFile() worries me a lot: how does it work, exactly? I
assume it does exactly as implied, and loads it up in memory -- so calling it
at the beginning of a program could mean that *all* assemblies are loaded in
memory right from the start, making for a slower startup... Calling and
loading all files in the GAC to search through them would end up with a lot
of memory for assemblies that have nothing to do with the application, right?
b) This all seems to be a very complex route, that even with caching for
later, could be a massive drain on system resources -- is there any simpler
way?
c) GetAssemblies() is not available on CE...Is there *any* other way to get
a list of assemblies loaded in memory other than AppDomain.GetAssemblies?
Thank you for any and all feedback, and pointers,
Sky
BTW: For anybody that is interested, the code for the above looks a bit like:
private static Type LoadType(string typeName) {
System.Reflection.Assembly assembly;
return LoadType(typeName, out assembly);
}
private static Type LoadType(string typeName, out
System.Reflection.Assembly assemblyTypeFoundIn) {
if (string.IsNullOrEmpty(typeName)) {
throw new System.ArgumentNullException("typeName");
}
//Clear results first:
assemblyTypeFoundIn = null;
System.Reflection.Assembly assembly = null;
System.Type type = null;
type = System.Type.GetType(typeName, false, true);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
#if (!PocketPC) && (!pocketPC) && (!WindowsCE)
foreach (System.Reflection.Assembly tmpAasembly in
System.AppDomain.CurrentDomain.GetAssemblies()) {
type = tmpAasembly.GetType(typeName);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
}
#endif
//Get Path to Bin folder:
string exePath;
//exePath = System.AppDomain.CurrentDomain.BaseDirectory;
//exePath =
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
exePath =
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetModules()[0].FullyQualifiedName);
string[] fileNames = System.IO.Directory.GetFiles(exePath, "*.dll");
foreach (string fileName in fileNames) {
try {
assembly = System.Reflection.Assembly.LoadFrom(fileName);
type = assembly.GetType(typeName);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
}
catch {
assembly = null;
}
}
return null;
}
find the Type no matter what, and will work even if only supplied
"{TypeName}", not the full "{TypeName},{AssemblyName}"
As far as I know yet -- hence this question -- there is no 'one solution
fits all', but instead there are several parts that have to be put together
to check.
What I have so far is, and would like as much feedback as possible to ensure
I've done the best job possible is:
Step 1: Find a Type in the calling Assembly, or fallback to mscorlib:
GetType() looks for a class by that name in the calling Assembly, and then
falls back to search in mscorlib.
As you can imagine, this doesn't get us far.
Step 2: Looking in other Assemblies already loaded:
If not in either of these two, you have to fall back to using
AppDomain.GetAssemblies(), and then loop through each individually to test
each one with assembly.GetType(string).
Step 3: Looking in Assemblies not already loaded:
But these only refer to assemblies already loaded -- and will fail if the
assembly has not loaded yet, so you then have to Assembly.Load(pathName) for
each assembly in the bin dir that ends with ".dll" and ".exe".
Step 4: Looking in the GAC:
The above solutions almost get us through everything, except there stilll is
missing one place to look, the GAC. How can I get a list of assemblies in the
GAC, to search through them as well?
Questions:
a) The Assembly.LoadFile() worries me a lot: how does it work, exactly? I
assume it does exactly as implied, and loads it up in memory -- so calling it
at the beginning of a program could mean that *all* assemblies are loaded in
memory right from the start, making for a slower startup... Calling and
loading all files in the GAC to search through them would end up with a lot
of memory for assemblies that have nothing to do with the application, right?
b) This all seems to be a very complex route, that even with caching for
later, could be a massive drain on system resources -- is there any simpler
way?
c) GetAssemblies() is not available on CE...Is there *any* other way to get
a list of assemblies loaded in memory other than AppDomain.GetAssemblies?
Thank you for any and all feedback, and pointers,
Sky
BTW: For anybody that is interested, the code for the above looks a bit like:
private static Type LoadType(string typeName) {
System.Reflection.Assembly assembly;
return LoadType(typeName, out assembly);
}
private static Type LoadType(string typeName, out
System.Reflection.Assembly assemblyTypeFoundIn) {
if (string.IsNullOrEmpty(typeName)) {
throw new System.ArgumentNullException("typeName");
}
//Clear results first:
assemblyTypeFoundIn = null;
System.Reflection.Assembly assembly = null;
System.Type type = null;
type = System.Type.GetType(typeName, false, true);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
#if (!PocketPC) && (!pocketPC) && (!WindowsCE)
foreach (System.Reflection.Assembly tmpAasembly in
System.AppDomain.CurrentDomain.GetAssemblies()) {
type = tmpAasembly.GetType(typeName);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
}
#endif
//Get Path to Bin folder:
string exePath;
//exePath = System.AppDomain.CurrentDomain.BaseDirectory;
//exePath =
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
exePath =
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetModules()[0].FullyQualifiedName);
string[] fileNames = System.IO.Directory.GetFiles(exePath, "*.dll");
foreach (string fileName in fileNames) {
try {
assembly = System.Reflection.Assembly.LoadFrom(fileName);
type = assembly.GetType(typeName);
if (type != null) {
assemblyTypeFoundIn = type.Assembly;
return type;
}
}
catch {
assembly = null;
}
}
return null;
}