Skip to content

Commit

Permalink
Fixing formatting and including referenced file
Browse files Browse the repository at this point in the history
  • Loading branch information
einari committed Feb 29, 2024
1 parent d4648d2 commit f9d9637
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 259 deletions.
364 changes: 105 additions & 259 deletions _posts/2007/05/cross-appdomain-singleton/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,284 +18,130 @@ You need to add a reference to the mscoree.tlb which is situated in the .net dir

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..

```csharp
private static AppDomain GetAppDomain(string friendlyName)

{

IntPtr enumHandle = IntPtr.Zero;

mscoree.CorRuntimeHostClass host =

new mscoree.CorRuntimeHostClass();

try

{
IntPtr enumHandle = IntPtr.Zero;
mscoree.CorRuntimeHostClass host = new mscoree.CorRuntimeHostClass();

host.EnumDomains(out enumHandle);

object domain = null;

while (true)

{

host.NextDomain(enumHandle, out domain);

if (domain == null)
try
{
host.EnumDomains(out enumHandle);

break;
object domain = null;

AppDomain appDomain = (AppDomain)domain;
while (true)
{
host.NextDomain(enumHandle, out domain);

if( appDomain.FriendlyName.Equals(friendlyName) )
if (domain == null)
break;

return appDomain;
AppDomain appDomain = (AppDomain)domain;

}
if( appDomain.FriendlyName.Equals(friendlyName) )
return appDomain;
}
}
finally
{
host.CloseEnum(enumHandle);
Marshal.ReleaseComObject(host);
host = null;
}

return null;
}
```

finally
The full implementation of the class is then :

```csharp
public class CrossAppDomainSingleton<T> : MarshalByRefObject where T:new()
{

host.CloseEnum(enumHandle);

Marshal.ReleaseComObject(host);

host = null;

}

returnnull;

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.FullN ame, type.FullName);
appDomain.SetData(type.FullName, instance);
}

_instance = instance;
}

return _instance;
}
}
}

<table style="background-color:#f2f2f2;border:#e5e5e5 1px solid;" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody><tr style="vertical-align:top;line-height:normal;"><td style="width:40px;text-align:right;"><pre style="border-right:#e7e7e7 1px solid;font-size:11px;margin:0;color:gray;font-family:courier new;padding:2px;">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</pre></td><td><pre style="margin:0;padding:2px 2px 2px 8px;"><span style="font-weight:normal;font-size:11px;color:black;font-family:Courier New;background-color:transparent;"> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">private</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">static</span> AppDomain GetAppDomain(<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">string</span> friendlyName)
{
IntPtr enumHandle <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> IntPtr.Zero;
mscoree.CorRuntimeHostClass host <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">new</span> mscoree.CorRuntimeHostClass();
<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">try</span>
{
host.EnumDomains(<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">out</span> enumHandle);</span></pre><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">object</span> domain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">while</span> (<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">true</span>) { host.NextDomain(enumHandle, <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">out</span> domain); <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span> (domain == <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>) { <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">break</span>; } AppDomain appDomain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> (AppDomain)domain; <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span>( appDomain.FriendlyName.Equals(friendlyName) ) { <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">return</span> appDomain; } } } <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">finally</span> { host.CloseEnum(enumHandle); Marshal.ReleaseComObject(host); host <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; } <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">return</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; }</td></tr></tbody></table>

The full implementation of the class is then :

<table style="background-color:#f2f2f2;border:#e5e5e5 1px solid;" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody><tr style="vertical-align:top;line-height:normal;"><td style="width:40px;text-align:right;"><pre style="border-right:#e7e7e7 1px solid;font-size:11px;margin:0;color:gray;font-family:courier new;padding:2px;">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</pre></td><td><pre style="margin:0;padding:2px 2px 2px 8px;"><span style="font-weight:normal;font-size:11px;color:black;font-family:Courier New;background-color:transparent;"> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">public</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">class</span> CrossAppDomainSingleton&lt;T&gt; : MarshalByRefObject where T:<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">new</span>()
{
<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">private</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">static</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">readonly</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">string</span> AppDomainName <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:#666666;font-family:Courier New;background-color:#e4e4e4;">"Singleton AppDomain"</span>;
<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">private</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">static</span> T _instance;</span></pre><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">private</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">static</span> AppDomain GetAppDomain(<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">string</span> friendlyName) { IntPtr enumHandle <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> IntPtr.Zero; mscoree.CorRuntimeHostClass host <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">new</span> mscoree.CorRuntimeHostClass(); <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">try</span> { host.EnumDomains(<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">out</span> enumHandle);<div></div><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">object</span> domain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">while</span> (<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">true</span>) { host.NextDomain(enumHandle, <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">out</span> domain); <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span> (domain == <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>) { <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">break</span>; } AppDomain appDomain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> (AppDomain)domain; <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span>( appDomain.FriendlyName.Equals(friendlyName) ) { <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">return</span> appDomain; } } } <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">finally</span> { host.CloseEnum(enumHandle); Marshal.ReleaseComObject(host); host <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; } <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">return</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span>; }<div></div><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">public</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">static</span> T Instance { get { <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span> (<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span> == _instance) { AppDomain appDomain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> GetAppDomain(AppDomainName); <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span> (<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span> == appDomain) { appDomain <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> AppDomain.CreateDomain(AppDomainName); } Type type <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">typeof</span>(T); T instance <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> (T)appDomain.GetData(type.FullName); <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">if</span> (<span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">null</span> == instance) { instance <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> (T)appDomain.CreateInstanceAndUnwrap(type.Assembly.FullN ame, type.FullName); appDomain.SetData(type.FullName, instance); } _instance <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">=</span> instance; }<div></div><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">return</span> _instance; } } }</td></tr></tbody></table>
```

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

