Using resources.groovy to define services - grails

I'm using the resources.groovy to declare a service e.g.
aService(com.foo.OrganizationService)
so that I can tie aService to my controllers instead of using organizationService which could change in the future.
I've noticed that the OrganizationService doesn't get treated special like other services "not" declared in the resources.groovy. For example it doesn't get injected with grailsApplication, and likely a hibernateSession etc and other things I've not hit yet....
Now, I know I can manually wire in stuff to my service but I'd rather not have to maintain that...
Is there a special way to declare a service in the resources.groovy so that gets treated like another service that grails loads up?
TIA

The short answer to your question is "no".
Under the covers, Grails services are driven by some intelligent code that is referencing a specific location and expecting certain properties.
Viewing the source code (especially around the ServicesGrailsPlugin.groovy) is a good way to see the "magic" in how these are wired together.
Is there a reason you wouldn't want to use a bonafide Grails service to solve your problem? If you are expecting things like a grailsApplication, it seems like that use is pretty specific to Grails and would be a good candidate for porting over to a "true" Grails service.
Good luck!

So I've come full circle on this. This is a timing problem. Where services haven't been grails initialized yet.
Basically when you use the resources.groovy to do service wiring you run the risk of using a Service that might initialize itself e.g. afterPropertiesSet method or static initializers that use grails services (log, hibernate session, ..) that haven't been injected yet.
So... What I've turned to instead is to create my own BeanBuilder in a BootStrap.groovy file.
BeanBuilder builder = new BeanBuilder(grailsApplication.parentContext)
def bb = builder.beans {
LoginListener(com.foo.LoginListener) {
springSecurityService = ref("springSecurityService")
userService = ref("userService")
}
}
bb.registerBeans(grailsApplication.mainContext)

Related

DefaultMessageCodesResolver in Grails

When validating domainclasses in Grails, it uses the DefaultMessageCodesResolver from Spring to "extend" the set of i18n-keys to try and lookup. I would like to simplify this, and have therefore implemented my own SimpleMessageCodesResolver by extending the MessageCodesResolver interface.
However, I can't seem to make Grails pick up on this. I've declared it as a custom dependency injection, trying to override, what Spring normally does:
messageCodesResolver(SimpleMessageCodesResolver)
I still see the DefaultMessageCodesResolver when looking at the domain object... Any ideas how to make this work?
I belive your custom dependency injection should be:
defaultMessageCodesResolver(SimpleMessageCodesResolver)
MessageCodesResolver is an interface, but not spring bean as DefaultMessageCodesResolver instance is.

Ninject binding/unbind issue

