How do Service / SourceProviders work in Eclipse 4 RCP 2.0? - eclipse-rcp

I've been busily getting with the future and migrating an old eclipse 3.7 application over to Eclipse 4 and whilst I'm happy with the application model for porting all the views I have a number of source providers that I am unsure about porting wise. I've been using a few tutorials on Eclipse 4 including this Tutorial from good old Lars but none seem to cover this particular element.
For a small amount of Context my existing application has a few classes extending AbstractSourceProvider that are registered in the org.eclipse.ui.services extension point. My views register themselves as listeners to these services using the ISourceProviderService.getSourceProvider(key) function from the workbench and update themselves if that source fires a sourced changed event. I also have a few providers that reference each other some times too so I'm wondering if this will still work with injection.
What sort of model is used in Eclipse 4?, should I just use the same old extension point? Can these extension point services be injected in to the views in the new cool anotationy way?
What gives?

You can create a service in a number of ways:
Create an instance of your service class and put it in the IEclipseContext. This is often done in an 'Addon':
public class MyAddon
{
#PostConstruct
void postConstruct(IEclipseContext context)
{
MyService myService = ContextInjectionFactory.make(MyService.class, context);
context.put(MyService.class, myService);
}
}
The 'Addon' is declared in the application.e4xmi file.
You could also create the service like this in the LifeCycle class for the RCP.
An OSGi service will automatically be added to the Eclipse context.
You can use a Context Function which uses an OSGi service but doesn't create the actual service until it is needed.
In all cases you reference the service by injection:
#Inject
MyService myService;
Note that injection is only done on objects created by Eclipse from objects described in the application.e4xmi. It is possible to do injection on other objects using ContextInjectionFactory.

Related

How to write a custom module for spring data

I need to extend spring data in order to support my own custom backend. From the spring data website, it seems that it is possible to add community modules to the framework, which in turn enables you to support a custom backend. However, I can't seem to find some code examples/docs illustrating the module implementation mechanism.
Even a basic example using a file-based persistence would be very helpful.
You just have to extend it then you can override the methods and add your own. If you're using IntelliJ, just implement/extend (for example) CrudRepository, execute Generate Code and select Implement methods or Override methods.
public MyRepository extends CrudRepository<T, Long>{
//in Mac, you press command + N. Then select Override methods.
//in Windows, I don't think Generate Method is given a shortcut. You can find it in the menu bar
}

Platform-specific IoC in MVVMCross