To use the class you do the following :

<table style="background-color:#f2f2f2;border:#e5e5e5 1px solid;" border="0" width="100%" cellspacing="0" cellpadding="0"><tbody><tr style="vertical-align:top;line-height:normal;"><td style="width:40px;text-align:right;"><pre style="border-right:#e7e7e7 1px solid;font-size:11px;margin:0;color:gray;font-family:courier new;padding:2px;">1
2
3
4
5
6
7
8</pre></td><td><pre style="margin:0;padding:2px 2px 2px 8px;"><span style="font-weight:normal;font-size:11px;color:black;font-family:Courier New;background-color:transparent;"> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">public</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">class</span> MySingleton : CrossAppDomainSingleton&lt;MySingleton&gt;
{</span></pre><span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">public</span> <span style="font-weight:normal;font-size:11px;color:blue;font-family:Courier New;background-color:transparent;">void</span> HelloWorld() { Console.WriteLine(<span style="font-weight:normal;font-size:11px;color:#666666;font-family:Courier New;background-color:#e4e4e4;">"Hello world from '"</span> <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">+</span> AppDomain.CurrentDomain.FriendlyName <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">+</span> <span style="font-weight:normal;font-size:11px;color:#666666;font-family:Courier New;background-color:#e4e4e4;">" ("</span> <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">+</span> AppDomain.CurrentDomain.Id <span style="font-weight:normal;font-size:11px;color:red;font-family:Courier New;background-color:transparent;">+</span> <span style="font-weight:normal;font-size:11px;color:#666666;font-family:Courier New;background-color:#e4e4e4;">")'"</span>); } }</td></tr></tbody></table>

Look at the entire C# sample file from [here](http://localhost:8080/wp-content/2014/10/crossappdomainsingleton1.zip)

private static AppDomain GetAppDomain(string friendlyName) 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)

```csharp
public class MySingleton : CrossAppDomainSingleton<MySingleton>
{

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;

}

{

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;

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

return null;

}
Look at the entire C# sample file from [here](/assets/posts/2007/05/crossappdomainsingleton1.zip)
Binary file added assets/posts/2007/05/crossappdomainsingleton1.zip
Binary file not shown.

0 comments on commit f9d9637

Please sign in to comment.