I use Guice in a desktop application and I want to add generic bindings for services. These services are singleton (binded) instances and are created during application startup manually. I use the IoC container only to create the GUI. I create these services manually because during start up I want to publish the progress.
Since the GUI consume these services, they must been binded to the guice GUI module.
I can't think of a way to bind them without using a class with setter and getter for each class.
Let's say I have CarService and EngineService. What I have now is:
public class GuiceServices {
public static void main(String[] args) {
ServicesModule servicesModule = new ServicesModule();
CarService carService = new CarServiceImpl();
servicesModule.setCarService(carService);
System.out.println("progress: 50%");
EngineService engineService = new EngineServiceImpl();
servicesModule.setEngineService(engineService);
System.out.println("Progress: 100%");
Injector i = Guice.createInjector(new GuiModule(), servicesModule);
i.getInstance(MainView.class).show();
}
class ServicesModule extends AbstractModule {
private CarService carService;
private EngineService engineService;
@Override
protected void configure() {
}
public void setCarService(CarService carService) {
this.carService = carService;
}
public void setEngineService(EngineService engineService) {
this.engineService = engineService;
}
@Provides
public CarService getCarService() {
return carService;
}
@Provides
public EngineService getEngineService() {
return engineService;
}
}
}
But it is kind of pain since these services are plenty.
Is there a way to avoid this?
Ideally, a map is more convenient. Something like:
public class GuiceServices {
public static void main(String[] args) {
ServicesMap servicesMap = new ServicesMap();
CarService carService = new CarServiceImpl();
servicesMap.put(CarService.class, carService);
System.out.println("progress: 50%");
EngineService engineService = new EngineServiceImpl();
servicesMap.put(EngineService.class, engineService);
System.out.println("Progress: 100%");
Injector i = Guice.createInjector(new GuiModule(), new ServicesModule(servicesMap));
i.getInstance(MainView.class).show();
}
class ServicesModule extends AbstractModule {
private ServicesMap services;
public SerrvicesModule(ServicesMap services) {
this.services = services;
}
@Override
protected void configure() {
for (Class<?> serviceType : services.keySet())
{
bind(serviceType).toInstance(services.get(serviceType));
}
}
}
}
But I cannot find a way to create-implement this "servicesMap". Because the bind method returns a generic builder. Does Guice (or Guava) provide something for cases like this?
I know that I can use Guice to create the services and publish the progress using an injection/type listener, but my business package (module) that contains all the services has no javax.inject dependency. Plus, the creation of these services is complex hence is better to make it manually. Also, publishing a GUI progress within a Guice module sounds too complex to be in a Guice module.
So, is there a way? Instead of the System.out.println
in the above snippets, there is a splash screen that is created manually as well.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…