Introduction
I wrote this article named "A useful generic singleton template". I got several replies which indicated my odd article's defects. I decided to make a resume for these useful replies and compose a new article for singleton.
My original article can be found in the History chapter of this article. I wish to thank CodeProject members who left very useful replies : Brien Givens, mike75 and those who will give different ideas in the future.
Background
I use often Singleton in my project. I use singleton class for creating a class which is independent in the project. These classes in my project could be working as a Data Pool, as a Resource Manager or just as a independent part with private
constructor.
I worked with my generic singleton template mentioned in the History part of this tip, but several replies gave me another idea about how to use singleton in C# project.
Several Singleton Pattern
Mike75 proposed an article "Implementing the Singleton Pattern in C#" which listed 5 useful ways of implementing the singleton pattern. What is a useful singleton pattern? At least, it should be thread-safe - only one instance should only be created once in the whole life of the program.
public sealed class Singleton
{
private static Singleton instance = null;
private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
Above is a very simple thread-safe singleton class. It seems all good, it prevented from being created by two or more threads. But lock is acquired every time a new thread requires the instance.
Think about my generic singleton template, it used a version named double-check locking mentioned in the article "Implementing the Singleton Pattern in C#". It has several downsides, please read the original article to understand more.
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Above is a version which is better than the first version. But it's also its fatal convenient. Here is the explanation from the original article:
Static constructors in C# are specified to execute only when an instance of the class is created or a static member is referenced, and to execute only once per AppDomain. Given that this check for the type being newly constructed needs to be executed whatever else happens, it will be faster than adding extra checking as in the previous examples. However:
- It's not as lazy as the other implementations. In particular, if you have static members other than
Instance
, the first reference to those members will involve creating the instance. This is corrected in the next implementation. - There are complications if one static constructor invokes another which invokes the first again. Look in the .NET specifications (currently section 9.5.3 of partition II) for more details about the exact nature of type initializers - they're unlikely to bite you, but it's worth being aware of the consequences of static constructors which refer to each other in a cycle.
- The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called
beforefieldinit
. Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (i.e. a block which looks like a constructor but is marked static) as beforefieldinit
.
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
Here, instantiation is triggered by the first reference to the static member of the nested class, which only occurs in Instance. This means the implementation is fully lazy, but has all the performance benefits of the previous ones. Note that although nested classes have access to the enclosing class's private
members, the reverse is not true, hence the need for instance to be internal here. That doesn't raise any other problems, though, as the class itself is private
. The code is a bit more complicated in order to make the instantiation lazy, however.
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()
{
}
}
Using .NET 4's Lazy<T>
type is a most suggested method to construct a singleton class. Many replies suggested me to use Lazy<T>
. Just take a rest and see its MSDN's definition.
Using the Code
What can we do with singleton pattern, what should we pay attention to when we use it. To be continued...
History
In my projects, singleton is often used for data pool management or a data service management. And this class conserves data shared by the whole application. Any other class or function shouldn't be able to access the data source directly. A singleton class is very useful if we want to isolate the data pool from others.
The generic singleton template facilitates you to define a singleton class. The code below shows the generic singleton template:
public static class Singleton<T> where T : class
{
static volatile T _instance;
static object _lock = new object();
static Singleton()
{ }
public static T Instance
{
get
{
return (_instance != null) ? _instance : ResetAndGetInstance();
}
}
private static T ResetAndGetInstance()
{
lock (_lock)
{
if (_instance == null)
{
GetInstance();
}
}
return _instance;
}
private static void GetInstance()
{
ConstructorInfo constructor = null;
try
{
constructor = typeof(T).GetConstructor(BindingFlags.Instance |
BindingFlags.NonPublic, null, new Type[0],
null); }
catch (Exception excep)
{
throw new SingletonException(excep);
}
if (constructor == null || constructor.IsAssembly)
{
throw new SingletonException(string.Format
("A private or protected constructor is missing
for '{0}'.", typeof(T).Name));
}
_instance = (T)constructor.Invoke(null);
}
}
The code below shows how to use this template to create a singleton class. It presents a data pool that can be used for preventing the data source from being used disorderly by the outside class.
public class DataPool
{
static object _syncRoot = new object();
volatile List<DataUnit> _datas = new List<DataUnit>();
private DataPool()
{
}
public List<DataUnit> GetNewData(DateTime oldDt)
{
lock (_syncRoot)
{
var newDu = _datas.Where(p => p.DateTime > oldDt);
if (newDu != null && newDu.Count() > 0)
return newDu.ToList();
else
return null;
}
}
public List<DataUnit> GetAllDatas()
{
lock (_syncRoot)
{
List<DataUnit> history = new List<DataUnit>();
foreach (var item in _datas)
{
history.Add(new DataUnit()
{
DateTime = item.DateTime,
Message = item.Message,
Sender = item.Sender
});
}
return history;
}
}
public void AddData(string message, string sender)
{
lock (_syncRoot)
{
_datas.Add(new DataUnit()
{
DateTime = DateTime.Now,
Message = message,
Sender = sender
});
}
}
public static DataPool Instance()
{
return Singleton<DataPool>.Instance;
}
}
For calling this singleton data pool (getting instance of this singleton class), you just need to call the static
method Instance()
.
var newMessages = DataPool.Instance().GetNewData(_maxDateTime);
Points of Interest
I'm not sure if this is the best way to define a singleton class, but it's really useful and efficient.