External Dependency Injection Framework integration proof-of-concept

35 views
Skip to first unread message

Arseny Tolmachev

unread,
Jul 12, 2016, 1:38:03 AM7/12/16
to Lift
Hi, everyone.

I have created a small PoC for integrating external dependency injection framework into Lift.
Right now, it is difficult to inject services into snippets to create testable and modular code.
Of course, you can use cake pattern or built-in capabilities, but other frameworks could be more feature-reach and allow creation of better testable snippets.

My additions are in this branch https://github.com/eiennohito/lift/tree/external_di (only top commit)
It is done on top of Lift 2.6.3, the version I am using for the time being.


If you are interested in this getting to the main branch, please let me know.

Antonio Salazar Cardozo

unread,
Aug 7, 2016, 7:29:28 PM8/7/16
to Lift
Took a while but I finally had a look here. A few notes:

 - It's not immediately obvious to me what the example really tries to
   achieve. Are you attempting to decouple from `S`?
 - Lift itself provides dependency injection out of the box with `FactoryMaker`
   and `Injector`, one of which allows you to inject things by request/session
   and the latter of which allows generalized dependency injection and stack-
   limited customization of an injected variable.
 - That said, I get that some may prefer to use some other framework they're
   more familiar with. I dig that possibility, and to that end I'd ask what you think
   Lift could do to make that easier to be implemented externally to the core.
   Can you maybe lay out an explanation of which bits of Lift's internals you felt
   needed to change in order to let you achieve this, and why?

Thanks for sharing!
Antonio

Antonio Salazar Cardozo

unread,
Aug 7, 2016, 7:33:58 PM8/7/16
to Lift
Thought about this a little more and looked at the commit more closely… It seems
like really what you needed was a way to intercept Lift's snippet instantiation. You
can to a large extent already do that with `LiftRules.snippets`—which I think stands
in for your `snippetInstantiation` abstraction. However, instead of operating on a class,
it operates on what is invoked from the HTML, which is just a string (or really a list of
them). These can in turn be resolved to classes. You should be able to plug your custom
instantiation strategy directly into `LiftRules.snippets`, without making any changes
to Lift core, I believe.

Exposing Lift's snippet-name-to-class-instantiation logic for customization is something
I've been wanting to do for a little while; hopefully I'll have some time to look at it during
the Lift 3.1 cycle.
Thanks,
Antonio

Arseny Tolmachev

unread,
Aug 7, 2016, 9:48:14 PM8/7/16
to Lift
Thank you for taking your time form looking into the implementation and the reply!

Lift's DI code is usable only within Lift. I wanted reuse Guice high-level service code in my other projects and wanted to use it with Lift as well without getting Lift to depend on Guice. 

For the implementation itself, I needed to hijack snippet and comet actor instantiation. 
Comets are hijackable by LiftRules.cometCreationFactory (you need to initialize it by calling package private LiftCometActor.callInitCometActor), but snippets aren't.

LiftRules.snippets can be used for this, certainly, but I would need to reimplement everything currently there is: instance caching, reflective calls, error messages. It needs to output resolved NodeSeq transformation.

If you are open to incorporating the logic for the snippet instantiation, I would be glad to apply your suggestions and comments and submit a pull request.

Arseny



Antonio Salazar Cardozo

unread,
Aug 8, 2016, 1:45:17 PM8/8/16
to Lift
Let me think on the snippet instantiation thing for a bit. I like the idea of abstracting it
out, but I haven't had a chance to think about the best way to do that yet. Plus I want
to keep my limited Lift time dedicated to the list + getting 3.0.0 out the door ASAP for
now.

So it might be a little while but please know I'm keeping this in mind :)

And thanks again for sharing your work—always great to see how others are adapting
Lift to their use cases. My proposal to use LiftRules.snippets, btw, is ~80% about letting
you use this without depending on a Lift-internal change which could take a little bit to
be released.
Antonio
Reply all
Reply to author
Forward
0 new messages