Я не совсем уверен, что делает метод sendMail, поскольку у меня нет упомянутой вами книги. Метод sendMail действительно требует закрытия, как вы описали, но он, вероятно, использует построитель , а не выполняется обычным способом. По сути, это будет специфичный для домена язык для описания отправляемого электронного письма.
Причина, по которой определенный вами класс не будет работать, заключается в том, что область действия закрытия - это то место, где оно объявлено, а не то, где оно запускается. Таким образом, если ваше закрытие вызывает метод to (), он не сможет вызвать метод to в MailService, если вы не передадите экземпляр почтовой службы в закрытие.
С некоторыми изменениями ваш пример может работать, хотя и с использованием регулярное закрытие. Следующие изменения в вызове и
// The it-> can be omitted but I put it in here so you can see the parameter
service.sendMail {it->
it.to "foo@example.org"
it.subject "Registration Complete"
it.body view:"/foo/bar", model:[user:new User()]
}
Метод sendMail в классе должны выглядеть следующим образом
def sendMail(closure) {
closure(this)
// Code to send the mail now that all the
// various properties have been set
}
MailService.sendMail делегирование закрытия:
MailMessage sendMail(Closure callable) {
def messageBuilder = new MailMessageBuilder(this, mailSender)
callable.delegate = messageBuilder
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.call()
def message = messageBuilder.createMessage()
initMessage(message)
sendMail message
return message
}
и, например, метод в MailMessageBuilder:
void to(recip) {
if(recip) {
if (ConfigurationHolder.config.grails.mail.overrideAddress)
recip = ConfigurationHolder.config.grails.mail.overrideAddress
getMessage().setTo([recip.toString()] as String[])
}
}