I'm a bit lost with the use of Inject on variable.
I got this code working :
private XXServiceAsync xxServiceAsync;
#Inject
protected IndexViewImpl(EventBus eventBus, XXServiceAsync tableManagementServiceAsync) {
super(eventBus, mapper);
this.xxServiceAsync = xxServiceAsync;
initializeWidgets();
}
With this code, I can call my RPC service wherever I need in the class (On click ...)
I would like to clear a bit the code by injecting direcly in the variable ; doing so :
#Inject
private XXServiceAsync xxServiceAsync;
protected IndexViewImpl(EventBus eventBus) {
super(eventBus, mapper);
initializeWidgets();
}
This always keep the Service to NULL.
Am I doing something wrong ? Is the GIN magic with rpc services meant to be done otherwise?
Thanks!
It is still null at that point, because Gin (and Guice, and other frameworks like this) cannot assign the fields until the constructor has finished running.
Consider how this would look if you were manually wiring the code (remember that Gin/Guice will cheat a little to assign private fields, call non-visible methods):
MyObject obj = new MyObject();//initializeWidgets() runs, too early!
obj.xxServiceAsync = GWT.create(xxService.class);
If you need something in the constructor, pass it into the constructor. If you wont need it right away (such as until asWidget() is called), then a field or setter annotated with #Inject can be helpful.
If you have field level injection you can use an empty #Inject method to do your post-inject initialization. The no-arg injected method will be run after field injections on the class are complete.
#Inject void initialize(){
...
initializeWidgets()
}
Edit: I previously stated that it was run after method injection as well, but testing shows that this is not always the case.
Related
Another question appeared during my migration from an E3 application to a pure E4.
I got a Structure using inheritance as in the following pic.
There I have an invocation sequence going from the AbstractRootEditor to the FormRootEditor to the SashCompositeSubView to the TableSubView.
There I want to use my EMenuService, but it is null due to it can´t be injected.
The AbstractRootEditor is the only class connected to the Application Model (as a MPart created out of an MPartDescriptor).
I´d like to inject the EMenuService anyway in the AbstractSubView, otherwise I would´ve the need to carry the Service through all of my classes. But I don´t have an IEclipseContext there, due to my AbstractSubView is not connected with Application Model (Do I ?).
I there any chance to get the service injected in the AvstractSubView?
EDIT:
I noticed that injecting this in my AbstractSubView isn´t possible (?), so I´m trying to get it into my TableSubView.
After gregs comment i want to show some code:
in the AbstractRootEditor:
#PostConstruct
public final void createPartControl(Composite parent, #Active MPart mPart) {
...
ContextInjectionFactory.make(TableSubView.class, mPart.getContext());
First I got an Exception, saying that my TableSubView.class got an invalid constructor, so now the Constructor there is:
public TableSubView() {
this.tableInputController=null;
}
as well as my Field-Injection:
#Inject EMenuService eMenuService
This is kind of not working, eMenuService is still null
If you create your objects using ContextInjectionFactory they will be injected. Use:
MyClass myClass = ContextInjectionFactory.make(MyClass.class, context);
where context is an IEclipseContext (so you have to do this for every class starting from one that is injected by Eclipse).
There is also a seconds version of ContextInjectionFactory.make which lets you provide two contexts the second one being a temporary context which can contain additional values.
I have an #Embeddable class that uses property access to wrap another object that's not directly mappable by JPA via field access. It looks like this:
#Embeddable
#Access(AccessType.PROPERTY)
public class MyWrapper {
#NotNull
#Transient
private WrappedType wrappedField;
protected MyWrapper() {
}
public MyWrapper(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Transient
public WrappedType getWrappedField() {
return wrappedField;
}
public void setWrappedField(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Column(name = "wrappedTypeColumn")
protected String getJPARepresentation() {
return wrappedField.toString();
}
protected void setJPARepresentation(String jpaRepresentation) {
wrappedField = new WrappedType(jpaRepresentation);
}
}
Persisting an #Entity with a MyWrapper field works fine. But when I execute a query to load the Entity from the database, I get a NullPointerException. The stacktrace and some debugging shows that Eclipselink creates a new instance of MyWrapper by calling its default constructor and then calls the setJPARepresentation() method (as expected).
But now the unexpected happens: the stacktrace shows that the getJPARepresentation() is called from inside the setter, which then of course leads to a NullPointerException when return wrappedField.toString() is executed.
java.lang.NullPointerException
at MyWrapper.getJPARepresentation(MyWrapper.java:27)
at MyWrapper.setJPARepresentation(MyWrapper.java)
... 109 more
Fact is, there is obviously no call to the getter in the code and the stacktrace shows no line number indicating from where in the setter called the getter. So my conclusion would be, that the bytecode weaver of Eclipselink generated the call to the getter.
It's easy to build a workaround, but my question is: Why does Eclipselink do that?
P.S: I'm using EclipseLink 2.3.2.v20111125-r10461 in a GlassFish Server Open Source Edition 3.1.2 (build 23)
When weaving is enabled (default on Glassfish), EclipseLink will weave code into property get/set methods for,
change tracking
fetch groups (partial objects)
lazy (relationships)
For change tracking support the set method will be weaved to check if the new value is different than the old value, so it must call the get method to get the old value.
Now this is still odd, as since your are building a new object, I would not expect the change listener to be set yet, so would expect the change tracking check to be bypassed. You could decompile the code to see exactly what was generated.
The easiest fix is to just put in a null check in your get method, which is probably best in general for your code. You could also switch to field access, which will not have issues with side-affects in get/set methods. You could also use a Converter to handle the conversion, instead of doing the conversion in get/set methods.
I want to be able to create two instances of the same class and have them be injected with different properties and then have those two objects injected into two specific locations in my application.
Currently I have a method in my ClientModule...
#Provides
#Named("bean1")
public MainBean getMainBean() {
MainBean mainBean = new MainBean(new SecondaryBean());
return mainBean;
}
And then in my presenters etc I do the following:
public MyPresenter(final EventBus eventBus, final MyView view,
#Named("bean1") MainBean bean, TitleSetupData data) {
super(eventBus, view);
this.bean1 = bean1;
}
And it works great. Based on the #Named annotation corresponding I get the correct bean.
However, this approach has a weakness in that I need to create and inject all the dependencies of MainBean in the #Provides method.
So any #Inject annotations of SecondaryBean are not honoured for example.
One thing I could do is pass into the getMainBean method any relevant dependencies but I'm wondering if there might be another more elegant or better solution.
Anyone got any ideas?
I came across the same problem.
What you are looking for is #Assisted Inject, where some of the constructor parameters are injected, and some are passed as arguments when you instantiate your object.
You can find a full example at this blog post which helped me getting started.
This is a question about how best to do DI, so it's not tied to any particular DI/IoC framework because, well, framework should be chosen based on pattern and practice rather than the other way around, no?
I'm doing a project where repository has to be injected into services, a service may require multiple repositories and I'm curious about the pros and cons between following approaches:
Inject repositories in service constructor
public class SomeService : ISomeService
{
private IRepository1 repository1;
private IRepository2 repository2;
public SomeService(IRepository1 repository1, IRepository2 repository2)
{
this.repository1 = repository1;
this.repository2 = repository2;
}
public void DoThis()
{
//Do something with repository1
}
public void DoThat()
{
//Do something with both repository1 and repository2
}
}
Inject a custom context class that include everything any service may need but lazy instantiated (the IServiceContext will be a protected field in BaseService)
public class SomeService : BaseService, ISomeService
{
public SomeService(IServiceContext serviceContext)
{
this.serviceContext= serviceContext;
}
public void DoThis()
{
//Do something with serviceContext.repository1
}
public void DoThat()
{
//Do something with both serviceContext.repository1 and serviceContext.repository2
}
}
Inject into methods that need them only
public class SomeService : ISomeService
{
public void DoThis(IRepository1 repository1)
{
//Do something with repository1
}
public void DoThat(IRepository1 repository1, IRepository2 repository2)
{
//Do something with both repository1 and repository2
}
}
Some pointers would be appreciated, moreover what're the aspects that I should consider in evaluating alternative like these?
The preferred way of injecting dependencies is Constructor Injection.
Method Injection is less ideal, because this will quickly result in having to pass around many dependencies from service to service and it will cause implementation details (the dependencies) to leak through the API (your method).
Both options 1 and 2 do Constructor Injection, which is good. If you find yourself having to inject too many dependencies in a constructor, there is something wrong. Either you are violating the Single Responsibility Principle, or you are missing some sort of aggregate service, and this is what you are doing in option 2.
In your case however, your IServiceContext aggregate service is grouping multiple repositories together. Many repositories behind one class smells like a unit of work to me. Just add a Commit method to the IServiceContext and you will surely have a unit of work. Think about it: don't you want to inject an IUnitOfWork into your service?
The first option seems to be the most natural from a DI perpective. The service class requires both repositories to perform its function, so making them required in order to construct an instance makes sense semantically (and practically).
The second option sounds a bit like Service Location, which is generally considered an anti-pattern (see http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx). In a nutshell, it creates implicit dependencies, where explicit dependencies are always preferred.
I would do either constructor based injection or property based injection. I would not pass in a context that contains the dependencies unless that context is serving some other purpose.
I prefer constructor based injection for required dependencies, as it makes it super easy for the object creation to blow up if something is missing. I got that from here. If you are going to verify that your dependencies are met, then you have to do it with constructor based injection, since there is no way to tell which setter is the last setter to be fired.
I have a new project where I am using GWT-Views like Composite, etc.
I have injected the items in the main menu (like ProductList below) using GinInjector. This works fine!
Somewhere I want to have a reference from a small component to an item from my main menu in order to update it. I try to inject it this way:
public class ProductForm extends Composite {
...
#Inject
ProductList list;
....
}
But when I use the list I always get null. Whereby, ProductList is defined this way:
public class MyModule extends AbstractGinModule {
...
#Override
protected void configure() {
bind(ProductList.class).asEagerSingleton();
bind(ProductForm.class).asEagerSingleton();
}
...
}
Any idea what I am doing wrong?!
Solution:
I failed to mention that ProductForm is an element of the ProductList using the UIBinder's #UIField tag, So That injecting it will create a new object rather than the one created using UIBinder.
I had to restructure my code to include presenters and an event bus so that no direct references between views are needed (other than the #UIField attributes).
I was working through Gin documentation : I'll quote it here :
Gin "Magic"
Gin tries to make injection painless and remove as much boilerplate from your code as possible. To do that the generated code includes some magic behind the scenes which is explained here.
Deferred Binding
One way Gin optimizes code is by automating GWT deferred binding. So if you inject an interface or class1 bound through deferred binding (but not through a Guice/Gin binding), Gin will internally call GWT.create on it and inject the result. One example are GWT messages and constants (used for i18n purposes):
public interface MyConstants extends Constants {
String myWords();
}
public class MyWidget {
#Inject
public MyWidget(MyConstants myconstants) {
// The injected constants object will be fully initialized -
// GWT.create has been called on it and no further work is necessary.
}
}
Note: Gin will not bind the instances created through GWT.create in singleton scope. That should not cause unnecessary overhead though, since deferred binding generators usually implement singleton patterns in their generated code.
You can see for yourself in this URL : http://code.google.com/p/google-gin/wiki/GinTutorial
It fails to mention why a singleton cannot be autogenerated by deferred binding and injected.
You can fix this by handcreating, using GWT.create(YourFactoryInterface.class).getProductList() in the constructor.
This means for testing puposes, you will need to pull the GWT.create into a seperate method and override it in a subclass and use that for testing like :
YourFactoryInterface getFactory() {
return GWT.create(YourFactoryInterface.class)
}
and
getFactory().getProductList()
Gin's asEagerSingleton() binding was broken for quite a while, and was injecting null. Not sure when the fix went in, but I had problems with eager singletons on v1.0. See the issue or the explanation, if you're interested. I'd either switch to regular .in(Singleton.class) bindings, or make sure you're using Gin 1.5.
Is the Ginjector creating the ProductForm? I think maybe that is needed to make it populate the injected variable.