One option might be implicit parameters, but it doesn't seem as clean 
(could be a knee jerk). I tried defining an implicit param on the form 
handler, but then lift couldn't find the mapped handler. Doing this I 
believe changes the function signature, and so the reflective call 
doesn't see it.

However, you can define a method on your snippet that takes an implicit. 
Consider a simple snippet:


trait UserService {
   def findByUserName(userName: String) : String
}

object Config {
   implicit val us = new UserService() {
     def findByUserName(userName: String) = userName
   }
}

import Config._

class MySnippet {

   def userService(implicit us: UserService) = us

   def login(xhtml : NodeSeq) : NodeSeq = {
     var userName = ""
     var password = ""

     def doLogin() = {
       println(userName + "; " + userService.findByUserName(userName))
     }

     bind("user", xhtml,
       "userName" -> SHtml.text(userName, userName = _),
       "password" -> SHtml.password(password, password = _),
       "submit"   -> SHtml.submit(?("Save"), doLogin _)
     )
   }
}


Notice the part in the doLogin closure:

userService.findByUserName(userName)

Because of the universal access principal, we can treat userService, a 
single argument function that returns type UserService (a trait), as an 
object. Also see how the userService method receives an implicit 
parameter. Because we define an object (Config) that provides an 
implicit value of that type, and we import that value, the compiler can 
provide it implicitly.

One thing about this method is that we have to have a satisfying 
implicit value in scope. In a unit test we could easily do it on the 
fly, but for normal execution I'm not sure where you can plug something in.

I'd still love to hear more thoughts, and if this method could be at all 
usable.

sincerely,
chris

Jeppe Nejsum Madsen wrote:
> Chris Lewis <burningodzi...@gmail.com> writes:
> 
>> I am specifically talking about decoupling my web logic, ie, event 
>> handlers for forms in lift snippets, from the persistence layer. As 
>> currently implemented, snippets know exactly what persistence mechanism 
>> is in use because there is no intermediary API. 
> 
> Chris, I'm sharing the same concerns as you about the decoupling. For
> now, I've just accepted it to get started with Lift.
> 
> But now that our app starts to grow, I think we'll need to find a
> good solution for this in order to 
> 
> 1) Maintain a good test suite (I'm a strong believer in TDD and
> automated testing in general. I don't think that having type safety and
> FP makes tests obsolete).
> 
> 2) Loosely couple the code to make it maintainable over time 
> 
> 
> One of my big issues right now is how to test snippets that access the
> persistence/business layer. This is trivial if snippets has some kind of
> DI, as you could just inject mock objects instead of the real
> thing. Alas, I haven't found a good solution yet. I do think that Scala
> provides some language support for this (ie. the articles you linked to)
> and I would like to pursue this first, before using more heavyweight
> solutions such as Spring/Guice etc.
> 
> /Jeppe
> 
> 
> > 
> 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to