Blog'A'Little

Just another C# guy

CrossAppDomainSingleton - Update

I forgot a couple of very essential things in my last post about a singleton that lives across appdomains.

When accessing a remote object using remoting, like I did with the singleton implementation, the remoting system obtains a lease for the object. The lease period is implemented in the MarshalByRefObject class through a method called InitializeLifeTimeService(). A singleton like the one we wanted to achieve needs to live forever, therefor you need to override the InitializeLifeTimeService() method and always return null. Returning null means that it should live forever (more details can be at http://msdn.microsoft.com/msdnmag/issues/03/12/LeaseManager/default.aspx)

1
2
3
4
5
6
7
8
9
10
11
12
13
    /// <summary>
    /// Override of lifetime service initialization.
    ///
    /// The reason for overriding is to have this singleton live forever
    /// </summary>
    /// <returns>object for the lease period - in our case always null</returns>
    public override object InitializeLifetimeService()
    {
      // We want this singleton to live forever
      // In order to have the lease across appdomains live forever,
      // we return null.
      return null;
    }

In addition I've made it all threadsafe. So look at the attachment for this post instead..

On a second note; if you for instance expose an event in your singleton and any subscribers to that event exists in another AppDomain, you might want to keep in mind that you should probably inherit from MarshalByRefObject and override the IntializeLifeTimeService() method and return null there as well. Otherwize you might end up having a broken lease in the delegate added to the singleton.

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

Comments

Jesse Chisholm said:

I'm surprised this hasn't had any comments in over a year.

Thanks for the improvements.

What is the best way to kill this singleton as part of an explicit clean application shutdown?

-Jesse

kick it on DotNetKicks.com kick it on GameDevKicks.com
# september 26, 2008 2:24

baimos said:

Hi, I have one question. What about private constructor? If I don't make a mistake the code line appDomain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName) will throw exception in such case.

kick it on DotNetKicks.com kick it on GameDevKicks.com
# oktober 15, 2008 4:21

Egor said:

Thanks for this, it gave me a great head start. I just wanted to say that your update is broken - it misses the singletony part of it, a new instance will be created for every domain. You need to include this part from the original:

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);

    }

kick it on DotNetKicks.com kick it on GameDevKicks.com
# februar 20, 2009 1:59
Leave a Comment

(required) 

(required) 

(optional)

(required) 

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