AppDomain

Now you have a brief understanding about what a Thread is. At this point, you will learn about the environment in which every Thread runs, and that is the AppDomain. In the unmanaged world, a system had multiple processes, and each process had one or more threads. In the managed world, the system still has many processes, but it now has an additional boundary called the AppDomain. An AppDomain has been described as a lightweight process. Although this is mostly correct conceptually in that AppDomains provide isolation like a process for security, faults, and errors, when it comes to Threads, the AppDomain no longer seems like a process. Threads can easily weave in and out of an AppDomain, which is very much unlike a process.

An AppDomain supports and encapsulates a substantial amount of security information, but that will not be discussed here. The AppDomain class encapsulates the AppDomain, so a good place to start reading about AppDomains would be in the SDK documentation on the AppDomain class. For instance, you can find out about all of the assemblies that are loaded on behalf of the AppDomain. Listing 11.9 shows how to get at some of the properties available from the AppDomain class. The source for this sample is available as part of the AppDomain solution in the AppDomainAssemblyList directory.

Listing 11.9. AppDomain Properties
using System;
using System.Reflection;

namespace AppDomainTest
{
    class AssemblyList
    {
        static void Main(string[] args)
        {
            AppDomain ad = AppDomain.CurrentDomain;
            Assembly [] assemblyList = ad.GetAssemblies();
            Console.WriteLine("There are {0}  assemblies loaded in this AppDomain",
 assemblyList.Length);
            foreach(Assembly a in assemblyList)
            {
                Console.WriteLine(a.FullName);
            }
            Console.WriteLine("Base directory: {0} ", ad.BaseDirectory);
        }
    }
}

You can access much of the information about the AppDomain in which you are running. Although this is interesting and important, what you really want to do is create your own AppDomain.

When I created my first AppDomain and made calls into the loaded AppDomain, it seemed a lot like inproc COM, or for that matter COM in general. I don't know what I was expecting, but the interface to the “other” AppDomain seemed so seamless that I immediately wanted to find a tool that told me that I was indeed talking to an AppDomain that I created. Listings 11.10 and 11.11 are in essence the “Hello World!” for creating AppDomains. Listing 11.10 shows how to create, load, and communicate with an AppDomain. The source for this sample is available as part of the AppDomain solution in the AppDomainCreateAppDomain directory.

Listing 11.10. AppDomain Creation
using System;
using System.Threading;
using System.Reflection;
using System.Runtime.Remoting;
using InterAppDomain;

namespace AppDomainTest
{
    class InterAppDomain
    {
        static void Main(string[] args)
        {
            // Set ApplicationBase to the current directory
            AppDomainSetup info = new AppDomainSetup();
            info.ApplicationBase = "file:\\" +
System.Environment.CurrentDirectory;

             // Create an application domain with null evidence
            AppDomain dom = AppDomain.CreateDomain("RemoteDomain", null, info);

            // Load the assembly HelloWorld and instantiate the type
            // HelloWorld
            BindingFlags flags = (BindingFlags.Public | BindingFlags.Instance |
 BindingFlags.CreateInstance);
            ObjectHandle objh = dom.CreateInstance("HelloWorld", "InterAppDomain
.HelloWorld", false, flags, null, null, null, null, null);
            if (objh == null)
            {
                Console.WriteLine("CreateInstance failed");
                return;
            }

            // Unwrap the object
            Object obj = objh.Unwrap();

            // Cast to the actual type
            HelloWorld h = (HelloWorld)obj;

            Console.WriteLine("In the application domain: {0}  thread {1} ", Thread
.GetDomain().FriendlyName, Thread.CurrentThread.GetHashCode());
            // Invoke the method
            h.SayHello("Hello World!");

            // Clean up by unloading the application domain
            AppDomain.Unload(dom);
        }
    }
}

First, notice that you need a reference to the Assembly that you will be loading. Second, you create the AppDomainSetup class. You could set many properties on this class, but for now, you are only interested in the directory path at which your Assembly can be found. Here it is the same directory as the working directory of the application. Third, you actually create an AppDomain. The first argument is the name of the AppDomain. Like giving a name to a Thread can help debugging run a little more smoothly, giving a name to an AppDomain is not required, but it makes life easier for whomever needs to debug this application. The next argument to CreateDomain is an instance of an Evidence class. This is where you would prove that this assembly is okay. You set it to null. The final argument is the AppDomainSetup that was created earlier.

After the AppDomain has been created, you create an instance of the object with which you want to communicate using CreateInstance. CreateInstance has many arguments, most of which you set to null. The first argument is the name of the Assembly followed by the name of the type within the Assembly in which you are interested. The third argument flags whether you are interested in case. The fourth argument is a set of flags indicating how the Assembly is to search for your type.

using InterAppDomain;

This at first seems like cheating. How are you to know that you are really talking to a remote Assembly and not the copy of the DLL that is loaded right here? You need it because the object, or at least a handle to the object, will be instantiated on this side, so you need to know the signatures of the methods that you can call. Essentially, you need type-library information.

Listing 11.11 shows the Assembly that you are loading. The source for this sample is available as part of the AppDomain solution in the AppDomainCreateAppDomainHelloWorld directory.

Listing 11.11. AppDomain Assembly
using System;
using System.Threading;
namespace InterAppDomain
{
    public class HelloWorld : MarshalByRefObject
    {
        public void SayHello(String greeting)
        {
            if (greeting == null)
            {
                throw new ArgumentNullException("Null greeting!");
            }
            Console.WriteLine("In the application domain: {0}  thread {1} ", Thread
.GetDomain().FriendlyName, Thread.CurrentThread.GetHashCode());
            Console.WriteLine(greeting);
        }
    }
}

Not much is involved in the process. You just print out the name of the AppDomain and the Thread ID so that you can compare them to the printout before the AppDomain was entered.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.227.194