My personal project for almost 4 years now, Code Toaster, is almost ready to show to the world (again, if you've been following this blog for a while). Code Toaster is an Integrated IDE, and libraries, for rapid creation of developing code generation templates. You can find a lot more information over at http://www.codetoaster.com/, including documentation, code samples, and video tutorials. But in this post, I'd like to take a look at a few of the more difficult architectural challenges I faced when building Code Toaster, all of which were solved by taking advantage (or working around issues with) the .Net Application Domain (aka AppDomain). But first, some background information. The AppDomain A .Net process consists of one or more Application Domains, which are used to provide code isolation, security, and so forth. Code running in one Application Domain cannot directly invoke code running in another Application Domain, however methods on the AppDomain class make it possible to load a .Net assembly into a new AppDomain, create an instance of a class in that assembly, and invoke its properties and methods. AppDomain's are important to Code Toaster for several reasons. The foremost is that, once an assembly is loaded into an AppDomain using Assembly.Load (or one of its associated methods), the assembly cannot be unloaded from the AppDomain. In several cases it's necessary for Code Toaster to temporarily load an assembly to retrieve type (or other) information contained in an assembly, and then unload the assembly to reclaim the memory used. Scenarios that benefited from using AppDomains The figure below shows how Visual Studio attaches to a separate AppDomain within the CodeToaster.exe process, whose purpose is solely to contain and execute templates in isolation. This provides several benefits: In future posts I intend to take a closer look at the code that made all of this come together. For now, I invite you to head on over to http://www.codetoaster.com/ and check out the finest code generation tool ever made!
This was easier said than done. It's one thing to run some code in another AppDomain. It's quite another to load a Type in AppDomain B into a Property Explorer in AppDomain A, and have it appear and work correctly, with the appropriate adornments for UITypeEditors and so forth (see the figure to the left : the template BDC.Sample is loaded in another AppDomain, but appears correctly in the Template Property Explorer).
Wednesday, October 1, 2008
Code Toaster AppDomain Magic
Another very important scenario occurs when debugging templates. Attaching the Visual Studio debugger to a template executing in Code Toaster's AppDomain causes the Code Toaster process (codetoaster.exe) to end when the debugger detaches. This is not unique to Code Toaster: the popular CodeSmith code generation tool suffers from the same problem. As I was later to discover, executing templates in their own AppDomain causes debugging to operate as desired (detaching the debugger does not kill the process).