Question

I've recently been challenged on my view that singletons are only good for logging and configuration. And with Dependency Injection I am now not seeing a reason why you can't use your services or repositories as singletons.

There is no coupling because DI injects a singleton instance through an interface. The only reasonable argument is that your services might have shared state, but if you think about it, services should be stand alone units without any shared state. Yes they do get injected with the repositories but you only have one way that a repository instance is created and passed to the service. Since repositories should never have a shared state I don't see any reasons why it also cannot be a singleton.

So for example a simple service class would look like this:

public class GraphicService : IGraphicService
{
    private IGraphicRepository _rep;
    public GraphicService(IGraphicRepository rep)
    {
       _rep = rep;
    }

    public void CreateGraphic() 
    {
      ...
      _rep.SaveGraphic(graphic):
    }
}

No state is shared in service except repository which also doesn't change or have it's own state.

So the question is, if your services and repositories don't have any state and only passed in, through interface, configuration or anything else that's instantiated the same way they then why wouldn't you have them as singleton?

Was it helpful?

Solution

If you're using the Singleton pattern i.e a static property of a class, then you have the tightly coupling problem.

If you need just a single instance of a class and you're using a DI Container to control its lifetime, then it's not a problem as there are none of the drawbacks. The app doesn't know there is a singleton in place, only the DI Container knows about it.

Bottom line, a single instance of a class is a valid coding requirement, the only issue is how you implement it. The Di Container is the best approach. the Singleton pattern is for quick'n dirty apps where you don't care enough about maintainability and testing.

OTHER TIPS

Some projects use singleton for dependence lookup before dependency injection gets populated. for example iBATIS jpetstore if I'm not mistaken. It's convenient that you can access your dependence gloablly like

public class GraphicService : IGraphicService
{
    private IGraphicRepository _rep = GraphicRepository.getInstance(); 


    public void CreateGraphic() 
    {
        ...
        _rep.SaveGraphic(graphic):
    }
}

But this harms testability (for not easy to replace dependence with test doubles) and introduces implicit strong dependence (IGraphicService depends on both the abstraction and the implementation).

Dependeny injection sovles these. I don't see why can't use singleton in your case, but it doesn't add much value when using DI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top