weavejester / integrant

Micro-framework for data-driven architecture
MIT License
1.24k stars 64 forks source link

RefMap or resolve as protocol method #63

Closed clyfe closed 4 years ago

clyfe commented 4 years ago

RefMap would be like RefSet but would resolve to a map {k -> ref} instead a refs set. Knowing the key can be useful (think handler registration). Alternatively, extend the RefLike protocol with a resolve method and in expand-key postwalk the config via it, this would allow custom RefThings. Sample:

(defprotocol RefLike
  (ref-key [r] "Return the key of the reference.")
  (resolve [r config]))
;; ...
(defn- expand-key [config value]
  (walk/postwalk
   #(cond
      (reflike? %) (resolve % config)
      :else %)
   value))
clyfe commented 4 years ago

I just noticed the resolve-key multi-method in 0.8.0-alpha, which can be used to bring the key into the output; nevertheless, the notes above are still desirable to have.

clyfe commented 4 years ago

PR https://github.com/weavejester/integrant/pull/64

weavejester commented 4 years ago

Knowing the key can be useful (think handler registration).

Can you explain your use-case further?

clyfe commented 4 years ago

In the config map I want to have:

Outcome in the system map:

Something along these lines:

;; ns registry
(derive ::handler :module/const)

(defn register [[k v]]
  #_(... register v to handle events named k))

(defmethod ig/init-key ::handlers [_ handlers]
  (run! register handlers)
  handlers)

;; ns my.handlers
(defn foo ...)
(defn bar ...)

(derive ::foo ::registry/handler)
(derive ::bar ::registry/handler)

(def config {::foo foo
             ::bar bar
             ::registry/handlers (ig/refmap ::registry/handler)})
clyfe commented 4 years ago

RefLike protocol was extended. RefMap construct was not accepted into the core. Standalone RefMap implementation based on the extended RefLike protocol is here: https://github.com/tape-framework/refmap