Jackie
Jackie

Reputation: 23607

Proper way to autowire services to command objects in Grails when constructed inside controller

I have code like this...

@Validateable
class RecipientsCommand {
 ...
 EmailService emailService
 void getEmailEligibleRecipients(Long accountId){
    emailService.loadEligibleEmail(accountId) 
 }
}

resource.groovy

imports com.test.commands.RecipientsCommand
beans = {
 recipientsCommand(RecipientsCommand){bean -> bean.autowire = true}
}

But the service is still always null when I call

new RecipientCommand()

Since the Command Object seems to be an interface between the views and the controller I am creating it, filling it and passing it to the view. Then I am using it to parse and save data. If I change to...

EmailService emailService = new EmailService()

Everything works fine.

Upvotes: 0

Views: 838

Answers (1)

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27255

The auto wiring only happens when Grails creates the instance for you. You can't just new RecipientCommand() and expect Spring to be involved in that. If you retrieve the recipientsCommand bean from the Spring application context it will be auto wired and if the RecipientCommand is created by the framework and passed as an argument to your controller action, that will also be auto wired. invoking the new RecipientCommand() constructor will result in a new instance being created which is not auto wired.

EDIT:

Examples...

class SomeController {
    def someAction(RecipientCommand co) {
        // co will already be auto wired
        // this approach does NOT require you to have defined the 
        // recipientsCommand bean in resources.groovy
    }
}

class SomeOtherController {
    def someAction() {
        // rc will be autowired
        // this approach requires you to have defined the 
        // recipientsCommand bean in resources.groovy
        def rc = grailsApplication.mainContext.getBean('recipientsCommand')
    }
}

class AnotherSomeOtherController {
    def recipientsCommand

    def someAction() {
        // recipientsCommand will be auto wired
        // this approach requires you to have defined the
        // recipientsCommand bean in resources.groovy
    }
}

class YetAnotherController {
    def someAction() {
        // rc will not be autowired
        def rc = new RecipientCommand()
    }
}

I hope that helps.

Upvotes: 3

Related Questions