Hallo zusammen,
ich bekomme immer null wenn ich ein Object zurück, das schon im DI Container vorhanden ist, warum?
Ich kann mal Codesegmente hier posten, vielleicht seht ihr das auf anhieb
Hier ist mein Modul:
An dieser Stelle wird das Modul initialisiert
über die Demo Klasse wird die Anwendung gestartet
Im ExampleEmfWorkbench werden die Objekte injected, an der Stelle sind die Services auch vorhanden
Im Renderer werden die Steuerelemente über eine Xml Datei die Klassen als String gelesen und per Reflection instanziert und in den Workbench ergänzt.
Jetzt kommen wir zum eigentlichen Problem, sobald die View instanziert und über den EmfWorkbenContext geholt wird, wird das Object von Guice in den Container gesteckt oder, sodass die View die ganzen Services injection kann?
Was ist an der Stelle mein Denkfehler? Vermutlich die Inzierung der View oder das Objekt über getInstance() zu holen oder? Auf jeden Fall bekomme ich an der Stelle mein selectionService nicht.
Viele Grüße
lam
ich bekomme immer null wenn ich ein Object zurück, das schon im DI Container vorhanden ist, warum?
Ich kann mal Codesegmente hier posten, vielleicht seht ihr das auf anhieb
Hier ist mein Modul:
Code:
public class BaseEmfModule extends AbstractModule {
@Override
protected void configure() {
bind(IEmfControlManager.class).to(EmfControlManager.class).asEagerSingleton();
bind(IEventBroker.class).to(EventBroker.class).asEagerSingleton();
bind(ISelectionService.class).to(SelectionService.class).asEagerSingleton();
bind(EmfWorkbenchRenderer.class).asEagerSingleton();
bind(EmfWorkbenchFile.class).asEagerSingleton();
bind(EmfCommandManager.class).asEagerSingleton();
}
}
An dieser Stelle wird das Modul initialisiert
Code:
public class EmfWorkbenchContext {
private static final Logger LOG = Logger.getLogger(EmfWorkbenchContext.class.getSimpleName());
private static List<Module> modules = new ArrayList<>();
private static Injector injector;
private EmfWorkbenchContext() {
modules.add(new BaseEmfModule());
}
/**
* This step should be done first, before the {@link #init()} method is called.
* @param module
*/
public static void add(Module module) {
modules.add(module);
}
public static void inject(Object obj) {
injector.injectMembers(obj);
}
public static void init() {
injector = Guice.createInjector(modules);
LOG.log(Level.ALL, "Initialize Guice for ApplicationContext with SelectionServiceModul!");
}
public static <T> T getInstance(Class<T> type) {
T instance = null;
try {
instance = injector.getInstance(type);
} catch (Exception e) {
LOG.log(Level.SEVERE, "Failed to get the instance via guice "+e.getLocalizedMessage());
}
return instance;
}
}
über die Demo Klasse wird die Anwendung gestartet
Code:
public class EmfWorkbenchDemo extends AbstractDemoApplication {
private static ExampleEmfWorkbench workbench;
@Override
protected Parent getRoot() {
return workbench;
}
public static void main(String[] args) {
EmfWorkbenchContext.init();
EmfWorkbenchContext.add(new CommandsModule());
workbench = EmfWorkbenchContext.getInstance(ExampleEmfWorkbench.class);
workbench.render();
launch(args);
}
}
Im ExampleEmfWorkbench werden die Objekte injected, an der Stelle sind die Services auch vorhanden
Code:
public class ExampleEmfWorkbench extends EmfWorkbench{
@Inject IEmfControlManager manager;
@Inject ISelectionService selectionService;
@Inject IEventBroker eventBroker;
@Inject EmfWorkbenchRenderer renderer;
public void render() {
renderer.setWorkbench(this);
renderer.doSwitch(getWorkbench());
renderer.doSwitch(getWorkbench().getToolbar());
Perspective firstPerspective = getWorkbench().getPerspectives().get(0);
renderer.doSwitch(firstPerspective);
}
...
}
Im Renderer werden die Steuerelemente über eine Xml Datei die Klassen als String gelesen und per Reflection instanziert und in den Workbench ergänzt.
Code:
@Override
public Node caseView(View object) {
try {
Class clazz = Class.forName(object.getViewClass());
return (Node) EmfWorkbenchContext.getInstance(clazz);
} catch (NullPointerException | ClassNotFoundException e) {
log.log(Level.SEVERE, "Viewpart cannot created (id: "+object.get_Id()+"instance: "+object.getViewClass()+", message: "+e.getMessage()+") ");
}
return new Label("ViewPart cannot be created!");
}
Jetzt kommen wir zum eigentlichen Problem, sobald die View instanziert und über den EmfWorkbenContext geholt wird, wird das Object von Guice in den Container gesteckt oder, sodass die View die ganzen Services injection kann?
Code:
import com.google.inject.Inject;
import de.dc.javafx.xcore.workbench.ui.EmfWorkbenchContext;
import de.dc.javafx.xcore.workbench.ui.control.EmfView;
import de.dc.javafx.xcore.workbench.ui.event.ISelectionService;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
public class EmfExampleTableView extends EmfView {
@Inject ISelectionService service;
public static class Person {
private final SimpleStringProperty vorname;
private final SimpleStringProperty nachname;
private final SimpleIntegerProperty alter;
private Person(String vName, String nName, int alter) {
this.vorname = new SimpleStringProperty(vName);
this.nachname = new SimpleStringProperty(nName);
this.alter = new SimpleIntegerProperty(alter);
}
public String getVorname() {
return vorname.get();
}
public void setVorname(String fName) {
vorname.set(fName);
}
public String getNachname() {
return nachname.get();
}
public void setLastName(String fName) {
nachname.set(fName);
}
public int getAlter() {
return alter.get();
}
public void setAlter(int fAlter) {
alter.set(fAlter);
}
}
@Override
protected void createPartControl(BorderPane parent) {
TableView table = new TableView();
ObservableList<Person> data = FXCollections.observableArrayList(new Person("Denis", "Panjuta", 28),
new Person("Hans", "Wurst", 25), new Person("Dieter", "Mieter", 33));
table.setEditable(true);
TableColumn vorNameCol = new TableColumn("Vorname");
TableColumn nachNameCol = new TableColumn("Nachname");
TableColumn alterCol = new TableColumn("Alter");
table.getColumns().addAll(vorNameCol, nachNameCol, alterCol);
vorNameCol.setMinWidth(100);
vorNameCol.setCellValueFactory(new PropertyValueFactory<>("vorname"));
nachNameCol.setMinWidth(100);
nachNameCol.setCellValueFactory(new PropertyValueFactory<>("nachname"));
alterCol.setMinWidth(100);
alterCol.setCellValueFactory(new PropertyValueFactory<>("alter"));
table.setItems(data);
// An dieser Stelle wird null zurückgegeben
selectionService.registerProvider(table.getSelectionModel().selectedItemProperty());
// Wenn ich über EmfWorkbenchContext gehe wird das gewollte Object geholt.
EmfWorkbenchContext.getInstance(ISelectionService.class).registerProvider(table.getSelectionModel().selectedItemProperty());
parent.setCenter(table);
}
}
Was ist an der Stelle mein Denkfehler? Vermutlich die Inzierung der View oder das Objekt über getInstance() zu holen oder? Auf jeden Fall bekomme ich an der Stelle mein selectionService nicht.
Viele Grüße
lam