I see where you are going. You don't actually need to store the system
in an atom as it can be directly referenced from reloaded.repl.system,
but I get your point (i.e. adapters).

Thanks Marc.

On 25 February 2015 at 14:26, Marc Limotte <[email protected]> wrote:
> Hi Colin,
>
> Nesting defmethod in the start fn of the Component does have a bad smell.
> This actually seems counter to the intention of Component, which is to make
> these dependencies explicit and external.  I might do it like this:
>
> 1. Create a "pure" implementation using Component as it was intended.
> 2. Stash the system map in an atom at startup
> 3. Write some convenience functions with are the lower-arity versions, and
> use the system in the atom for the missing arguments.  Might be a good place
> to use a macro if you're doing lots of these.
>
> This way, you have isolated the "friendly" (but less pure) API from the core
> system.  You can still fall back to the versions of the functions which have
> explicit deps, which could be useful for testing and other scenarios.
>
> Example:
>
>
> ; define your components and system
> ...
>
> ; Tuck the system in here at startup
> (defonce system (atom nil))
>
> (defmulti handle-command first)
>
> (defn add-customer [db eventstore customer]
>   ...)
>
> ; Convenience function that pulls system from an atom
> (defn add-customer [customer]
>   (add-customer (@system :db) (@system eventstore) customer))
>
> (defmethod handle-command :add-customer [[_ customer]]
>   (add-customer customer))
>
> (defn export-query [db pdf-generator]
>   ...)
>
> ; Convenience function that pulls system from an atom
> (defn export-query []
>   (export-query (@system :db) (@system :pdf-generator)))
>
> (defmethod handle-command :export-query [[_]]
>   (export-query))
>
>
>
> marc
>
>
>
>
> On Wed, Feb 25, 2015 at 8:23 AM, Colin Yates <[email protected]> wrote:
>>
>> Not as curious as me! Naval gazing is happening right now :).
>>
>> I realised this is part of a bigger question:
>> https://groups.google.com/d/msg/clojure/C3mYu9fMXec/gGUF5rhhZfwJ
>>
>> On 25 February 2015 at 13:19, Jeroen van Dijk
>> <[email protected]> wrote:
>> > Sounds reasonable. Though destructuring a component (I was guessing "db"
>> > etc
>> > were fields of this particular component) isn't the same as passing the
>> > whole system. I'm guessing that you have a lot bigger system in mind
>> > than
>> > these few commands. I don't have experience with that approach. I'm
>> > curious
>> > to see what you'll end up with.
>> >
>> > Cheers,
>> > Jeroen
>> >
>> > On Wed, Feb 25, 2015 at 2:01 PM, Colin Yates <[email protected]>
>> > wrote:
>> >>
>> >> Yes, I did consider that but didn't like the idea of passing the
>> >> system around. Also handle-command would need access to the system as
>> >> well.
>> >>
>> >> I am wondering whether simply having a 'registry' component which
>> >> handlers register themselves with (e.g. a map of {predicate handler})
>> >> isn't a way forward and not using defmulti...
>> >>
>> >> On 25 February 2015 at 12:51, Jeroen van Dijk
>> >> <[email protected]> wrote:
>> >> > So I guess another question is where "handle-command" is being
>> >> > called.
>> >> > What
>> >> > about providing the component as argument to the multimethod (there
>> >> > are
>> >> > other approaches too depending on your need). So:
>> >> >
>> >> > (defmulti handle-command(fn [component command] (first command)))
>> >> >
>> >> > (defmethod handle-command :add-customer  [{:keys [db eventstore} [[_
>> >> > customer]]]
>> >> >   ... )
>> >> >
>> >> > Isn't something like this enough?
>> >> >
>> >> > Jeroen
>> >> >
>> >> > On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates <[email protected]>
>> >> > wrote:
>> >> >>
>> >> >> Hi Jeroen - sure.
>> >> >>
>> >> >> I have a gateway which can handle a number of 'commands', let's say:
>> >> >>
>> >> >> AddCustomerCommand
>> >> >> ExportQueryCommand
>> >> >>
>> >> >> to handle the AddCustomerCommand I need access to a database and an
>> >> >> eventstore. To handle ExportQueryCommand I need access to the
>> >> >> database, a PDF service and so on.
>> >> >>
>> >> >> One way of achieving this is (assuming commands are of the form
>> >> >> [:command-discriminator payload]:
>> >> >>
>> >> >> (defmulti handle-command first)
>> >> >>
>> >> >> (defn add-customer [db eventstore customer]
>> >> >>  ...)
>> >> >>
>> >> >> (defrecord AddCustomerComponent [db eventstore]
>> >> >>   ...
>> >> >>   (start [this] (defmethod handle-command :add-customer [[_
>> >> >> customer]]
>> >> >> (add-customer db eventstore customer))..)
>> >> >>
>> >> >> (defn export-reports [db pdf-generator]
>> >> >>  ...)
>> >> >>
>> >> >> (defrecord ExportQueryCommand [db pdf-generator]
>> >> >>   ...
>> >> >>   (start [this] (defmethod handle-command :export-query [[_]]
>> >> >> (export-query db pdf-generator))..)
>> >> >>
>> >> >> and so on.
>> >> >>
>> >> >> Fundamentally my question is one of dispatching where the target of
>> >> >> the dispatch requires collaborators that aren't part of the dispatch
>> >> >> payload.
>> >> >>
>> >> >> Does that clarify?
>> >> >>
>> >> >> On 25 February 2015 at 12:11, Jeroen van Dijk
>> >> >> <[email protected]> wrote:
>> >> >> > I would try to stay away from any nested def's in components (but
>> >> >> > also
>> >> >> > in
>> >> >> > other functions). I'm using component a lot and I never had the
>> >> >> > need
>> >> >> > for
>> >> >> > this.
>> >> >> >
>> >> >> > Maybe you can elaborate on why you think you need a multimethod
>> >> >> > inside
>> >> >> > the
>> >> >> > component? Maybe a full example?
>> >> >> >
>> >> >> > Cheers,
>> >> >> > Jeroen
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> > On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates
>> >> >> > <[email protected]>
>> >> >> > wrote:
>> >> >> >>
>> >> >> >> Hi,
>> >> >> >>
>> >> >> >> I have a number of commands flying around which need to be
>> >> >> >> handled.
>> >> >> >> defmulti/defmethod seem a nice answer. The problem is that each
>> >> >> >> command
>> >> >> >> handler will need different collaborators (those with long
>> >> >> >> memories
>> >> >> >> will
>> >> >> >> realise this isn't new ground here ;)).
>> >> >> >>
>> >> >> >> I want to do something like:
>> >> >> >>
>> >> >> >> (ns one)
>> >> >> >> (defmulti handle first)
>> >> >> >>
>> >> >> >> (ns two)
>> >> >> >> (defrecord CommandAHandler [collab-1 collab-2]
>> >> >> >>   component/Lifecycle
>> >> >> >>   (start [this]
>> >> >> >>     (defmethod handle :command-a ....
>> >> >> >>       (collab-1 ...)))
>> >> >> >>
>> >> >> >> I realise that the lifecycle of defmethod doesn't match the
>> >> >> >> component
>> >> >> >> (i.e. stopping can't unregister the defmethod), but my main
>> >> >> >> reservation
>> >> >> >> is
>> >> >> >> that a nested defmethod feels a bit weird. Has anyone done
>> >> >> >> anything
>> >> >> >> like
>> >> >> >> this before?
>> >> >> >>
>> >> >> >> Thanks!
>> >> >> >>
>> >> >> >> --
>> >> >> >> You received this message because you are subscribed to the
>> >> >> >> Google
>> >> >> >> Groups "Clojure" group.
>> >> >> >> To post to this group, send email to [email protected]
>> >> >> >> Note that posts from new members are moderated - please be
>> >> >> >> patient
>> >> >> >> with
>> >> >> >> your first post.
>> >> >> >> To unsubscribe from this group, send email to
>> >> >> >> [email protected]
>> >> >> >> 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 [email protected].
>> >> >> >> For more options, visit https://groups.google.com/d/optout.
>> >> >> >
>> >> >> >
>> >> >> > --
>> >> >> > You received this message because you are subscribed to the Google
>> >> >> > Groups "Clojure" group.
>> >> >> > To post to this group, send email to [email protected]
>> >> >> > Note that posts from new members are moderated - please be patient
>> >> >> > with
>> >> >> > your
>> >> >> > first post.
>> >> >> > To unsubscribe from this group, send email to
>> >> >> > [email protected]
>> >> >> > 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 [email protected].
>> >> >> > For more options, visit https://groups.google.com/d/optout.
>> >> >>
>> >> >> --
>> >> >> You received this message because you are subscribed to the Google
>> >> >> Groups "Clojure" group.
>> >> >> To post to this group, send email to [email protected]
>> >> >> Note that posts from new members are moderated - please be patient
>> >> >> with
>> >> >> your first post.
>> >> >> To unsubscribe from this group, send email to
>> >> >> [email protected]
>> >> >> 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 [email protected].
>> >> >> For more options, visit https://groups.google.com/d/optout.
>> >> >
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups "Clojure" group.
>> >> > To post to this group, send email to [email protected]
>> >> > Note that posts from new members are moderated - please be patient
>> >> > with
>> >> > your
>> >> > first post.
>> >> > To unsubscribe from this group, send email to
>> >> > [email protected]
>> >> > 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 [email protected].
>> >> > For more options, visit https://groups.google.com/d/optout.
>> >>
>> >> --
>> >> You received this message because you are subscribed to the Google
>> >> Groups "Clojure" group.
>> >> To post to this group, send email to [email protected]
>> >> Note that posts from new members are moderated - please be patient with
>> >> your first post.
>> >> To unsubscribe from this group, send email to
>> >> [email protected]
>> >> 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 [email protected].
>> >> For more options, visit https://groups.google.com/d/optout.
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Clojure" group.
>> > To post to this group, send email to [email protected]
>> > Note that posts from new members are moderated - please be patient with
>> > your
>> > first post.
>> > To unsubscribe from this group, send email to
>> > [email protected]
>> > 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 [email protected].
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to [email protected]
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected]
>> 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 [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to