Say I have a class called PermissionManager which should only exist once for my system and basically fulfills the function of managing various permissions for various actions in my application. Now I have some class in my application which needs to be able to check a certain permission in one of its methods. This class’s constructor is currently public, i.e. used by API users.
Until a couple of weeks ago, I would have simply had my class call the following pseudo-code somewhere:
PermissionManager.getInstance().isReadPermissionEnabled(this)
But since I have noticed everyone here hating singletons + this kind of coupling, I was wondering what the better solution would be, since the arguments I have read against singletons seem to make sense (not testable, high coupling, etc.).
So should I actually require API users to pass in a PermissionManager instance in the constructor of the class? Even though I only want a single PermissionManager instance to exist for my application?
Or am I going about this all wrong and should have a non-public constructor and a factory somewhere which passes in the instance of PermissionManager for me?
Additional info Note that when I say ‘Dependency Injection’, I’m talking about the DI Pattern…I am not using any DI framework like Guice or Spring. (…yet)
If you are using a dependency-injection framework, then the common way to handle this is to either pass in a PermissionsManager object in the constructor or to have a property of type PermissionsManager that the framework sets for you.
If this is not feasible, then having users get an instance of this class via factory is a good choice. In this case, the factory passes the PermissionManager in to the constructor when it creates the class. In your application start-up, you would create the single PermissionManager first, then create your factory, passing in the PermissionManager.
You are correct that it is normally unwieldy for the clients of a class to know where to find the correct PermissionManager instance and pass it in (or even to care about the fact that your class uses a PermissionManager).
One compromise solution I’ve seen is to give your class a property of type PermissionManager. If the property has been set (say, in a unit test), you use that instance, otherwise you use the singleton. Something like:
Of course, strictly speaking, your PermissionManager should implement some kind of IPermissionManager interface, and that’s what your other class should reference so a dummy implementation can be substituted more easily during testing.