Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static Access To Multiple Instance Variable

I have a singleton instance that is referenced throughout the project which works like a charm. It saves me the trouble from having to pass around an instance of the object to every little class in the project. However, now I need to manage multiple instances of the previous setup, which means that the singleton pattern breaks since each instance would need it's own singleton instance.

What options are there to still maintain static access to the singleton? To be more specific, we have our game engine and several components and plugins reference the engine through a static property. Now our server needs to host multiple game instances each having their own engine, which means that on the server side the singleton pattern breaks.

I'm trying to avoid all the classes having the engine in the constructor.

Edit: The engines isn't guaranteed to be running on a unique thread. Each engine has a unique ID that can be used to identify the instance.

like image 437
Kasper Holdum Avatar asked Jan 22 '23 06:01

Kasper Holdum


2 Answers

This case is where the Singleton pattern breaks down. Having a single place where all of your code could retrieve an instance was convenient, but now you need to keep multiple instances. However, you're right that it's very annoying to pass context instances all the way through the constructor chains of your object tree. One solution to this problem is to use an Inversion of Control framework, like Ninject. It's a bit of a design investment (since it takes some time to get used to using IoC), but it's particularly good at resolving these issues, where you want to use dependency injection (passing your GameEngine to your various classes), but don't want to write a bunch of glue code just to pass the references around.

That said, if you only have a single context like this (i.e. it's only the GameEngine that's your singleton), then it's probably simplest to just add it to all of your constructors.

like image 172
Dan Bryant Avatar answered Feb 03 '23 20:02

Dan Bryant


The closest thing you might be able to do is use the ThreadStatic attribute on your singleton instance variable. This will maintain static semantics in terms of access, but each thread will have its own instance.

public class ThreadStaticSingleton
{
    [ThreadStatic]
    private static ThreadStaticSingleton instance;

    public static ThreadStaticSingleTon Instance
    {
        get 
        {
            if(instance == null) instance = new ThreadStaticSingleton();

            return instance;
        }
    }
}

That being said, that could very easily not be what you want. If you need to have either multiple threads access the same instance via the static variable or have one thread access different instances by the same variable, then this won't work.

Put another way, this will work if both of the following are true:

  • Each game engine runs on its own thread
  • Each game engine only runs on one thread

Otherwise, you'll likely have to go the factory pattern route, where each engine passes some sort of identifying information (even if it's just this) to a static function to obtain the instance rather than just using the Instance property.

like image 26
Adam Robinson Avatar answered Feb 03 '23 19:02

Adam Robinson