I want to set body of Html email from String, not Xml Node for Lift Mailer, so I subclassed Mailer and redefined buildMailBody method:
class HtmlMailer extends Mailer {
final case class HtmlMailBodyType(text: String) extends MailBodyType
override protected def buildMailBody(tab: MailBodyType) = {
tab match {
case HtmlMailBodyType(text) =>
val bp = new MimeBodyPart
bp.setText(text, charSet, "html")
bp
case _ => super.buildMailBody(tab)
}
}
}
object HtmlMailer extends HtmlMailer
When I try to use it:
import net.liftweb.util.Mailer
import Mailer._
HtmlMailer.sendMail(From(sender.email), Subject(subject), To(user.email), HtmlMailBodyType(body))
I get compilation error:
error: type mismatch;
found : net.liftweb.util.Mailer.From
required: com.mypackage.HtmlMailer.From
Error occurred in an application involving default arguments.
HtmlMailer.sendMail(From(sender.email), Subject(subject), To(user.email), HtmlMailBodyType(body))
Why is this happeing and how can I fix it correctly?
I changed import Mailer._ to import HtmlMailer._ and it worked, but I beleive it breaks Liskov substitution principle, as I cannot substitute HtmlMailer instead of Mailer, because they have different parameter types?
You are having trouble with path dependent types and singletons. When you have nested classes, each instance of the outer class has a different instance of the nested class.
Now, the
From(plusSubject,To, etc), since they are nested, belong to a specific instance. In this case, you have two instances providing them. They are the objects:Note that these are not classes, they are objects.
Now, the method
sendMailrequires that its parameters be composed of classes belonging to the same instance as itself. There are many reasons for making such a requirement, as there are ways of not making it.So, really, there’s no violation of the liskov substitution principle here, just a violation of type that has been hidden by the import. If you write it out explicitly, it becomes clearer:
You can replace
HtmlMailerthere withnet.liftweb.util.Maileror any other instance ofnet.liftweb.util.Mailerand it will work. You cannot use two different instances ofnet.liftweb.util.Mailer, even if they are both of the very same class.