Jeffrey Palermo (.com)

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Run features in a separate AppDomain - level 300

Along with putting feature dlls in a separate directory with the shared assemblies they need, I like to run these features in an isolated AppDomain to contain memory usage as well as state.  When using Trace for logging, this is a great benefit because application state is local to the AppDomain, so my Trace.Listeners collection is dedicated to the AppDomain.  Here's an easy sample showing how to do this:

            Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

            Trace.WriteLine("Starting MainClass");

       

            AppDomainSetup setup = new AppDomainSetup();

            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; // or another directory.

            setup.ApplicationName = "My Domain";

            AppDomain ad = AppDomain.CreateDomain("CreateDomain", null, setup);

            object o = ad.CreateInstanceAndUnwrap("BusinessLogic", "BusinessLogic.BusinessLogic");

            Trace.WriteLine(o.ToString());

       

            Trace.WriteLine("DONE testing appdomain.  Now testing process");

            Console.ReadLine();

And here is my BusinessLogic class I contrived for this test:

namespace BusinessLogic

{

    /// <summary>

    /// Summary description for Class1.

    /// </summary>

    [Serializable()]

    public class BusinessLogic : MarshalByRefObject

    {

        public override string ToString(){

            System.Diagnostics.Trace.WriteLine("From Business Logic");

            string retValue = "Information about current runtime:\n";

            retValue += "Current AppDomain location: " + AppDomain.CurrentDomain.BaseDirectory + "\n";

            retValue += "Executing Assembly FullName: " + Assembly.GetExecutingAssembly().ToString() + "\n";

            retValue += "BusinessLogic location: " + Assembly.GetExecutingAssembly().Location + "\n";

            retValue += "Framework Assembly FullName: " + typeof(Audit).Assembly.ToString() + "\n";

            retValue += "Framework location" + typeof(Audit).Assembly.Location + "\n";

            return retValue;

        }

        public override bool Equals(object obj) {

            throw new Exception("BOMB");

            return base.Equals (obj);

        }

    }

}

 

Notice how I marked the class as Serializable.  And don't forget to mark other classes that  you may need to pass back and forth (not many, I hope).  I also have to inherit my object from MarshalByRefObject because my initial call is directly to this object.  Any exceptions that may be raised up back to the parent AppDomain must also be Serialiable and implemet a Serialization constructor. 

I love this model for code and state isolation, and it has made my life so much easier!


Posted 02-22-2005 4:58 PM by Jeffrey Palermo

[Advertisement]

Comments

Hasani wrote re: Run features in a separate AppDomain - level 300
on 02-23-2005 12:36 PM
You don't need to have the class marked as serializable or derive from MarshalByRefObject to work across domains. If you use AppDomain.GetData/SetData, the runtime will marshal the object for you. I created a class, TelnetTraceListener, that derives from TraceListener and it works flawlessly across app domains via AppDomain.GetData/AppDomain.SetData.
Hasani wrote re: Run features in a separate AppDomain - level 300
on 02-26-2005 1:40 PM
Also want to add that because I was using remoting, my objects would sometimes expire (The lease time). To prevent this, I had to override the method InitializeLifetimeService.
John M wrote re: Run features in a separate AppDomain - level 300
on 06-12-2007 7:38 PM

What is (Audit) in the BusinessLogic class referring to?