Tutorial :Possible to use a singleton with a non-default constructor in C#?



Question:

I'm implementing a notification framework for one of my projects. As i want it to be very generic, the user can use several transport layers, so that he doesn't really need to care about using one delivery method (lets say WCF) or another (for eg ActiveMQ). The interface the user has access is of course independent of the delivery method (WCF or ActiveMQ). Still, the two classes (consumer and producer) implements singletons, so they actually use default constructors (meaning, no parameters). My problem is that i would like to have one parameter, the delivery method the user want to use. But as far as i know, singleton only use default constructors? which is normal, as there should be no point of using singletons with parameters. So, what are my options here? not to create a singleton? create a method to set the delivery method?

Thank you very much for your help,

Sebastian


Solution:1

You can certainly have parameters with singletons, except instead of passing the parameter into a constructor, you are passing it into the getInstance() method. Your overridden constructor needs to be private of course for a true singleton implementation. My example is written in Java but applies for C# as well.

Example:

Singleton s = Singleton.getInstance(42);  

In the Singleton code:

private Singleton() {    }    private Singleton(int num) {     //set num  }    public getInstance(int num) {    //singleton code (calls the private non-default constructor if an object     //does not already exist)   }  


Solution:2

There are some dependency injection frameworks like Spring.Net which might help you. You can effectively pass a parameter in a configuration file for your singletons constructor.

Link to a Spring Framework example

Might I suggest that if you have two different behaviours required of your singleton that you might want to subclass. That way you get the behaviour that you want by calling the singleton of the class behaviour you want.


Solution:3

You can do this easily with a dependency injection framework. I have a similar construct in my current project using MEF. All that's required is to use the constructor injection options, and add that assembly and the requested dependency's assembly to the catalog, and it wires it up correctly.

Another option is to have some form of initialize function that takes your option, and constructs the singleton instance. Instead of constructing it on first access, you can construct it during the initialization call. The downside here is that you need to make sure to initialize your singleton before you use it (typically at program start, using a config file).

A similar, but less error-prone option, is to just have the singleton lazy initialize, and give it a "default" option. Allow the caller to set a static property to alter which option is constructed, so if it's set prior to the singleton's construction, you'll get a different default. This can be confusing, though, since again, you need to make sure you set the property before accessing the singleton, or you'll get unexpected behavior.


Solution:4

I know it is late to answer the original question, but i just had this problem and here is how i solved it. Might not be ideal, but it seems to work. I created a Init method that must be called before trying to use the singleton instance.

public void Init(/*parameters*/)  {          if (_isInitialized)          {              throw new InvalidOperationException("Component is already initialized!");          }          //do your work here  }  

Any other access to the singleton instance (properties get, set, method calls) will throw an invalid operation exception telling that the object was not initialized.

I think this does what i need, is less confusing than GetInstance(params) because there is no risk of misunderstanding what the method does. The downside is it will not throw compilation time errors, but the first run without the initialization done will throw an exception, so it should be good enough.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »