Marko Apfel - Afghanistan/Belgium/Germany

Management, Architecture, Programming, QA, Coach, GIS, EAI

  Home  |   Contact  |   Syndication    |   Login
  187 Posts | 2 Stories | 201 Comments | 4 Trackbacks


Twitter | LinkedIn | Xing


Post Categories



Enterprise Library


SQL Server


Till yet I thought, that if you have an assembly in the GAC all referenced assemblies must also be in the GAC. So a break of this GAC-assembly resolving chain is impossible.

This results in some annoying problems. Lets have a view at the following scenario:

You write an own appender for log4net. You deploy your solution with log4net-assembly beside your application assemblies. Your appender is located in one of there application assemblies and log4net is configured to use this appender. Everything works fine so lang. But if you deploy your solution to a machine where another application deployed log4net to the GAC, your application runs in problems. GAC-assemblies trumps all other assemblies. This means, that your solution don’t bind to the local log4net-assembly. Instead it bind to the GAC located one (if both assemblies have the same identity and you don’t use an own compilation with own strong name).

Now the “resolving pointer” is in the GAC and could not leave this store. This means, that your appender could not be resolved, because it is located outside the GAC. Merde!

But there is a trick to overdrive the bind mechanism: with an assembly-resolve-handler per AppDomain:

	AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
	// Do something (like configure log4net)
	AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;

private static Assembly CurrentDomain_AssemblyResolve(object sender,  ResolveEventArgs args)
	return AssemblyResolveUtils.TryLoadAssembly(...);

It is a little bit unbelievable – according to “trivial” information everywhere this should not be possible – but it works!

posted on Tuesday, May 31, 2011 8:30 AM