Fork me on GitHub
#component
<
2022-08-19
>
Ziad Salah15:08:29

Hi all, happy Friday! Am I expected to implement Lifecycle in all of my components, even ones for which I have no state nor anything to setup and teardown?

hiredman16:08:17

no, Lifecycle has a no-op extension to Object

👍 1
Ziad Salah16:08:57

Was just about to say I've reread the readme and saw the following:

The default implementation of Lifecycle is a no-op. If you omit the Lifecycle protocol from a component, it can still participate in the dependency injection process.
Thanks for confirming. I do have a follow-up question though:

Ziad Salah16:08:19

The readme also mentions:

Components which do not need a lifecycle can be ordinary Clojure maps.
In my case, say I have a component SomeThirdPartyApi, I've made it a defrecord which implements a custom protocol, for example:
(defprotocol SomeThirdPartyProtocol
  (get-info-from-third-party [this email] "Get info for user with email"))
Is this 'overkill' at all? How do I reconcile what I'm trying to do with the message above about components with no need for a lifecycle potentially working as a map?

hiredman16:08:44

there are several different constraints depending on what you are doing

hiredman16:08:07

you can put anything at all in the system map

👍 1
hiredman16:08:59

but in order to depend on anything else in the system map, because of the way component injects dependencies, it has to be map like

👍 1
hiredman16:08:09

(a defrecord is map like)

👍 1
Ziad Salah16:08:21

Awesome, thanks for explaining that

Ziad Salah16:08:16

I suppose a related question is that the docs mention:

Define the functions implementing the behavior of the component to take an instance of the component as an argument.
In my case I've opted to do that via a protocol definition that the defrecord implements. When would you opt for a good old function vs one defined in a protocol and implemented in a record?

hiredman16:08:36

an extremely useful feature of clojure protocols when combined with component is the ability to make protocols extendable via metadata

hiredman16:08:48

protocol vs. just a function is going to depend on if I have more than one implementation (often the second implementation is a kind of mocked version of the component for tests)

👍 1
Ziad Salah16:08:51

Thank you so much for all of this. So it may make sense for me to default towards 'just a function' and only go down the protocol route either if I find myself needing to mock behaviour for tests, or make use of protocol extensions. Thank you also for the links on protocol extensions. I think I will need to do some reading and look at examples to wrap my head around when I might find that useful.

seancorfield17:08:56

@UVD9WKYDQ https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc/connection.clj#L320-L328 -- uses an empty hash map with start attached via metadata and it returns a function with stop attached via metadata. Since there are no dependencies, any Clojure "object" can be used (as long as it can carry metadata).

👍 1