Reflection

  • Thread starter Thread starter Jozsef Bekes
  • Start date Start date
J

Jozsef Bekes

Hi All,

I am trying to use reflection for getting all the classes from the dlls of a
software written by my company. I am using this line:

Assembly.LoadFile(s).GetTypes()

Gettypes fails, I guess because when one dll refers to another one of mine,
Reflection does not find that dll. This is what the exception contains
anyway. So I realized that I'd need to copy the dlls, or register them to
the GAC. And then I tried Reflector, and to my amazement, everything was
working fine! Then I tried some tricks, invoked Assembly.LoadFile() for all
the referenced dlls before trying GetTypes() on the one in question, still
no success. Does anyone have an idea how it can be done without copying and
GAC?

I appreciate all your answers.

Thanks,

Jozsi
 
Try this before you load and see if it helps.
String path = Path.GetDirectoryName(Path.GetFullPath(assemblyName));
#if VS2003
AppDomain.CurrentDomain.AppendPrivatePath(path);
#else
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = path;
#endif

Hope it helps
Leon Lambert
 
Hi Leon,

thank you for the suggestion. I could not manage to make it work even with
the lines you suggested, but this might also be needed for making the stuff
run.

Thank you,
Jozsi
 
Was hoping to avoid this but here is a more complex way to try.
First define a ResolveEventHandler in the class where you are doing the
loading. It would look something like the following. Sorry for ugly
look. This UseNet Reader is wrapping stuff

private ResolveEventHandler resolveEventHandler;

Then somewhere before you try to load add a handler. Something like this.

resolveEventHandler = new ResolveEventHandler(AssemblyResolver);
Thread.GetDomain().AssemblyResolve += resolveEventHandler;

Then create a resolver method something like this.
In my case i had a command line argument to specify
additional directories where to search for support
dlls. So the handler will also search there.
public Assembly AssemblyResolver(Object sender,ResolveEventArgs args)
{
String path;
// try looking in same directory as the original one first

// assembly is a class variable containing the starting loaded
// assembly

// assemblyNameToResolve is a class string variable.

path=assembly.Location.Substring(0,assembly.Location.LastIndexOf("\\") + 1);
assemblyNameToResolve = args.Name;
if ((assemblyNameToResolve.IndexOf(",") != -1) &&
(assemblyNameToResolve.IndexOf("Culture") != -1))
assemblyNameToResolve=assemblyNameToResolve.Substring(0,assemblyNameToResolve.IndexOf(","));

// I had a collection of loaded assemblies.
// This check to see if i already loaded it and just
// return it if it was already loaded
Assembly assm = assembliesLookup[assemblyNameToResolve] as Assembly;
if (assm != null)
return(assm);
try
{
assm =
Assembly.LoadFrom(String.Concat(path,assemblyNameToResolve,".dll"));
}
catch (Exception)
{
}
// if not found try looking in directories passed in
// as command line arguments
if (assm == null)
{
foreach (String assemblyPath in extAssemblyDirectory)
{
try
{
assm =
Assembly.LoadFrom(String.Concat(assemblyPath,assemblyNameToResolve,".dll"));
if (assm != null)
break;
}
catch (Exception)
{
}
}
}
if (assm == null)
throw(new Exception("Cant find assembly " +
assemblyNameToResolve));

// add to collection of already looked up assemblies
assembliesLookup.Add(assemblyNameToResolve,assm);
return(assm);
}

When done using the loading class add the following code to remove the
handler.

Thread.GetDomain().AssemblyResolve -= resolveEventHandler;

This should work because it did for me. Sorry for the ugliness because
of line wrap
Leon Lambert
 
Back
Top