Singleton Objects, C#


This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.

Singleton objects ensure that a class has only one instance and provide a global point of access to it. Some classes must have exactly one and only one instance in a system. A global variable makes an object accessible, but it does not keep you from instantiating multiple new objects. A better solution is to make the class itself responsible for keeping track of its sole instance. The class can ensure that no other instance is created by intercepting requests to create new objects, and it can provide a way to access the instance. The Singleton patterns are adequate when there must be exactly one instance of a class and it must be accessible from a well-known access point. They are adequate as well when the sole instance should be extensible by subclassing and clients should be able to use an extended instance without modifying their code.

There are two well-known object modes in SOAP .NET Remoting:

  • SingleCall: Every message is dispatched to a new object instance.
  • Singleton: Every message is dispatched to the same object instance.

The term singleton is a concept where a global object services all requests. The Singleton concept is a taken from Design Patterns. It is similar to CWinApp in Microsoft Foundation Classes-the one and only application object. Although there can be many printers in a system, there should be only one printer spooler. There should be only one file system and one window manager. The Singleton object server is activated only once, and its destructor is never called unless we kill the server object explicitly. Notice that the variable returned by the server is not reset between different invocations of the client. This behavior demonstrates that the server does indeed preserve its state during its lifetime. Let's develop a sample Singleton application. Listing 23.11 shows the remote, singleton object to be created

Listing 23.11: Object Code2 (Listing23.11.cs)


// compile with:
// csc /t:library /out:object2.dll Listing23.11.cs


using
System;

namespace
ExampleRemoting
{
    public class DateTimeServer : MarshalByRefObject
    {
        private static int iSayac = 0;
        public DateTimeServer()
        {
            Console.WriteLine("DateTime server activated");
        }

        ~DateTimeServer()
        {
            Console.WriteLine("DateTime server Object Destroyed...");
        }

        public String MyMethod(String name)
        {
            String strMessage = "Hi " + name + ". Here is the current DateTime: " + DateTime.Now;
            Console.WriteLine(strMessage);
            return strMessage;
        }

        public int BeniSay()
        {
            // lock this object to prevent concurrent updates
            // to single instance lock(this)
            {
                Console.WriteLine("Counter: " + ++iSayac);
                return iSayac;
            }
        }
    }
}


Listing 23.12 displays the sample server code.

Listing 23.12: SOAP Server2 (Listing23.12.cs)


// compile with:
// csc /r:object2.dll Listing23.12.cs
/* sample output:
press <enter> to exit
DateTime server activated

Counter: 1
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 2
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 3
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 4
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 5
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 6
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 7
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 8
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 9
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

Counter: 10
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM
DateTime server Object Destroyed
*/


using
System;
using
System.Runtime.Remoting;
using
System.Runtime.Remoting.Channels;
using
System.Runtime.Remoting.Channels.Http;

namespace
ExampleRemoting
{
    public class Example
    {
        public static void Main()
        {
            ChannelServices.RegisterChannel(new HttpChannel(999));
            RemotingConfiguration.RegisterWellKnownServiceType(
            Type.GetType("ExampleRemoting.DateTimeServer, object2"),
            "server/SayDateTime.SOAP",
            WellKnownObjectMode.Singleton);
            System.Console.WriteLine("press <enter> to exit.");
            System.Console.ReadLine();
        }
    }
}


Listing 23.13 shows the sample client code. Note that we will use HTTP channels to connect to the remote object twice in a row.

Listing 23.13: SOAP Client2 (Listing23.13.cs)


/* after executing the Listing23.12.exe use the SOAPSUDS tool to create object2.dll
proxy:
soapsuds -url:http://127.0.0.1:999/server/SayDateTime.SOAP?WSDL -oa:object22.dll
*/
// compile with:
// csc /r:object22.dll Listing23.13.cs
/* sample output:
HttpChannel

1 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

2 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

3 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

4 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

5 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM
HttpChannel

6 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

7 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

8 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

9 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM

10 - HttpChannel
Hi Clown Bozo. Here is the current DateTime: 8/19/2002 4:02:28 AM
*/


using
System;
using
System.Runtime.Remoting;
using
System.Runtime.Remoting.Channels;
using
System.Runtime.Remoting.Channels.Http;

namespace
ExampleRemoting
{
    public class Client
    {
        public static void Main()
        {
            HttpChannel channel = new HttpChannel();
            ChannelServices.RegisterChannel(channel);
            Run(); // run 1st, singleton counter counts
            Run(); // run 2nd, singleton counter counts
        }

        public static void Run()
        {
            Console.WriteLine("HttpChannel.");
            DateTimeServer obj = (DateTimeServer)Activator.GetObject(
            typeof(DateTimeServer),
            "http://127.0.0.1:999/server/SayDateTime.SOAP");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(obj.BeniSay() + " - HttpChannel");
                Console.WriteLine(obj.MyMethod("Clown Bozo"));
            }
        }
    }
}


Conclusion

Hope this article would have helped you in understanding Singleton Objects using C#. See other articles on the website on .NET and C#.

visual C-sharp.jpg The Complete Visual C# Programmer's Guide covers most of the major components that make up C# and the .net environment. The book is geared toward the intermediate programmer, but contains enough material to satisfy the advanced developer.


Similar Articles