So I’m working on a middleware layer.
I’m consuming a COM DLL that deals with the low level hardware interaction, and providing an interface for the UI to do IO with the hardware.
As part of the design of my layer, we put in a contextmanager that arranges the various pieces of hardware to produce contexts that our application can work with.
So I want to guarantee that a developer that is working with my code has a single context manager to work with and then inside that context manager I can guarantee that we only allocate 1 work queue per hardware device.
Just to complicate this there is some initialization that must be done before I can start adding in hardware devices. Something that would be simple if not for the fact that typically you only access a singleton via a readonly property.
I know the singleton pattern can make alot of things difficult because of it’s global accessibility. I really do not want, nor need for this class to have the global availability of a singleton, I just want the guarantee that only one will be created inside the app.
For that would I be crazy to do something like this, to basically give my singleton a constructor:
public class MySingleton
{
private static MySingleton _MySingleton;
private static object singletonLock = new object();
private MySingleton(int foo1, string foo2)
{
//do init stuff
}
public static MySingleton StartSingleton(int foo1, string foo2)
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
_MySingleton = new MySingleton(foo1, foo2);
}
else
throw new Exception("Singleton already initialized");
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
public static MySingleton Instance
{
get
{
try
{
Monitor.Enter(singletonLock);
if (_MySingleton == null)
{
throw new Exception("Singleton must be Initialized");
}
}
finally
{
Monitor.Exit(singletonLock);
}
return _MySingleton;
}
}
}
It’s not crazy code but it is a singleton anyway. If you remove
Instanceproperty then it won’t be singleton anymore.Global accessibility is not all that makes singletons nasty. What makes them nasty is that they are used all through the system directly without you being able to track all those usages. That’s why it is such a nightmare in multi-threading code, that’s why it is so hard to unit test anything with singletons inside.
So if it is your code I’d recommend creating just one object during application initialization and pass it around with dependency injection or as plain constructor argument. If it is a library, you can either check in constructor if it is first object being created or not and throw an exception or you can go with static constructor as you did but without
Instanceproperty, forcing developers to pass instance around.As always, you can just create singleton, after all all it matters is that product works and customers enjoy using it, singletons or no singletons doesn’t really matter.