Archive for April 2010

What is an Application Domain and what is it used for?

leave a comment »

I recently had to work with some large legacy .net 2.0 system and it did made heavy use of Application Domains. I did have general knowledge about what an Application Domain is, but wasn’t familiar with other basic topics like communication between AppDomains and memory recollection. So, in this post I’ll share what I’ve learned on the topic.

You can imagine an Application Domain as a logical container in which you can load assemblies. An application domain lives inside a process and you can have many application domains living at the same time inside the same process (see figure below).

ApplicationDomains Image

In the above image we have C# SampleConsoleApplication executable. When you start the executable a SampleConsoleApplication process is created, then the CLR creates a default AppDomain for your code.  In this case, the default domain is the SampleConsoleApplication domain and, as you can see, the CLR also loaded other assemblies referenced by SampleConsoleApplication into this default domain (like System.dll).

Next, let’s say you want your SampleConsoleApplication to use classes from another library, ClassLibrary1. Normally you would just reference ClassLibrary1. But there are scenarios where you don’t want to do that. A few scenarios I can think is:

  1. You have an application that supports plug-ins (e.g. MMC, SAP, etc). Presume¬† ClassLibrary1 is a plug-in written by a 3rd Party. You have to isolate ClassLibrary1 from a security and reliability point of view. From a security point of view you don’t want ClassLibrary1 to access your directly code (MMC/SAP code in this case) because it might be malicious. From reliability point of view, even if ClassLibrary1 is not malicious it still might have bugs in implementation that you couldn’t just ignore using a try catch. For example it could have a memory leak and, if you were referencing it directly, it would cause your memory usage to keep growing and never be recollected even after you don’t use ClassLibrary1 classes anymore.
  2. Other examples: You are writing a web-server like IIS. Unintentionally somebody could have bugs in his ASP.NET web-site that could crash your web server.  You want complete isolation here, but without creating one process for each web-site. Why? Processes are very expensive to create form both performance and initial memory footprint point of view. Your web-server would be slow and would accommodate a lower number of web-sites as opposed to if you were using an ApplicationDomain for each web-site.
  3. You are writing a real-time system that processes data received from instruments (e.g. various blood analyzers). Some of the processing steps are done by various libraries written by various companies and could fail because a type of instrument is malfunctioning, a bug in the code, etc. You could use an application domain to isolate 3rd party processing failures, and simply unload problematic processings when they happen, leaving the core of the system to continue functioning and process data.

I guess, you see the pattern by now. Application Domains can help you isolate code from a security, resource usage, exceptions point of view without creating new processes. They can also be unloaded when you either finish using them or code inside them is causing problems.

To provide this level of isolation, you are not allowed to use types from an AppDomain in another AppDomain directly. Instead when you need to use a class from another AppDomain you can use either remoting or WCF. (See http://stackoverflow.com/questions/1294494/is-net-remoting-really-deprecated)

If you’re stuck with maintaining a legacy system that uses remoting keep on reading.

If you’re using remoting, there are two important ways by which you can send one object from one AppDomain to another.

  1. Marshaling by Value: You have a class that is marked as serializable. When you create an instance of that class and pass it to another domain, as a parameter in a function call for example, you are actually serializing/deserializing it. This is Marshaling by Value.
  2. Marshaling by Reference: In some cases it doesn’t make sense to serialize a class and send it to another AppDomain serialized, because the class contains members that are specific to a single application domain. For example: Suppose you have a class member that is a reference to socket, a filehandle, a db connection. Once serialized, those references would be invalid in the receiving AppDomain. In this case you have your class inheriting from MarshalByRefObject and when you instantiate it in another AppDomain a TransparentProxy is created for it. For example you have a DataAccess class that contains a method InsertPerson(string name) that opens a db connection and inserts a person in a database. When you instantiate it in another AppDomain a class identical to your class (having same name, same public methods, same public properties) is created instead. This is called a TransparentProxy. When you call InsertPerson on it, it will make a remote call to an instance of type DataAccess living in the first AppDomain, which will perform the operation and send the result back. (it’s enough if you imagine the remote call as web-service call).

I hope this abstraction suffices your needs.


Written by Liviu Trifoi

April 21, 2010 at 5:26 pm