I have a bit of a dilemma, which to be honest is a fringe case but still poses an issue.
Currently I am using Ninject MVC and bind all my controllers like so:
Kernel.Bind<SomeController>.ToSelf();
Which works a treat for 99% of things that I have needed to do, however at the moment I am doing some wacky stuff around dynamic routing and dynamic controllers which require me to manually write a method to get the type of a controller from ninject. Now initially I thought it would be easy, but its not... I was expecting that I could get the controller based on its name, but that didnt work.
Kernel.Get<IController>("SomeController");
That got me thinking that its probably because it only knows about a binding to SomeController, not IController. So I thought, I can just write all my bindings like so:
Kernel.Bind<IController>.To<SomeController>().Named("SomeController");
This way it should be easy to get the type of the controller from the name doing the previous code, however if I were to bind this way, I would have a problem when I come to unbind the controllers (as plugins can be loaded and unloaded at runtime). So the normal:
Kernel.Unbind<SomeController>()
Which was great, will no longer work, and I would have to do:
Kernel.Unbind<IController>();
However then I realised that I need to give it some constraint to tell it which binding for this type I want to unbind, and there seems to be no overloads or DSL available to do this...
So I am trapped between a rock and a hard place, as I need to satisfy the ControllerLookup method, but also need to keep it so I can add and remove bindings easily at runtime.
protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
//... find and return type from ninject
}
Anyone have any ideas?
(Just incase anyone questions why I am doing this, its because of the way I am loading plugins, Ninject knows about the types and the namespaces, but within the context of creating a controller it doesn't know the namespace just the controller name, so I do this to satisfy the isolation of the plugin, and the location of the dynamic controller, it is a roundabout way of doing it, but it is what people have done with AutoFac before Example of similar thing with AutoFac)
In my opinion the bindings should be created once at application startup and not change anymore after the first resolve. Everything else can lead to strange issues. Unless you have proper isolation using an AppDomain for each plugin you can not really unload them anyway. Instead of unloading bindings you can make them conditional and disable them using some configuration.
If you really want to unload bindings then I suggest not to do it for single bindings but take advantage of modules. Load all bindings belonging to one plugin together in one or several modules and unload those modules instead of the single bindings.

How to separate interface from implementation in Grails services?

I was wondering if it's possible to create a service interface on Grails and I can't find a proper way of doing it.
This explanation isn't satisfactory, since it seems to mix Java and Groovy:
http://www.grails.org/doc/latest/guide/8.%20The%20Service%20Layer.html
It seems to me like a bad design flaw of the framework, given that the interface mechanism is one of the best features of Java (and most OO languages).
Any idea to clarify this issue?
Thanks!
Mulone
You can have an interface, but actually you don't need one. If I understand you correctly you would like to have two implementations of a service and be able to choose which one to use.
Simply implement two services named for example MyService1 and MyService2, then in grails-app/conf/spring/resource.groovy you can specify:
beans = {
...
// syntax is beanId(implementingClassName) { properties }
myService(MyService1)
...
}
or even:
beans = {
...
if (someConfigurationOption) {
myService(MyService1)
} else {
myService(MyService2)
}
}
This is how you tell Spring which service to actually inject for myService. Now you will be able to use myService like:
public MyController {
def myService
...
}
and Spring will auto wire a proper implementation. This allows you to configure which service implementation to use based for example on some configuration.
Define the service interface in a class com.mycompany.mypackage.MyInterface.groovy stored under src/groovy
Define the service implementation stored under grails-app/services
class MyService implements MyInterface {
// service implementation goes here
}
Its not a design flaw. Groovy is different than java in that it is a dynamic language that uses 'duck-typing'. Whats interesting in groovy is that there are also interfaces. So if you follow #don's suggestion, you can make sure that your service conforms to the interface, but the way you do DI with grails is to just specify the service implementation. i.e. you do not get the compile time check where you use the service implementation, like you do in java.
Note that there is no tight coupling here. Coupling implies that something is bound to a type. But with groovy's loose typing system, types are essentially dynamic creatures. So in java, if you declare a type to be a specific implementation, the code might not compile if you change the type later. In groovy, the code will always compile if you use the 'def'...(I think this is correct)
The best solution I found for this is using Spring bean aliases. Basically you need to:
1) Create an interface in src/groovy ( MyService.groovy )
2) Inject your service wherever you need it:
class MyController {
MyService myService
}
3) Create your regular services implementing that interface ( ImplOneService.groovy, ImplTwoService.groovy )
4) Add an entry to resources.groovy where you define which implementation to use (eventually, testing for environment, or anything else you need):
beans = {
if (...development, useFTP, etc...) {
springConfig.addAlias 'myService', 'ImplOneService'
} else {
springConfig.addAlias 'myService', 'ImplTwoService'
}
}
Complete sources here
My comments: Using interfaces in groovy really seems like some kind of "I want to stick with some java stuff I'm more comfortable with". In this case, strong-typing. But it's exactly the nice part of groovy saying "No worries, you can keep the java way if you want".

Grails URLMappings

