using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace DoLittle.Framework { public class CrossAppDomainSingleton : MarshalByRefObject where T:new() { private static readonly string AppDomainName = "Singleton AppDomain"; private static T _instance; private static AppDomain GetAppDomain(string friendlyName) { IntPtr enumHandle = IntPtr.Zero; mscoree.CorRuntimeHostClass host = new mscoree.CorRuntimeHostClass(); try { host.EnumDomains(out enumHandle); object domain = null; while (true) { host.NextDomain(enumHandle, out domain); if (domain == null) { break; } AppDomain appDomain = (AppDomain)domain; if( appDomain.FriendlyName.Equals(friendlyName) ) { return appDomain; } } } finally { host.CloseEnum(enumHandle); Marshal.ReleaseComObject(host); host = null; } return null; } public static T Instance { get { if (null == _instance) { AppDomain appDomain = GetAppDomain(AppDomainName); if (null == appDomain) { appDomain = AppDomain.CreateDomain(AppDomainName); } Type type = typeof(T); T instance = (T)appDomain.GetData(type.FullName); if (null == instance) { instance = (T)appDomain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName); appDomain.SetData(type.FullName, instance); } _instance = instance; } return _instance; } } } public class MySingleton : CrossAppDomainSingleton { public void HelloWorld() { Console.WriteLine("Hello world from '" + AppDomain.CurrentDomain.FriendlyName + " (" + AppDomain.CurrentDomain.Id + ")'"); } } public class TestClass : MarshalByRefObject { public void TestMethod() { Console.WriteLine("**** Test method running in '" + AppDomain.CurrentDomain.FriendlyName + " (" + AppDomain.CurrentDomain.Id + ")' ****"); MySingleton.Instance.HelloWorld(); Console.WriteLine("\n\n"); } } class Program { static void Main(string[] args) { Console.WriteLine("**** Call HelloWorld in root appdomain '" + AppDomain.CurrentDomain.FriendlyName + " (" + AppDomain.CurrentDomain.Id + ")' ****"); MySingleton.Instance.HelloWorld(); Console.WriteLine("\n\n"); AppDomain dataDomain = AppDomain.CreateDomain("Data Domain"); AppDomain logicDomain = AppDomain.CreateDomain("Business Logic Domain"); Type testClassType = typeof(TestClass); TestClass dataDomainTestClass = (TestClass)dataDomain.CreateInstanceAndUnwrap(testClassType.Assembly.FullName,testClassType.FullName); TestClass logicDomainTestClass = (TestClass)logicDomain.CreateInstanceAndUnwrap(testClassType.Assembly.FullName, testClassType.FullName); dataDomainTestClass.TestMethod(); logicDomainTestClass.TestMethod(); } } }