Reputation: 1015
I want to write a generic singleton with an external constructor. In other words the constructor can be modified. I have 2 designs in my mind but I don't know whether they are practical or not.
First one is to enforce derived class' constructor to be non-public but I do not know if there is a way of it?
Second one is to use a delegate and call it inside the constructor?
It isn't necessarily to be a constructor. The reason I chose custom constructor is doing some custom initializations.
Any suggestions would be appreciated :)
Upvotes: 2
Views: 3308
Reputation: 1460
This is my point, using .NET 4
public class Singleton<T> where T : class, new()
{
Singleton (){}
private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());
public static T Instance { get { return instance.Value; } }
}
Upvotes: 2
Reputation: 54543
You can try to use factory pattern to create a singleton factory, which will produce the concrete singletons.
Upvotes: 0
Reputation: 1015
Ok here is my solution. I used reflection to check for public constructors. Please comment if I'm missing something.
public abstract class Singleton<T> where T: class
{
private static volatile T _instance;
private static object _lock = new object();
protected Singleton()
{
ConstructorInfo[] constructorPublic = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Instance);
if (constructorPublic.Length > 0)
{
throw new Exception(String.Format("{0} has one or more public constructors so the property cannot be enforced.",
typeof(T).FullName));
}
}
public static T Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
ConstructorInfo constructorNonPublic = null;
try
{
constructorNonPublic = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null,
new Type[0], null);
}
catch (Exception e)
{
throw e;
}
if (constructorNonPublic == null || constructorNonPublic.IsAssembly)
{
throw new Exception(String.Format("A private or protected constructor is missing for {0}",
typeof (T).Name));
}
_instance = constructorNonPublic.Invoke(null) as T;
}
}
}
return _instance;
}
}
}
Upvotes: -1
Reputation: 43217
Here's one way to do this, If at all I could get you right.
public abstract class MySingletonBase<T>
where T : class
{
protected MySingletonBase()
{
}
// All other functions that will be inherited.
}
public class MySingleton<T> : MySingletonBase<T>
where T : class
{
private static MySingleton<T> instance;
protected MySingleton()
{
}
public static MySingleton<T> GetInstance()
{
if (instance == null)
{
instance = new MySingleton<T>();
}
return instance;
}
}
Upvotes: 2
Reputation: 1064114
That doesn't sound nice. I wonder if configuring this through IoC is going to be simpler and easier to support. Most IoC containers will support singeton-style object re-use, and highly configurable initialization. Without the side-effect making your object all ugly.
Singleton is nice, but is vastly over-used. Of course I'm as guilty of this as the next geek...
Upvotes: 2