CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.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!



Comments

Hasani said:

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.
# February 26, 2005 1:40 PM

John M said:

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

# June 12, 2007 7:38 PM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com