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.
Related
I'm trying to get dependencies set up correctly in my Workflow application. It seems the best way to do this is using the Service Locator pattern that is provided by Workflow's WorkflowExtensions.
My workflow uses two repositories: IAssetRepository and ISenderRepository. Both have implementations using Entity Framework: EFAssetRepository, and EFSenderRepository, but I'd like both to use the same DbContext.
I'm having trouble getting both to use the same DbContext. I'm used to using IoC for dependency injection, so I thought I'd have to inject the DbContext into the EF repositories via their constructor, but this seems like it would be mixing the service locator and IoC pattern, and I couldn't find an easy way to achieve it, so I don't think this is the way forward.
I guess I need to chain the service locator calls? So that the constructor of my EF repositories do something like this:
public class EFAssetRepository
{
private MyEntities entities;
public EFAssetRepository()
{
this.entities = ActivityContext.GetExtension<MyEntities>();
}
}
Obviously the above won't work because the reference to ActivityContext is made up.
How can I achieve some form of dependency chain using the service locator pattern provided for WF?
Thanks,
Nick
EDIT
I've posted a workaround for my issue below, but I'm still not happy with it. I want the code activity to be able to call metadata.Require<>(), because it should be ignorant of how extensions are loaded, it should just expect that they are. As it is, my metadata.Require<> call will stop the workflow because the extension appears to not be loaded.
It seems one way to do this is by implementing IWorkflowInstanceExtension on an extension class, to turn it into a sort of composite extension. Using this method, I can solve my problem thus:
public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
private MyEntities entities = new MyEntities();
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
}
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }
public void SaveChanges()
{
this.entities.SaveChanges();
}
}
The biggest downside to doing it this way is that you can't call metadata.RequireExtension<IAssetRepository>() or metadata.RequireExtension<ISenderRepository>() in the CacheMetadata method of a CodeActivity, which is common practice. Instead, you must call metadata.RequireExtension<IUnitOfWork>(), but it is still fine to do context.GetExtension<IAssetRepository>() in the Execute() method of the CodeActivity. I imagine this is because the CacheMetadata method is called before any workflow instances are created, and if no workflow instances are created, the extension factory won't have been called, and therefore the additional extensions won't have been loaded into the WorkflowInstanceExtensionManager, so essentially, it won't know about the additional extensions until a workflow instance is created.
I saw a post today about implementing SqlAzureExecutionStrategy:
http://romiller.com/tag/sqlazureexecutionstrategy/
However, all examples I can find of this use a Configuration that inherits from DbConfiguration. My project is using EF6 Code First Migrations, and the Configuration it created inherits from DbMigrationsConfiguration. This class doesn't contain a definition for SetExecutionStrategy, and I can find no examples that actually combine SqlAzureExecutionStrategy (or any SetExecutionStrategy) with DbMigrationsConfiguration.
Can this be done?
If anyone else comes across this question, this is what we figured out:
Create a custom class that inherits from DbConfiguration (which has SetExecutionStrategy):
public class DataContextConfiguration : DbConfiguration
{
public DataContextConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
}
}
Then add this attribute to your DataContext, specifying that it is to use your custom class:
[DbConfigurationType(typeof(DataContextConfiguration))]
public class DataContext : DbContext, IDataContext
{
...
}
After more investigation, now I think the correct answer is that:
DbMigrationsConfiguration is completely separate and only configures the migration settings. That's why it doesn't inherit from or have the same options as DbConfiguration.
It is not loaded, and is irrelevant, for actual operation.
So you can (and should) declare a separate class based on DbConfiguration to configure the runtime behaviour.
I added some tracing and I saw that the first time you use a DatabaseContext in an application, it runs up the migration, and the migration configuration.
But, the first time the DatabaseContext is actually used (e.g. to load some data from the database) it will load your DbConfiguration class as well.
So I don't think there is any problem at all.
I designed a new project using Guice/Gin so I could make our code more modular and swap-able especially when testing.
However, I am not able to find out how to make this work in practice. I was under the impression that I could just create a new Gin/Guice module in my test and install my 'base' module, overloading any bindings that I want to replace with specific testing implementations.
I don't want to have to use GWTTestCase and load my entire module, because it is very slow and unecissary for the types of granular testing I need to do.
I have tried using Jukito (http://code.google.com/p/jukito/), gwt-test-utils (http://code.google.com/p/gwt-test-utils/wiki/HowToUseWithGIN) and also some resources on doing this with guice (http://fabiostrozzi.eu/2011/03/27/junit-tests-easy-guice/).
None of these methods are yielding any results.
I think the Guice approach might work, if I defined a mirror guice module for my Gin module. However I really don't want to have to manage both of these. I really just want to test my GIN module like I would assume people test with Guice.
I feel like this should be really simple, can anyone point me to examples that work?
Update
Another way of looking at this question is:
How do I get the examples on the Jukito site (http://code.google.com/p/jukito/) work when the classes I am injecting are in an exernal Gin module?
**Update - In reference to Thomas Boyer's answer **
Thanks for the hint Tom, I was not able to find examples of using the adapter but I tried augmenting the Jukito examples to use the GinModuleAdapter anyway:
#RunWith(JukitoRunner.class)
public class MyGinTest {
public static class Module extends JukitoModule {
protected void configureTest() {
install(new GinModuleAdapter(new ClientModule()));
}
}
#Test
#Inject
public void testAdd(SyncedDOMModel mod){
assertNotNull(mod);
}
}
When I tried to run this test I recieved this exception:
java.lang.AssertionError: should never be actually called
at com.google.gwt.inject.rebind.adapter.GwtDotCreateProvider.get(GwtDotCreateProvider.java:43)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.Scopes$1$1.get(Scopes.java:65)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at org.jukito.JukitoRunner.ensureInjector(JukitoRunner.java:118)
at org.jukito.JukitoRunner.computeTestMethods(JukitoRunner.java:177)
at org.jukito.JukitoRunner.validateInstanceMethods(JukitoRunner.java:276)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:102)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:344)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:74)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
at org.jukito.JukitoRunner.<init>(JukitoRunner.java:72)
My gin module is part of a GWTP project, and looks like this:
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
install(new DefaultModule(ClientPlaceManager.class));
bindPresenter(MainPagePresenter.class, MainPagePresenter.MyView.class,
MainPageView.class, MainPagePresenter.MyProxy.class);
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.main);
bindPresenterWidget(MapTreePresenter.class,
MapTreePresenter.MyView.class, MapTreeView.class);
bindPresenterWidget(MapTreeItemPresenter.class,
MapTreeItemPresenter.MyView.class, MapTreeItemView.class);
bind(ResourcePool.class).to(DefferredResourcePool.class);
bind(WebSocket.class).to(WebSocketImpl.class);
}
}
As you can somewhat see, the class I am injecting in my test SyncedDOMModel, uses a WebSocket which I bind in my module. When I am testing, I don't want to use a real websocket and server. So I want to overload that binding in my test, with a class that basically emulates the whole thing. It's easier to just inject a different implementation of the WebSocket in this case rather than use mocking.
If it helps, this is a basic outline of the SyncedDOMMOdel class:
public class SyncedDOMMOdel {
....
#Inject
public SyncedDOMModel(WebSocket socket){
this.socket = socket;
}
....
}
You can use the GinModuleAdapter to use any GinModule as a Guice Module.
Obviously, you won't benefit from GIN's specific features: default to GWT.create() when something has no particular binding (this includes interfaces and abstract classes, which would throw in Guice), and automatically search for a RemoteService interface when an interface whose name ends Async has no specific binding.
And you won't be able to use anything that depends on JSNI or deferred binding (GWT.create()), as in any non-GWTTestCase unit test.
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.
GWT.create() is the reflection equivalent in GWT,
But it take only class literals, not fully qualified String for the Class name.
How do i dynamically create classes with Strings using GWT.create()?
Its not possible according to many GWT forum posts but how is it being done in frameworks like Rocket-GWT (http://code.google.com/p/rocket-gwt/wiki/Ioc) and Gwittir (http://code.google.com/p/gwittir/wiki/Introspection)
It is possible, albeit tricky. Here are the gory details:
If you only think as GWT as a straight Java to JS, it would not work. However, if you consider Generators - Special classes with your GWT compiler Compiles and Executes during compilation, it is possible. Thus, you can generate java source while even compiling.
I had this need today - Our system deals with Dynamic resources off a Service, ending into a String and a need for a class. Here is the solutuion I've came up with - btw, it works under hosted, IE and Firefox.
Create a GWT Module declaring:
A source path
A Generator (which should be kept OUTSIDE the package of the GWT Module source path)
An interface replacement (it will inject the Generated class instead of the interface)
Inside that package, create a Marker interface (i call that Constructable). The Generator will lookup for that Marker
Create a base abstract class to hold that factory. I do this in order to ease on the generated source code
Declare that module inheriting on your Application.gwt.xml
Some notes:
Key to understanding is around the concept of generators;
In order to ease, the Abstract base class came in handy.
Also, understand that there is name mandling into the generated .js source and even the generated Java source
Remember the Generator outputs java files
GWT.create needs some reference to the .class file. Your generator output might do that, as long as it is referenced somehow from your application (check Application.gwt.xml inherits your module, which also replaces an interface with the generator your Application.gwt.xml declares)
Wrap the GWT.create call inside a factory method/singleton, and also under GWT.isClient()
It is a very good idea to also wrap your code-class-loading-calls around a GWT.runAsync, as it might need to trigger a module load. This is VERY important.
I hope to post the source code soon. Cross your fingers. :)
Brian,
The problem is GWT.create doen't know how to pick up the right implementation for your abstract class
I had the similar problem with the new GWT MVP coding style
( see GWT MVP documentation )
When I called:
ClientFactory clientFactory = GWT.create(ClientFactory.class);
I was getting the same error:
Deferred binding result type 'com.test.mywebapp.client.ClientFactory' should not be abstract
All I had to do was to go add the following lines to my MyWebapp.gwt.xml file:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
Then it works like a charm
I ran into this today and figured out a solution. The questioner is essentially wanting to write a method such as:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Here MyInterface is simply a marker interface to define the range of classes I want to be able to dynamically generate. If you try to code the above, you will get an error. The trick is to define an "instantiator" such as:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Now define a GWT deferred binding generator that returns an instance of the above. In the generator, query the TypeOracle to get all types of MyInterface and generate implementations for them just as you would for any other type:
e.g:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
The MyIntefaceGenerator class is just like any other deferred binding generator. Except you call it directly within the above generator instead of via GWT.create. Once the generation of all known sub-types of MyInterface is done (when generating sub-types of MyInterface in the generator, make sure to make the classname have a unique pattern, such as MyInterface.class.getName() + "_MySpecialImpl"), simply create the Instantiator by again iterating through all known subtypes of MyInterface and creating a bunch of
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
style of code. Lastly throw an exception so you can return a value in all cases.
Now where you'd call GWT.create(clz); instead do the following:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Also note that in your GWT module xml, you'll only define a generator for Instantiator, not for MyInterface generators:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Bingo!
What exactly is the question - i am guessing you wish to pass parameters in addition to the class literal to a generator.
As you probably already know the class literal passed to GWT.create() is mostly a selector so that GWT can pick and execute a generator which in the end spits out a class. The easist way to pass a parameter to the generator is to use annotations in an interface and pass the interface.class to GWT.create(). Note of course the interface/class must extend the class literal passed into GWT.create().
class Selector{
}
#Annotation("string parameter...")
class WithParameter extends Selector{}
Selector instance = GWT.create( WithParameter.class )
Everything is possible..although may be difficult or even useless. As Jan has mentioned you should use a generator to do that. Basically you can create your interface the generator code which takes that interface and compile at creation time and gives you back the instance. An example could be:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
All you need to know is how to do the generator. I may tell you that at the end what you do in the generator is to create Java code in this fashion:
if ("clase1".equals(className)) return new clase1();
else if ("clase2".equals(className)) return new clase2();
...
At the final I thought, common I can do that by hand in a kind of InstanceFactory...
Best Regards
I was able to do what I think you're trying to do which is load a class and bind it to an event dynamically; I used a Generator to dynamically link the class to the event. I don't recommend it but here's an example if it helps:
http://francisshanahan.com/index.php/2010/a-simple-gwt-generator-example/
Not having looked through the code of rocket/gwittir (which you ought to do if you want to find out how they did it, it is opensource after all), i can only guess that they employ deferred binding in such a way that during compile time, they work out all calls to reflection, and statically generate all the code required to implement those call. So during run-time, you cant do different ones.
What you're trying to do is not possible in GWT.
While GWT does a good job of emulating Java at compile time the runtime is of course completely different. Most reflection is unsupported and it is not possible to generate or dynamically load classes at runtime.
I had a brief look into code for Gwittir and I think they are doing their "reflection stuff" at compile time. Here: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java
You might be able to avoid the whole issue by doing it on the server side. Say with a service
witch takes String and returns some sort of a serializable super type.
On the server side you can do
return (MySerializableType)Class.forName("className").newInstance();
Depending on your circumstances it might not be a big performance bottleneck.