The process contains one or more Application Domains.
The application domains provides the same level of isolation as processes: address spaces of Application Domain data are isolated; to pass data, a special simplified IPC-like mechanisms are used (and "real" IPC could of course be used to pass data, such as sockets, named pipes, etc, but why?).
One of the very important but little known reasons for such additional level of separation is such a fundamental .NET feature as the dynamic assembly loading with reflection. The problem is: you can load an assembly, but you cannot unload it. This is the important security feature. If you need some reloadable components, such as plug-ins, you can load assemblies over and over, but there is no a way to unload them, which is a big memory leak. (Yes, there can be memory leaks in .NET, despite of managed memory; this is just one of the ways to create a leak.) What to do in this case? You can create a separate Application Domain, load your temporary assembly in it, use it, and when you need to re-load the assembly, you can unload the whole Application Domain. Why is that safe? Because Application Domains are isolated; so you cannot possibly use anything acceptable but already unloaded.
For further understanding of Application Domain ideas, please read about them:
http://en.wikipedia.org/wiki/Application_domain[
^],
http://msdn.microsoft.com/en-us/library/dah4cwez.aspx[
^],
http://msdn.microsoft.com/en-us/library/yb506139.aspx[
^].
[EDIT]
As to "examples", there are code samples on each of the topics referenced from this MSDN page:
http://msdn.microsoft.com/en-us/library/yb506139.aspx[
^].
There are more example in MSDN help pages. You really need to see them, before you can ask more productive questions.
—SA