Freigeben über


AssemblyResolve Event

CLR uses documented heuristics to probe assemblies. If assembly can't be found through the standard heuristics, CLR will raise an AssemblyResolve event. You can subscribe AssemblyResolve event to provide the assembly in the case assembly can't be found through standard probing. This is the way (and the only way in v1/v1.1) to implement a custom assembly loader.

If your application is multi-threaded, your event handler may be called from many different threads simultaneously. In that case, your event handler has to be thread-safe.

The ResolveEventArgs has a Name property, which tells you which assembly CLR is expecting. It is very important that you always return the same assembly for the same Name. Otherwise you may encounter the Assembly Identity problem.

Comments

  • Anonymous
    April 25, 2004
    I have been playing around with the AssemblyResolve event a few months ago and I was somewhat surprised that I had to implement my own caching and keeping-track-of of loaded assemblies. Wrestling with bugs caused by doubly-loaded assemblies is not fun... Why doesn't the system walk the list of already loaded assemblies before firing AssemblyResolve? The only reason I can think of is that for some reason doubly loaded Assemblies are not a bug, but a feature. Are there any examples around that explore the possiblities of this?

    Another point: You mention "This is the way (and the only way in v1/v1.1) to implement a custom assembly loader". Does that mean there are alternatives in v2 of the framework? Could you provide a bit more information about that?
  • Anonymous
    April 25, 2004
    CLR does walk the list of already loaded assemblies before firing AssemblyResolve. I am not expert on this. I'll ask Suzanne to take a look.

    The second question, there will be more information when v2 beta1 is released. I can't disclose unpublished stuff yet.
  • Anonymous
    April 25, 2004
    Thanks for the answer.

    A small followup on the first question:
    The problem is that, as far as my understanding goes, only the assemblies loaded through Fusion are walked, and the very reason you got an AssemblyResolve event is of course that fusion was unable to find the assembly.
    Of course you could handle the event in a way that makes the assembly findable by Fusion (e.g. downloading it onto the search path), but in my case I was responding to AssemblyResolve by calling the Assembly.Load versions that take byte arrays (because my target assemblies were not files themselves, but were embedded in other files), and as far as I know those are not tracked by Fusion.

    As far as I know this whole system is rather underdocumented, so I don't know any more about it than what can be extracted from blogs like Suzanne's.
  • Anonymous
    April 25, 2004
    The comment has been removed
  • Anonymous
    April 26, 2004
    When does the system loader forget that an assembly has been found with a given name? Is it kept for the application lifetime or does eliminating all uses of an assembly allow the binding to be removed?
  • Anonymous
    April 26, 2004
    It is kept by the lifetime of the appdomain, unless the assembly happens to be loaded as domain neutral, in which case it is per application lifetime.
  • Anonymous
    April 27, 2004
    Ok thanks, that's good to know. Having to create separate AppDomains adds to the application design burden, but is a workable solution for reloading assemblies during runtime.
  • Anonymous
    April 27, 2004
    Luc: Yes, it is a feature. However, the AssemblyResolve event is meant as a last resort, for those who want to do something special (ought to be a rare case).

    Of course, I don't know the details of what you're doing, but I usually recommend avoiding such implementations. I can imagine a case where you would need to do this to work around a limitation imposed on you. But, if possible, it would be cleaner to have the assemblies be standalone, not embedded; then, using the event is unnecessary.

    Junfeng's comment really refers to an implementation detail. Conceptually, the only caching is in the LoadFrom context. See http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx .

    We're already working on beefing up the MSDN documentation in this area.