Chris,

I agree with Marius' comments.  By using Scala's functions and partial
functions, I have not found any need for Dependency Injection or many of the
other Java limitation workaround patterns.

Snippets are not associated in any way with persistence.  Snippets can work
any way you want and are not tied to a particular mechanism for storing
data.  Snippets are simply a way to transform XML to XML.

Lift's mapper classes are meant to be ActiveRecord-ish... closely tied to an
RDBMS... nothing more, nothing less.  There's no mocking in Mapper... most
of the tests I write for Mapper related stuff functions just fine against H2
or PostgreSQL.

Scala's traits used in conjunction with runtime logic singletons (e.g.,
LiftRules and S in Lift) mean that you don't need DI or other stuff.  How
can these things be used together?


   - Business logic should be expressed in traits.  Because traits can be
   mixed into anything and they can contain methods, you can abstract your
   business logic from your persistence, but also mix the business logic into
   your persistence.
   - Instead of hardcoding the access to the singletons, you can go through
   a Factory:
   User.find(By(...)) ->  UserFactory().find(By(...))



On Sun, Aug 30, 2009 at 8:21 AM, Chris Lewis <burningodzi...@gmail.com>wrote:

>
> I like the Lift framework. It has its rough edges, but it's a great way
> to get into web app development using scala. It borrows many good ideas
> from other frameworks, most notably its convention over configuration
> structure (rails) and its scriptless view layer (wicket).
>
> One thing I'm not a big fan of is its baked-in database layer, the
> Mapper (now in flux and being reborn as Record), and so was pleased to
> find the JPA archetype in the 1.1 tree. Using this archetype, you get a
> barebones but functioning lift app using pure JPA. This is a great
> start, but when I poked around the snippets I saw two things that
> troubled me:
>
> The underlying entity manager API leaks directly into what would be the
> service layer API; a single object exposed as Model.
> The snippet code is hardwired to Model, which uses it directly as a
> global DAO.
>
> This archetype is still in development, and it very well may change.
> It's carries a nature of being experimental; showing you how it can be
> done, but probably not how it should be done.
>

This is debatable.  While I agree that the large, multi-team projects are
going to call for more abstraction than a smaller project, showing people
how to do things closer to the metal and letting them build their own
abstractions can be more instructive.


>
> However, it highlighted an issue I have with Lift, one that the boring
> enterprise crowd has solved: dependency injection.
>
> I have an admittedly specific idea in mind for what I want to implement
> in my would-be Lift app: I want to be able to declare a few fields and
> annotate them so that a layer above will provide me with acceptable
> instances. Yeah, I want to inject DAOs in the oh-so-familiar
> Guice/Spring/T5 IoC way. I like this partially because it's familiar,
> but also because it provides me with loosely coupled code.
>

There's nothing that prevents you from doing that.  Lift is agnostic as to
the classes used/accessed in snippets.

Personally, I think that annotations indicate failure of the language.  When
annotations are required, it leads to a "second language" that runs in
parallel with the main language (Java, Scala, Python, etc.)  Thus, I have
tried to keep annotations out of Lift.


>
> There's been some good discussion on the subject of implementing
> dependency injection in Scala using mere language constructs. I dove
> into this subject, starting with chapter 27 of
> [http://www.artima.com/shop/programming_in_scala]: "Modular Programming
> Using Objects." It's a good read, and I recommend the book. After that I
> found my way to some relevant posts in the blogs of Debasish Ghosh and
> Jonas Boner, respectively:
>
> http://debasishg.blogspot.com/2008/02/scala-to-di-or-not-to-di.html
>
> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
>
> Very cool indeed, but I've slightly digressed. What I want to explore is
> how to loosely couple the persistence implementation (be it JPA, JDO, or
> a baked in model) with the accessing of persistent objects. I don't see
> how the aforementioned technique (the "cake" pattern) would help in the
> case of lift snippets, because we don't have any kind of hooks where we
> can provide configuration of snippets (at least, not that I know of).
> This is exactly the issue that DI solves.
>

I don't believe snippets need this kind of configuration if you follow the
same patterns as we've followed with LiftRules and S.  If, however, you
disagree, you can always create your own SnippetScope trait that you mix
into your Snippets.  This trait could provide all the services your snippet
could want (persistence, etc.)  The trait could configure itself during
construction and provide whatever services you want.


>
> So what are the thoughts of the lift-power users? Is there a way to get
> this in lift, or would you say that I am doing it wrong?
>

One of the most flexible parts of Scala is uniform access.  A parameterless
method looks like a val looks like a var looks like an object.  Thus an
trait can define a contract (e.g. def firstName: ValueHolder[String]) which
could be satisfied by object firstName extends MappedString or lazy val
firstName = .... ,etc.  With this kind of flexibility, fields, methods, etc.
all appear to the application and to the trait as the same thing.  This,
combined with factory functions and partial functions lead to a very
flexible way to build environment using language constructs.

Does this help?

Thanks,

David


>
> sincerely,
> chris
>
> >
>


-- 
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

--~--~---------~--~----~------------~-------~--~----~
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