Blog'A'Little

Just another C# guy

Cross AppDomain Singleton

PS: There is an addition to this post that you can find here 

One thing that I find a bit inconvient from time to time is the lack of shared memory between appdomains. Today I figured I had to find a way of doing this, so I created a CrossAppDomainSingleton class that has it's implementation and data shared between AppDomains.

The solution we want is that the singleton class is created in a given AppDomain and in all other AppDomains we get a transparent proxy to that singleton. 

In order to do this we need to have the ability to enumerate through existing AppDomains in order to create an instance in the correct AppDomain (at least I found this to be cool way of doing it). I came across a thread on microsoft.public.dotnet.framework.clr that gave me a good solution (http://groups.google.com/group/microsoft.public.dotnet.framework.clr/browse_frm/thread/dba9c445ad8d5c3/9df14bf0af393c28?lnk=st&q=enumerate+appdomain+group%3Amicrosoft.public.dot%20net.*&rnum=5#9df14bf0af393c28)

You need to add a reference to the mscoree.tlb which is situated in the .net directory (c:\windows\microsoft.net\framework\v2.0.50727). When you add a reference to it you'll get an Interop.mscoree.dll added to your output directory. You will have to have this alongside your deployment if you're going to use this in a solution.

With my modifications, we get a method that finds a AppDomain based upon the friendly name. If it doesn't find it, it returns null..


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  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;
}

The full implementation of the class is then :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 public class CrossAppDomainSingleton<T> : 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;
}
}
}

This class is not thread safe, so that bit needs to be added..

To use the class you do the following :

1
2
3
4
5
6
7
8
 public class MySingleton : CrossAppDomainSingleton<MySingleton>
{

public void HelloWorld()
{
Console.WriteLine("Hello world from '" + AppDomain.CurrentDomain.FriendlyName + " (" + AppDomain.CurrentDomain.Id + ")'");
}
}

Look at the attachment to this blog for the entire C# sample file!!

 

kick it on DotNetKicks.com kick it on GameDevKicks.com

Comments

Marcin Buciora said:

COOL!!!!

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 11, 2008 12:22

Einar Ingebrigtsen said:

Thanks. I've working on a new version that will work with the compact framework as well. Involves quite a bit magic. :)  

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 11, 2008 10:48

Tini said:

Thank you soo much for this! really helpful.

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 23, 2008 10:39

Einar Ingebrigtsen said:

No problem. I'm glad it turned out helpful for you.

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 24, 2008 10:07

Delf said:

Thanks a lot for this generic singleton class. Now I should be able to get access to my singletons over App domains. This point is really appreciated when applications using plugins/modules that use application singletons.

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 25, 2008 11:48

Einar Ingebrigtsen said:

Glad to be of any assistance. You should also look at the update post for this :

www.dolittle.com/.../crossappdomainsingleton-update.aspx

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 25, 2008 5:42

CrossAppDomainSingleton - Update - Blog'A'Little said:

Pingback from  CrossAppDomainSingleton - Update - Blog&#39;A&#39;Little

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 25, 2008 6:14

Frederick Chapleau weBlog on IT. said:

The basic way to do a Plugin Framework, is to use a AppDomains, because you can Load &amp; Unload AppDomains

kick it on DotNetKicks.com kick it on GameDevKicks.com
# oktober 15, 2008 11:19

molly said:

htMlKq viTwQ937Baww5mLp1oWxu

kick it on DotNetKicks.com kick it on GameDevKicks.com
# august 18, 2009 4:24

payday loans said:

Your website is very interesting. I enjoyed your website a lot. Thank you.

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 2, 2010 4:49

PetrKunkAlpinist1977 said:

Da haste dir aber viel m�he gegeben

Den Eiger in 2,47 Stunden zu besteigen w�hre wohl vor 70Jahren nicht moeglich gewesen

Respekt Ueli Steck!

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 3, 2010 1:33

http://uxjqzz.com/ said:

VSQmbDHa

kick it on DotNetKicks.com kick it on GameDevKicks.com
# juli 26, 2010 11:54
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Design downloaded from Free Templates - your source for free web templates