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.