views:

199

answers:

8

Once the singleton pattern is understood, writing subsequent singleton classes in C# is a brainless exercise. I would hope that the framework would help you by providing an interface or a base class to do that. Here is how I envision it:

public sealed class Schablone : ISingleton<Schablone>
{
    // Stuff forced by the interface goes here

    // Extra logic goes here
}

Does what I am looking for exist?

Is there some syntactic sugar for constructing a singleton class - whether with an interface, a class attribute, etc.?

Can one write a useful and bullet-proof ISingleton themselves? Care to try?

Thanks!

+1  A: 

No, there is nothing in the .Net framework like this. You have to write singletons yourself. It would be a bit hard to have a definative API for singletons as there are so many ways of implementing them, and depending on your goals depends on what approach you will take.

I would suggest you read this article on singletons. (Written by Jon - He's a wise guy, listen to him) for guidance and tips on the various techniques. It covers some stuff that most people might not have thought about.

[A lot of people consider the singleton pattern to be a dubious design pattern. I won't go into the reasons here, but if your interested google has loads of info. Just be careful you don't overuse it unnecessarily.]

Simon P Stevens
Another option would be to use an IoC container like Castle Windsor and define a particular class to act as a singleton.
Nissan Fan
Optionally one can use Prism RegisterInstance<T>() or Ninject's IKernel.Bind<T>().To<U>().InSingletonScope - works like a charm
Maciek
+1  A: 

I don't think that is possible.

How would an interface prohibit you from adding a public constructor to your class?

After all, writing a singleton is not that much work once you understood the basic pattern (and the caveats of making it thread-safe).

0xA3
+3  A: 

What is there to force? A singleton can be implemented with as little as a single property and a field. It doesn't seem like there is a very good value/cost ratio here for any framework developers to bother with.

Not to mention, the singleton pattern is often a poor one to use, and IMO it'd be bad to have the framework promoting them. To me, a singleton is almost always a code smell.

Matt Greer
@Matt, why is singleton a code smell and how would you avoid it?
Hamish Grubijan
+4  A: 

How often do you find yourself writing singleton classes?

I'd suggest that if it's a sufficiently frequent task for you that you feel you're losing productivity, you may well be overusing the pattern. I find that it's very rarely appropriate - but can easily lead to hard-to-test code.

Writing a singleton class in C# isn't just brainless - it's almost entirely painless. The boiler plate required is tiny, assuming you don't require absolute laziness to the point where the singleton shouldn't be instantiated just by calling other static methods.

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    public static Singleton Instance { get { return instance; } }

    private Singleton() {}

    // Omit if you don't care about type initializer laziness
    static Singleton() {}
}

Obviously you'd need a class declaration anyway, so you've saved either three or four lines, depending on whether you need the static constructor. Personally I don't think that's so time consuming for the rare occasions on which a singleton is valid that it's worth being part of the framework.

Indeed, it's hard to see how it could be a framework feature rather than a language feature... at the very least the compiler would have to be aware of it, to understand that there will be some magic "Instance" property (or whatever) that it should make available to callers.

As Eric Lippert is fond of pointing out (entirely reasonably, I might add) language features have great costs associated with them in terms of design, implementation and testing. Furthermore, there's the burden of each developer learning about the new language feature. In short, they need to really earn their value - and for me, the singleton pattern isn't sufficiently useful and important that it makes the bar.

Jon Skeet
+1  A: 

Use an Inversion of Control container to manage it for you.

With StructureMap, you can declare any type as a singleton:

ObjectFactory.Initilialize(x => x.ForSingletonOf<Schablone>());

To retrieve it:

ObjectFactory.GetInstance<Schablone>();
Joshua Flanagan
Please elaborate. Are any of these classes provided by standard libraries?
Hamish Grubijan
ObjectFactory is in StructureMap.dll, available from the link in my answer. It is not part of the .NET Framework.
Joshua Flanagan
Interesting ... does it use Reflection tricks?
Hamish Grubijan
+1  A: 

.Net 4.0 comes with MEF. And you can use MEF to instantiate a singleton. Thru the shared creation policy. I'll dig out a code sample....

EDIT ----

better still, here's some doco....

http://mef.codeplex.com/wikipage?title=Parts%20Lifetime&amp;referringTitle=Guide

pms1969
+1  A: 

Cut. Paste. Next.

James Westgate
+2  A: 

As others and me (in comments) have pointed out, the singleton pattern is rarely appropriate.

Still, since some believe that this could not work, here's the helper class to implement such a singleton (inspired by the linked article about how to implement singletons):

public static class Singleton<T> where T: class, new() {
    public static T Instance {
        get {
            return Nested.instance;
        }
    }

    private static class Nested {
        public static readonly T instance = new T();

        static Nested() {}
    }
}

The class to be used as singleton needs to have a public default constructor.

You could then use it as follows:

Singleton<MyClass>.Instance.DoSomething();
Lucero
WOW! Does anybody see any problems with this code? I cannot say that I do, although I do have a question: where is DoSomething defined?
Hamish Grubijan
Hamish, DoSomething would be a method on your class that you are instantiating as a singleton.
pms1969
I see ... so this would work ONLY if everyone is using `Singleton<MyClass>.Instance` as opposed to instantiating stuff directly ...
Hamish Grubijan
Looks nice, but IMHO is not a *pure* singleton implementation as that would mean that you can never have more than one instance of your singleton type. With the public default constructor of `MyClass` it's fairly easy to create as many objects as you like. In fact, I don't think your code is much different from simply using a static field.
0xA3