Ensuring Singletons

Singleton.cs
01/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 02using System; 03using Db4objects.Db4o; 04using Db4objects.Db4o.Query; 05using Sharpen.Lang; 06 07namespace Db4objects.Db4odoc.Semaphores 08{ 09 /** 10 * This class demonstrates the use of a semaphore to ensure that only 11 * one instance of a certain class is stored to an IObjectContainer. 12 * 13 * Caution !!! The getSingleton method contains a commit() call. 14 */ 15 public class Singleton 16 { 17 /** 18 * returns a singleton object of one class for an IObjectContainer. 19 * <br><b>Caution !!! This method contains a commit() call.</b> 20 */ 21 public static Object GetSingleton(IObjectContainer objectContainer, Class clazz) 22 { 23 Object obj = queryForSingletonClass(objectContainer, clazz); 24 if (obj != null) 25 { 26 return obj; 27 } 28 29 String semaphore = "Singleton#getSingleton_" + clazz.GetName(); 30 31 if (!objectContainer.Ext().SetSemaphore(semaphore, 10000)) 32 { 33 throw new Exception("Blocked semaphore " + semaphore); 34 } 35 36 obj = queryForSingletonClass(objectContainer, clazz); 37 38 if (obj == null) 39 { 40 41 try 42 { 43 obj = clazz.NewInstance(); 44 } 45 catch (Exception e) 46 { 47 System.Console.WriteLine(e.Message); 48 } 49 50 objectContainer.Set(obj); 51 52 /* !!! CAUTION !!! 53 * There is a commit call here. 54 * 55 * The commit call is necessary, so other transactions 56 * can see the new inserted object. 57 */ 58 objectContainer.Commit(); 59 60 } 61 62 objectContainer.Ext().ReleaseSemaphore(semaphore); 63 64 return obj; 65 } 66 67 private static Object queryForSingletonClass(IObjectContainer objectContainer, Sharpen.Lang.Class clazz) 68 { 69 IQuery q = objectContainer.Query(); 70 q.Constrain(clazz); 71 IObjectSet objectSet = q.Execute(); 72 if (objectSet.Size() == 1) 73 { 74 return objectSet.Next(); 75 } 76 if (objectSet.Size() > 1) 77 { 78 throw new Exception( 79 "Singleton problem. Multiple instances of: " + clazz.GetName()); 80 } 81 return null; 82 } 83 84 } 85 86}

Singleton.vb
01' Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com 02Imports System 03Imports Db4objects.Db4o 04Imports Db4objects.Db4o.Query 05 06Namespace Db4objects.Db4odoc.Semaphores 07 ' This class demonstrates the use of a semaphore to ensure that only 08 ' one instance of a certain class is stored to an IObjectContainer. 09 ' 10 ' Caution !!! The getSingleton method contains a commit() call. 11 12 Public Class Singleton 13 14 ' returns a singleton object of one class for an IObjectContainer. 15 ' Caution !!! This method contains a commit() call. 16 17 Public Shared Function GetSingleton(ByVal objectContainer As IObjectContainer, ByVal clazz As System.Type) As Object 18 Dim obj As Object = queryForSingletonClass(objectContainer, clazz) 19 If Not obj Is Nothing Then 20 Return obj 21 End If 22 23 Dim semaphore As String = "Singleton#getSingleton_" + clazz.FullName 24 25 If Not objectContainer.Ext().SetSemaphore(semaphore, 10000) Then 26 Throw New Exception("Blocked semaphore " + semaphore) 27 End If 28 29 obj = queryForSingletonClass(objectContainer, clazz) 30 31 If obj Is Nothing Then 32 33 Try 34 obj = System.Activator.CreateInstance(clazz) 35 Catch e As Exception 36 System.Console.WriteLine(e.Message) 37 End Try 38 39 objectContainer.Set(obj) 40 ' Not Not Not CAUTION Not Not Not 41 ' * There is a commit call here. 42 ' * 43 ' * The commit call is necessary, so other transactions 44 ' * can see the New inserted Object. 45 ' */ 46 objectContainer.Commit() 47 48 End If 49 50 objectContainer.Ext().ReleaseSemaphore(semaphore) 51 52 Return obj 53 End Function 54 55 Private Shared Function queryForSingletonClass(ByVal objectContainer As IObjectContainer, ByVal clazz As System.Type) As Object 56 Dim q As IQuery = objectContainer.Query() 57 q.Constrain(clazz) 58 Dim objectSet As IObjectSet = q.Execute() 59 If objectSet.Size() = 1 Then 60 Return objectSet.Next() 61 End If 62 If objectSet.Size() > 1 Then 63 Throw New Exception("Singleton problem. Multiple instances of: " + clazz.FullName) 64 End If 65 Return Nothing 66 End Function 67 68 End Class 69 70End Namespace