I have the following code implementation of my generic singleton provider:
public sealed class Singleton<T> where T : class, new()
{
Singleton()
{
}
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator()
{
}
internal static readonly T instance = new T();
}
}
This sample was taken from 2 articles and I merged the code to get me what I wanted:
http://www.yoda.arachsys.com/csharp/singleton.html and
http://www.codeproject.com/Articles/11111/Generic-Singleton-Provider.
This is how I tried to use the code above:
public class MyClass
{
public static IMyInterface Initialize()
{
if (Singleton<IMyInterface>.Instance == null // Error 1
{
Singleton<IMyInterface>.Instance = CreateEngineInstance(); // Error 2
Singleton<IMyInterface>.Instance.Initialize();
}
return Singleton<IMyInterface>.Instance;
}
}
And the interface:
public interface IMyInterface
{
}
The error at Error 1 is:
'MyProject.IMyInterace' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MyProject.Singleton<T>'
The error at Error 2 is:
Property or indexer 'MyProject.Singleton<MyProject.IMyInterface>.Instance' cannot be assigned to -- it is read only
How can I fix this so that it is in line with the 2 articles mentioned above? Any other ideas or suggestions are appreciated.
Does my implementation break the Singleton pattern?
Basically, you’ve given a class constraint on your singleton class, along with the new() constraint.
When writing
you’re using an interface type as T, which violates the type constraint you defined.
For error 2,
you’re trying to assign a value to a read-only property. So you need to define a setter on your Instance property for that line to work.
Update
Something along these lines should do it for you :
You could then write :
If you want to go further, you could also specify the lifecycle of the objects created by this provider, so that you could use singletons, or have the provider return a new object for each call, and so on.
You should also take a look at the Dependency Injection pattern, which seems close to what you want achieve, and also look at existing DI frameworks (NInject, Nhibernate) that already do this and much more.