announcements

kuzmin_m 2025-11-19T11:04:05.211199Z

After six months of development and production testing, I’ve released https://github.com/darkleaf/di/blob/master/CHANGELOG.md#360. The main feature of this release is the new ->memoizehttps://github.com/darkleaf/di/blob/master/src/darkleaf/di/core.clj#L972. My team has wanted the ability to spin up a fresh system in tests — each time with different components — for a long while. It took three attempts, but I finally got this feature right.

🎉 14
Ahmed Hassan 2025-11-20T10:33:20.610179Z

Congratulations for the release. > ability to spin up a fresh system in tests — each time with different components > Can you give an example of this, and how ->memoize helps in this scenario?

kuzmin_m 2025-11-20T12:36:07.152469Z

@ahmed1hsn here are https://github.com/darkleaf/di/blob/master/test/darkleaf/di/memoize_test.clj of this feature. Here is some code from my project. compact-test contains redefined envs, and if you run this test second time it will use cached components. Some component as a dependency of reitit/handler depends on this envs. And memoized-test will memoize two versions of this component.

clojure
(t/deftest ok
  (def+start [^Clock clock :java.time/Clock
              handler `reitit/handler
              agent-id `method-test2/agent-id])
  (def method :metric_data)
  (def now (.. clock instant getEpochSecond))
  (def data
    [:not-used/agent-id
     now (+ now 58)
     [[...]])
  (def req (-> (method-test2/req method data)
               (agent-id)
               (use-snapshot ::s/metric-data.txt)))
  (def resp (handler req))
  (t/is (ring.pred/ok? resp)))


(t/deftest compact-test
  (def+start [handler      `reitit/handler
              ^Clock clock :java.time/Clock
              agent-id `method-test2/agent-id]
    {"METRIC_DATA_COMPACT_ALL_HOSTS" "true"
     "METRIC_DATA_NULLIFY_PID"       "true"})

  (def method :metric_data)
  (def now (.. clock instant getEpochSecond))
  (def data
    [:not-used/agent-id
     now (+ now 58)
     [[..]])
  (def req (-> (method-test2/req method data)
               (agent-id)
               (use-snapshot ::s/metric-data-compact.txt)))
  (def resp (handler req))
  (t/is (ring.pred/ok? resp)))
clojure
(defn start-test []
  (let [memoized-test  (di/->memoize (test-registries))]
    (def memoized-test memoized-test)))

(defmacro def+start
  [bindings & middlewares]
  (let [names (take-nth 2 bindings)
        keys  (take-nth 2 (rest bindings))]
    `(let [[~@names] (di/start [~@keys] memoized-test ~@middlewares)]
       ~@(for [n names]
           `(def ~n ~n))
       nil)))