1

Aside from "what is so bad about singletons" :-), I have an ASP.NET web application that utilises singletons at the business logic layer, thus:

public class MyBusinessService
{
    private static MyBusinessService mInstance = null;

    public static MyBusinessService Instance
    {
        get { return mInstance; }
    }

    static MyBusinessService()
    {
        mInstance = new MyBusinessService();
    }
}

We use them primarily for a dependency in a Model View Presenter architecture.

They can also be used across business logic classes in one of two ways. Firstly in the following manner:

var myService = new MyBusinessService();
myService.DoSomething();
myService.DoSomethingElse();

Or, it can be used in the following manner:

MyBusinessService.Instance.DoSomething();
MyBusinessService.Instance.DoSomethingElse();

Which construct is preferred and why? I'm not interested in whether the singleton pattern itself is good or bad.

Update: Ok, this question seems to be quite popular. I guess it is a quasi-singleton. Worst of both worlds! I'm not really interested in refactoring the pattern / anti-pattern / code hell. I'm more interested in understanding the effects of both usages described.

Our view (ASP.NET page) looks like this:

var presenter = new SomeViewPresenter(this, MyBusinessService.Instance);

but could alternatively be implemented as:

var presenter = new SomeViewPresenter(this, new MyBusinessService());

I prefer the former in this case. N.B. The use of the word singleton and the incorrect usage above is understood, but as the code stands, what is the outcome of the two original options?

Community
  • 1
  • 1
Rebecca
  • 12,888
  • 10
  • 84
  • 127
  • I don't understand... you say that this class is a singleton, but still it can be instantiated regularly as in the first example? – Paolo Tedesco Oct 26 '11 at 14:53
  • As an aside, your singleton is using a static variable to contain the reference. IIS reserves the right to recycle AppDomain/processes when it deems fit, ending up in you losing any contained statics. Any legs in using a serialized container like Application State or the Cache? – Adam Houldsworth Oct 26 '11 at 14:53
  • Read [Implementing the Singleton Pattern in C#](http://csharpindepth.com/Articles/General/Singleton.aspx) – Justin Oct 26 '11 at 14:57

6 Answers6

2

Your class is not a singleton without a private constructor

So if you add a private constructor

private MyBusinessService()
{
}

Then you are restricted to your second use, and it is a singleton class

Patrick McDonald
  • 59,808
  • 14
  • 95
  • 115
2

The latter is preferred because the former isn't behaving like a singleton - you are instantiating a new instance without any guards for stopping more than one instance existing.

The latter is the code you'd likely end up with if you put these guards in place. You don't need to use the property all the time too:

var service = MyBusinessService.Instance;
service.This();
service.That();

I also look at statics in ASP.NET with some skepticism and this is from a WinForms developer :-)

Adam Houldsworth
  • 60,104
  • 9
  • 137
  • 177
1

The first one is arguably preferred, since it isn't a singleton. Since you want to leave the arguments about singletons aside, the second would be preferred, because it is.

Jon Hanna
  • 102,999
  • 9
  • 134
  • 232
1

Generally, the singleton pattern should be used whenever you want to limit your program to having a single instance of a class. It should be used instead of simply marking everything static, because when you do this it's not possible to work with the class as an instance (for example passing it as a parameter to classes/methods), which makes adhering to good design patterns like the Dependency Inversion Principle difficult or impossible.

Your ability to "new" up a MyBusinessService defeats the purpose of a singleton. If you want to be able to create new instances at will, then just make it a normal instance class. If you want to restrict to one instance, then by definition you shouldn't have access to the default constructor.

Here's how your class would look as a true singleton:

public class MyBusinessService
{
    private static MyBusinessService mInstance = null;

    public static MyBusinessService Instance
    {
        get { return mInstance; }
    }

    static MyBusinessService()
    {
        mInstance = new MyBusinessService();
    }

    private MyBusinessService() {}
}

The addition of a default instance constructor marked private means that var myService = new MyBusinessService(); will not compile from outside the scope of MyBusinessService (thus restricting its use to the static constructor).

One more thing; if MyBusinessService may not be used in every case, or it's expensive to create, you might consider making it lazy. By default, static constructors are run on startup; however, static members are not evaluated until they are first referenced. So, you can set your class up like this, and a MyBusinessService instance will not be created until the program knows it will need one:

public class MyBusinessService
{
    //the instantiation will not happen until the Instance property is called
    private static readonly MyBusinessService mInstance = new MyBusinessService();

    public static MyBusinessService Instance
    {
        get { return mInstance; }
    }

    private MyBusinessService() {}
}
KeithS
  • 65,745
  • 16
  • 102
  • 161
0

The two options above are quite different. The first option will call the default ctor, but the second option will not. This may or may not be an issue depending on whether you need to initialize any instance members.

My preference is option #2 if you don't need an instance-based ctor. It truly depends on how you are using it.

SliverNinja - MSFT
  • 29,007
  • 10
  • 98
  • 161
0

Of these two options the second is prefered since it behaves like a real Singleton.

For a definitive guide on how to implement a Singleton see http://csharpindepth.com/Articles/General/Singleton.aspx .

You will find that there are several aspects (like performance, lazyness, exceptions, thread-safety etc.) to keep in mind.

Yahia
  • 67,016
  • 7
  • 102
  • 131