I'm giving a MVVMCross a spin, to see if it will be of use in some bigger projects coming up, and it's great. I like the navigation, viewModel location and general cross-platform approach, which is just what I need. However, I'm a bit stuck on splitting out some of the dependency injection depending on the platform.
So, we have the basic application, with a shared portable library, that initialises the service references when starting up:
public TwitterSearchApp()
{
InitaliseServices();
}
private void InitaliseServices()
{
this.RegisterServiceInstance<ITwitterSearchProvider>(new TwitterSearchProvider());
}
Fine. That defines the service implementations that will be used across all the platforms. But what about the situation where I will need different implementations on different platforms - for instance perhaps storage/caching, where the core requirement is the same, but needs to be handled differently on a phone than on a tablet.
I thought it might go in Setup somewhere:
public class Setup : MvxBaseWinRTSetup
{
public Setup(Frame rootFrame): base(rootFrame)
{
}
protected override MvxApplication CreateApp()
{
var app = new TwitterSearchApp();//set platorm specific IoC here maybe?
return app;
}
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{ // or perhaps here?
loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Visibility.WinRT.Plugin>();
base.AddPluginsLoaders(loaders);
}
}
but I'm not sure. I've seen the references to replacing the ViewModel locator, but is there are similar way of replacing the other IoC services?
thanks, great job on the framework in general, I really like how it works (apart from this bit, which I don't understand properly yet)
Toby
There are three basic options:
1. Add the platform specific services in your UI project and then register them in an override during setup - which override you use depends on when your services are needed, but for most cases you can just use the InitializeLastChance override which gets called at the end of initialization:
protected override void InitializeLastChance()
{
this.RegisterServiceInstance<IMyService>(new SingletonMyService());
this.RegisterServiceType<IMyService2, PerCallService2>();
base.InitialiseLastChance();
}
If 'last chance' is too late for your service - if you need the service during the core app startup - then you can override any initialisation step after InitializeIoC - e.g. InitializeFirstChance. For the list and order of initialisation steps, see InitializePrimary and InitializeSecondary in MvxBaseSetup.cs
2. Add the platform specific registration in some other bit of the UI code - e.g. in the constructor for a specific View (this option isn't used much... but you could use it in some odd cases, if you wanted to...)
3. Use a plugin - all plugins are is a wrapper around IoC. Plugins have the disadvantage that they add some development overhead (you have to add the separate projects and the plugin boilerplate files), but they have the advantages that they can be reused across apps and it's easier to write test apps and test harnesses for them. For more info on plugins, see Making mono cross platform support for Task/Intent and see http://slodge.blogspot.co.uk/2012/10/build-new-plugin-for-mvvmcrosss.html
My general advice - start with the first option and migrate out to a plugin if you want to reuse the code in later projects...

Create a GWT RPC Service

I’m trying to create a backend for a homepage with GWT. I created a Google Web Application in Eclipse without sample code and now I would like to add the service, but the developer Google guide doesn’t help me. I’m not sure, where to add the interface and how it exactly works.
If I understand the google documentation correctly, I have to add a module and an entry point class, is that correct? It would be great if you could give me some tips and help how to create a rpc service.
If you create a new GWT project in the Eclipse "New Project" wizard, with "Generate project sample code" checked, it will include a fully functioning RPC service with a sample method, which you can then adapt or copy according to your needs.
Out of memory, don't have eclipse in front of me.
First do create a test project with generated testcode, you can delete it afterward.
Yes you will have to add a module.
Create in client the two interfaces for the async calls, inherit it on server side.
Hope I understood your question right.
I'm not sure what would help you the most. Google developer guide was enough for me (at least when I started using it on version 1.6) to create RPC services for my GWT application.
General APP
Module: is the .gwt.xml file. Yes, you'll need it. The GWT compiler will find it automagically and try to compile all the GWT code (the <source> element will tell which subpackage contains Java code that will be converted to JS). It will tell also which class implements the EntryPoint interface. The onModuleLoad will be the code executed when javascript runs in the client page.
RPC
Well, you should first try UI things and only then, when you're confident enough, try the server thing. Anyway the scheme is:
interface MyService extends RemoteService {
List<String> doSomething(String sample, int other);
}
#RemoteServiceRelativePath("../path/to/servlet") // see later
intercace MyServiceAsync {
void doSomething(String sample, int other, AsyncCallback<List<String>> callback);
}
These are the interfaces. Later is the async one. That's what you'll use from client side. Always calling and passing an implementation of AsyncCallback which will receive (sometime later, you don't know when) the result.
First interface is the syncrhonous one. That is what you need to implement on server. You must inherit from RemoteServiceServlet class (it is an implementation of servlet that already does all the values handling), and implement your interface. GWT code does the rest (almost).
public class ServiceImpl extends RemoteServiceServlet implements MyService
{
// implement the method normally
}
From client you'll need to create the service proxy:
private static MyServiceAsync MY_SERVICE = GWT.create(MyService.class);
Yes. I know it's weird how GWT knows MyserviceAsync and MyService work together. Don't worry about that. It works :)
Just use the service like this:
MY_SERVICE.doSomething("value", 111, new AsyncCallback<List<String>>() {
// note that this code executes some time in the future when response from server is back
public void onSuccess(List<String> result) {
Window.alert("Server answered with " + result.size() + " elements!");
}
public void onFailure(Throwable t) {
Window.alert("Server failed: " + t.getMessage());
}
}
Path to server
You'll have to configure your app to make that servlet implementation listen to URL indicated in #RemoteServiceRelativePath. That's the way client knows where to make the request, and the server knows which servlet attends that request. I'd suggest using:
../my-service.gwt as relative path (GWT module gets published in <ROOT>/module_name
and
configuring your web app to use the servlet for /my-service.gwt
But it's entirely upon your preferences :)
Anyway I think Google tutorials are the best. So please copy&paste. Try&modify until you get to understand the whole thing.

IoC, MVC4 Web API & HttpParameterBinding/ParameterBindingAttribute

I'm using ASP.Net MVC 4 RTM Web API. I have a controller action with a parameter that I'd like to populate via custom model binding. To achieve this, I created a class that derives from System.Web.Http.Controllers.HttpParameterBinding that sets the value of this parameter. I then created an attribute class that derives from System.Web.Http.ParameterBindingAttribute which I use to decorate the parameter on my controller action.
This is all working great, my HttpParameterBinding class is populating the action parameter correctly. The problem I have is that my custom parameter binding class has a dependency that I'd like resolved via my IoC container (Unity). Is there a way to override how Web API creates HttpParameterBinding instances so that I can build up my custom binding class dependency from Unity? I was able to do something similar for a filter attribute by creating a custom filter provider that uses Unity's BuildUp method to populate dependencies, however I'm not seeing anything similar for Web API's HttpParameterBindings.
In general: to use IoC / Unity in the Web API you need to set it up seperately.
Try downloading the nuget package Unity.WebApi and see if that helps!
Take a look at this article: Parameter Binding in WebAPI
It walks through a couple different options from Converters to Binders to BinderProviders. It sounds like you may be able to write a custom ModelBinderProvider which knows how to provide your dependency. If that isn't high enough in the chain you can look at replacing the default IActionValueBinder service. It's a DefaultActionValueBinder instance, which you can extend or simply re-implement.
I also highly recommend downloading the WebAPI source code, as it's been an incredible help for these issues as I've run into them. Here's the WebAPI source code. I recommend downloading it so you can open it in VS for easy navigation.
Feel free to check out FlitBit too (It's very modular, don't let the number of packages scare you off)! I'm working on a WebAPI package for supporting FlitBit, specifically FlitBit.IoC and FlitBit.Dto. I'll add an update if I work out my IoC issue, since it's very similar to yours.

Is there a tool to convert my GWT RemoteServiceServlet into the correct Service and ServiceAsync interfaces?

I'm working on a GWT project and I find it very tedious to have to add a function to my servlet, then copy and paste the function signature into my Service interface, then copy and paste it into my ServiceAsync interface and change the return parameter to be a callback. Is there a tool or a setting where I can just add public methods to my class and they can get copied into the other interfaces? Even if its not automatic it would be nice to be able to select specific methods and have them copied automatically.
I'm using eclipse and ideally it would update my interface each time I save implementation since thats when it checks my code and complains that my changes break the interface.
If you add the method to your *Service interface, then Eclipse can auto-generate the method ("Add unimplemented methods...") in your *ServiceImpl servlet, which you can then just fill in. Also, if you've got the Google Eclipse plugin installed, it will underline the new method in your *Service interface and complain that it's not in the *ServiceAsync. It might have a CTRL + 1 option to generate it in that interface as well.
You don't really need a tool. Just factor out the many RPC methods by just one method that takes a Request/Response. all you need to do is create subclasses of Request/Response and you don't need to think about adding new methods in the 2 interfaces.
You can use Google Guice on the server side to map the incomming request to a class handling the call... or you could use a visitor approach to forward the incoming request to the code handling the request (without resorting on a big instanceof construct).
Instantiations WindowBuilder GWT Designer does exactly what you are looking for.
The RemoteService Wizard will create all three files at the same time as well as keep them in sync as you make changes.
http://www.instantiations.com/windowbuilder/gwtdesigner/index.html
FWIW - I am only a user/purchaser of this product. I am not employed or in any other way related to Instantiations.