4

I am linking to the following question --> https://stackoverflow.com/a/2550935/46724 specifically Jon Skeet's code:

public sealed class Singleton
 {
     private static readonly Singleton instance = new Singleton();
     public static Singleton Instance { get { return instance; } }

     static Singleton() {}
     private Singleton() {}
 }

What I would like to know is where would I put any logic I need on Initialization? The private or static constructor? By logic, I mean my Singleton is my DapperLite connection so I need to Initialize the mapping like so:

Database = new SqliteDatabase<int>(myConn);
Database.Init();

EDIT: I am stuck on Compact Framework 3.5 and VS 2008 for reference.

Community
  • 1
  • 1
Refracted Paladin
  • 12,096
  • 33
  • 123
  • 233

2 Answers2

1

If you have any static field needed in your class it should initialized in this constructor static Singleton() {}for any other instance fields or property it should goes private Singleton() {} for more take a look at the following code

 public class Bus
    {
        // Static variable used by all Bus instances. 
        // Represents the time the first bus of the day starts its route. 
        protected static readonly DateTime globalStartTime;

        // Property for the number of each bus. 
        protected int RouteNumber { get; set; }

        // Static constructor to initialize the static variable. 
        // It is invoked before the first instance constructor is run. 
        static Bus()
        {
            globalStartTime = DateTime.Now;

            // The following statement produces the first line of output,  
            // and the line occurs only once.
            Console.WriteLine("Static constructor sets global start time to {0}",
                globalStartTime.ToLongTimeString());
        }

        // Instance constructor. 
        public Bus(int routeNum)
        {
            RouteNumber = routeNum;
            Console.WriteLine("Bus #{0} is created.", RouteNumber);
        }

        // Instance method. 
        public void Drive()
        {
            TimeSpan elapsedTime = DateTime.Now - globalStartTime;

            // For demonstration purposes we treat milliseconds as minutes to simulate 
            // actual bus times. Do not do this in your actual bus schedule program!
            Console.WriteLine("{0} is starting its route {1:N2} minutes after global start time {2}.",
                                    this.RouteNumber,
                                    elapsedTime.TotalMilliseconds,
                                    globalStartTime.ToShortTimeString());
        }
    }

    class TestBus
    {
        static void Main()
        {
            // The creation of this instance activates the static constructor.
            Bus bus1 = new Bus(71);

            // Create a second bus.
            Bus bus2 = new Bus(72);

            // Send bus1 on its way.
            bus1.Drive();

            // Wait for bus2 to warm up.
            System.Threading.Thread.Sleep(25);

            // Send bus2 on its way.
            bus2.Drive();

            // Keep the console window open in debug mode.
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }

so in your case is an instance initialization

 private Singleton() 
{
Database = new SqliteDatabase<int>(myConn);
Database.Init();
}
BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
  • Beware of the needs for thread safety. If you're using your singleton in a multithreaded environment, you have to take that into account. http://msdn.microsoft.com/en-us/library/ff650316.aspx – rory.ap Feb 07 '14 at 15:07
  • @K.B,What difference it will make if the database initialization is there in the static constructor? – Jimmy Feb 07 '14 at 15:07
  • @roryap: The usage of static constructor makes it thread safe.See(http://csharpindepth.com/Articles/General/Singleton.aspx) – Jimmy Feb 07 '14 at 15:08
  • @Jimmy -- right, but this answer uses an instance constructor. – rory.ap Feb 07 '14 at 15:10
0

Here's a link from Jon Skeet's book C# in Depth

If you're using .NET 4.0:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
        try 
        {
            Database = new SqliteDatabase<int>(myConn);
            Database.Init();
        }
        catch(Exception ex)
        {
           // Handle errors
        }
    }

}

EDIT: Pre-4.0, solution #4 from the provided link. Fully thread safe without locks, his preferred solution.

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
        try
        {
            Database = new SqliteDatabase<int>(myConn);
            Database.Init();
        }
        catch (Exception ex)
        {
            // Handle errors
        }
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}
Matt
  • 2,682
  • 1
  • 17
  • 24
  • Doh, thanks. Sorry for the "lazy" question apparently. As a follow up, I CAN'T use .net 4... – Refracted Paladin Feb 07 '14 at 14:34
  • 1
    @RefractedPaladin: it is always a good idea to include such important details in your question. I suggest edit that into your question, and mention which .net version you CAN use. – Dmitriy Khaykin Feb 07 '14 at 15:18
  • Also to more directly answer your question, you should do the initialization in the instance constructor if you at any point need to reference that connection (though you really shouldn't be leaving it open). Otherwise I think it's a matter of preference here, but I still prefer it in the instance constructor. – Matt Feb 07 '14 at 15:32
  • @tencntraze, seems like OP know how to write code inside either of constructors. His question is where exactly he need to write it. What exactly is the problem if he put the db initialization in the static constructor? – Jimmy Feb 07 '14 at 15:54
  • @Jimmy There isn't a problem with that, so I added my comment above yours. – Matt Feb 07 '14 at 16:06
  • @tencntraze, but you said if you need a a reference to the connection, you need to put the initialization in the instance constructor. Could you please tell the reason for that. – Jimmy Feb 07 '14 at 16:11