And just to be clear - I get _why_ explicit parameter passing is a good 
idea, or rather why dynamic binding is frowned upon, I am asking for 
practical help with the consequences of that decision.

I also get the argument that a transaction changes at runtime state and so 
shouldn't be part of the (Stuart Sierra's) component lifecycle, but I can't 
be the only one to run into this; func-a calls func-b calls func-c which 
needs some state - the answer can't be for func-a to pass it to func-b 
particularly when neither of them know anything about the internals of 
func-c.

On Wednesday, 4 March 2015 17:58:58 UTC, Colin Yates wrote:
>
> Hi,
>
> I am looking for the Clojure equivalent of:
>
> class Whatever {
>     @Transactional
>     void doSomething(IDoSomething one, IDoSomethingElse two) {
>       one.doSomething()
>       two.doSomething()
>     }
> }
>
> where both one and two are dependency injected with a proxy which resolves 
> to a thread local database connection. In addition, one might itself have a 
> collaborator which itself has a collaborator which needs a datasource.
>
> So far I have two protocols:
>
> (defprotocol IDoSomething
>  (do-something [this ...])
>
> (defprotocol IDoSomethingElse
>  (do-something [this ...])
>
> Each protocol may have a number of implementations, one of which is a JDBC 
> implementation:
>
> (defrecord JdbcIDoSomething [db]
>   (do-something [this ...] ...))
>
> The problem is that the calling code only gets provided an IDoSomething 
> and an IDoSomethingElse and it wants to do something like:
>
> (let [one (->JdbcDoSomething db) two (->JdbcDoSomethingElse db)]
>   (with-transaction [tx db]
>     (do-something one)
>     (do-something-else two)))
>
> The problem here is that the implementations of do-something and 
> do-something-else won't have access to the local bound 'tx', they will have 
> their own 'db'.
>
> I realise the general argument is to be explicit and pass a db as the 
> first argument to the protocol but this isn't appropriate in this case as 
> there are validly multiple implementations. I could abstract a 
> 'unit-of-work' and pass that as the first argument to the protocols but 
> that seems a bit painful.
>
> Also, these protocols may be used quite far away from where the database 
> code lives and passing a parameter all the way through the call stack is 
> painful.
>
> I am using Stuart Sierra's components if that makes any difference.
>
> I can't be the first person to run into this but google is surprisingly 
> unhelpful which makes me think I have missed something fundamental, and 
> that I have something upside down.
>
> What do you all do?
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to