Reputation: 56914
I've got a singleton class:
public class Widget
{
private Mapper mapper;
private static Widget SINGLETON;
private Widget(Mapper map)
{
setMapper(map);
}
public Widget getInstance()
{
if(SINGLETON == null)
SINGLETON = new Widget(???);
return SINGLETON;
}
}
Not only do I not understand how to pass SINGLETON
a Mapper
in its private constructor, I'm not seeing how I can use dependency injection to properly set the singleton up. Say Mapper
is an interface. Perhaps under "normal" execution I want to pass SINGLETON
a StandardMapper
instance, but while unit testing, I want to pass it a MockMapper
.
Thanks in advance for any pointers!
Upvotes: 1
Views: 1485
Reputation: 9697
In this instance you will have to make Mapper
a parameter of getInstance
The other alternative is getting an instance of Mapper
from some sort of repository, or another static getInstance
method which is the first step on the long road to an untestable application.
Upvotes: 0
Reputation: 533510
This is what I would do to inject into a Singleton.
public enum Widget {
SINGLETON;
private Mapper mapper;
public void setMapper(Mapper mapper) { this.mapper = mapper; }
}
If you are going to inject this singleton somewhere I would make it implement an interface
public enum Widget implement IWidget {
This way the singleton can be mocked as required provided you only use its interface.
Upvotes: 0
Reputation: 160191
Pass an argument to getInstance()
, perhaps providing one with and without a Widget
.
If you're using a DI framework there are other options, but you don't mention what you're doing. There would be several AOP options as well, but ultimately you'll still have to decide how to indicate what Widget
implementation to use.
(Minor nit, you're not "injecting a singleton", you're injecting into a singleton.)
Upvotes: 1