Reflection, custom attributes

  • Thread starter Thread starter michal_januszczyk
  • Start date Start date
M

michal_januszczyk

what may be the reason for the following behaviour:

//I load an assembly from dll.
Assembly asembly = Assembly.LoadFrom(dllFullPath);


//then I get all Types from the assembly
types = asembly.GetTypes();
flags = (BindingFlags.Public|BindingFlags.Static|
BindingFlags.Instance|BindingFlags.DeclaredOnly);

//and next, I try to load some method infos from type.
foreach (type in types)
{
MethodInfo[] mInfos = type.GetMethods(flags);

//and at the very end I try to get some custom attribues
//defined for the method.
attributes = mi.GetCustomAttributes(typeof (
Common.DescriptionAttribute),false);
if(attributes.Length >0)
{
//do somethong with the attributes...
}
}

The most strange thing for me is the fact, that when
dllFullPath points to some deeply nested directory (with
the project), the custom attributes are not found. But
when I copy the _very same_ DLL to root directory of
drive, all attributes are found. (?)

What may be the reason for such behaviour ?

Plese help
Michal Januszczyk
 
The path must be incorrect. All things being equal that seems to be the only
logical explanation. If I set the wrong path, I get a IO exception if the
path is not correct when calling LoadFrom.

Maybe, you are pointing at a different version of the assembly in the two
different locations?

Pretty odd. Is all the code running on the same machine?

How are you using Common.DescriptionAttribute? I loaded the type from the
assembly that was loaded.:

Assembly assembly = Assembly.LoadFrom(dllFullPath);
Type[] types = assembly.GetTypes();
BindingFlags flags = (BindingFlags.Public | BindingFlags.Static |
BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (Type t in types)
{
MethodInfo[] mi = t.GetMethods(flags);
for (int i = 0; i < mi.Length; i++)
{
object[] attributes =
mi.GetCustomAttributes(assembly.GetType("AttributeReflection.Transactiona
ble"), false);
if(attributes.Length > 0)
{
MessageBox.Show(t.Name + ": " + attributes.Length.ToString());
}
}
}


HTH;
Eric Cadwell
http://www.origincontrols.com
 
-----Original Message-----
The path must be incorrect. All things being equal that
seems to be the only

No, the path is correct. The assembly loads, types are
found, methods too, but when querying for custom
attributes something strange happens...
Maybe, you are pointing at a different version of the
assembly in the two different locations?

no, I'm certain that the files are identical.
Pretty odd. Is all the code running on the same machine?
Yes, this is the same machine.

I've further investigated the problem, and have found the
following rule:
When the first DLL to be loaded (after the proces started)
contains types with methods with the attributes (that we
are looking for) , then all subsequent attempts to find
these attibutes succeedes (of course only for these
libraries that really contain the types->...-
attributes). But if the first loaded module is a one
that does not contain types with functions with the
attributes, then all subsequent attempts to find them
fails for all DLLs, _inluding_ these DLLs that should be
reported as having the attribs.
The provios rule (that from root drive I could load, and
from nested could not) was a coincidence, that in the
root directory there was only one, single DLL that
contained the attributes (types with methods with the
attibutes defined for them). When examining the nested
directory, there were also other files there, and when
searching iteratively through the dlls , the first dll
did not contain the attribute.

Now when I copy another DLL into root dir, that does not
contain the attributes, and the file is loaded before the
one that _has_ the attibutes, the entire search process
finds nothing.


How are you using Common.DescriptionAttribute?

I use it very similar way. Instead of displaying the
information on screen, I put the infos into database
and use later.
loaded the type from the assembly that was loaded.:

Assembly assembly = Assembly.LoadFrom(dllFullPath);
Type[] types = assembly.GetTypes();
<_CUT_>
foreach (Type t in types)
{
.... <_CUT_>
}


I guess that the first load of assembly records some type-
information that I do not clear (should I clear such
information, [and how?]). I tried to find some dispose-
like method of assembly type, but found only this:

ProcessModuleCollection moduleCollection =
System.Diagnostics.Process.GetCurrentProcess().Modules;
//get index of loaded module via Assembly.LoadFrom();
moduleCollection[index].Dispose();

But this does not seem to solve the problem.
 
About Common.DescriptionAttribute...
Is the custom attribute type defined in a third assembly that is referenced
by both the loaded and loading assembly?

I was not able to reproduce this scenario. Is there any more rules that
you've been able to determine? Do the loaded assemblies have to be in the
same directory? I loaded two exe assemblies (one with methods marked with my
custom attr and one without) and was able to see that the attributes had
been declared. It made no difference if I loaded the non-attributed assembly
first

-Eric
 
Back
Top