I have a plugin that relies on a custom url mapping. When i install the plugin i need to copy the content of the UrlMappings.groovy of the plugin and merge it with the one in the application where the plugin is installed
I would like however to register these url mappings directly into the grails framework without copying the content into the application itself. I don't want the user to change these mappings as they are core to how the plugins works.
Anyone can give me hints where to venture to achieve that.
Thank you
-ken
Create another file in grails-app/config/ with a name ending in UrlMappings.groovy and put the customized mappings in there, for example myUrlMappings.groovy
Seems like i need to interface with UrlMappingsHolderFactoryBean directly to be able to do that. I was hoping that there might be an easier way to do that. The code below is taken from the UrlMappingPlugin itself, the only source that i found to help me solve my problem.
if (application.isUrlMappingsClass(event.source)) {
application.addArtefact(UrlMappingsArtefactHandler.TYPE, event.source)
BeanBuilder beans = beans {
grailsUrlMappingsHolderBean(UrlMappingsHolderFactoryBean) {
grailsApplication = application
}
}
ApplicationContext appCtx = event.ctx
beans.registerBeans(appCtx)
HotSwappableTargetSource ts = appCtx.getBean("urlMappingsTargetSource")
ts.swap appCtx.getBean("grailsUrlMappingsHolderBean")
}
Personally I use Java approach and inject mappings form plugin (I have only one plugin for that).
But generally my approach is following:
1.App
class UrlMappings {
static mappings = DimaURLMappings.getMappings()
}
2.Plugin (called "Dima")
class DimaURLMappings {
static def getMappings(){
return {
//Mappings here
}
}
}
Yes I need to add it manually, but on the other hand it's quite obvious where application gets that mappings, and there are no magic.
I use it in such way because I have few applications that use my plugin. If you have few plugins with mappings you will just need to merge them I think it is not hard. you could also return closure from plugin. But don't forget to change "delegate" in application.

How to avoid having injector.createInstance() all over the place when using guice?

There's something I just don't get about guice: According to what I've read so far, I'm supposed to use the Injector only in my bootstrapping class (in a standalone application this would typically be in the main() method), like in the example below (taken from the guice documentation):
public static void main(String[] args) {
/*
* Guice.createInjector() takes your Modules, and returns a new Injector
* instance. Most applications will call this method exactly once, in their
* main() method.
*/
Injector injector = Guice.createInjector(new BillingModule());
/*
* Now that we've got the injector, we can build objects.
*/
RealBillingService billingService = injector.getInstance(RealBillingService.class);
...
}
But what if not all Objects I ever need can be created during startup? Maybe I want to respond to some user interaction when the application is running? Don't I have to keep my injector around somewhere (e.g. as a static variable) and then call injector.getInstance(SomeInterface.class) when I need to create a new object?
Of course spreading calls to Injector.getInstance() all over the place seems not to be desirable.
What am I getting wrong here?
Yes, you basically only should use the Injector to create get the instance for the root-object. The rest of the application shouldn't touch the Guice-Container. As you've noticed, you still need to create some objects when required. There are different approaches for doing that, each suitable for different needs.
Inject a Provider
Provider is a interface from Guice. It allows you to request a new instance of a object. That object will be created using Guice. For example.
class MyService{
private Provider<Transaction> transactionProvider;
public MainGui(Provider<Transaction> transactionProvider){
this.transactionProvider = transactionProvider;
}
public void actionStarted(){
Transaction transaction = transactionProvider.get();
}
Build a Factory
Often you need some kind of factory. This factory uses some injected services and some parameters and creates a new object for you. Then you use this factory for new instances. Then you inject that factory and use it. There also help for this with the AssistedInject-extension
I think with these two possibilities you rarely need to use the Guice-Injector itself. However sometimes is still appropriate to use the injector itself. Then you can inject the Injector to a component.
To extend on the answer Gamlor posted, you need to also differentiate between the object types you are using.
For services, injection is the correct solution, however, don't try to always make data objects (which are generally the leafs in your object graph) injectable. There may be situations where that is the correct solution, but injecting a Provider<List> is probably not a good idea. A colleague of mine ended up do that, it made the code base very confusing after a while. We just finished cleaning it all out and the Guice modules are much more specific now.
In the abstract, I think the general idea is that if responding to user events is part of the capabilities of your application, then, well...
BillingService billingService = injector.getInstance(BillingService.class);
billingService.respondToUserEvent( event );
I guess that might be a little abstract, but the basic idea is that you get from Guice your top-level application class. Judging from your question, I guess that maybe BillingService isn't your top-level class?

Resources