Clojure 2024 状态调查! 中分享您的想法。

欢迎!有关如何工作的更多信息,请参阅 关于 页面。

+1 投票
Libs

大家好,我正在尝试使用 Integrant 库进行状态管理。在管理(启动/停止)服务器方面相当直观,但我对某个具体用例感到困惑。

我想使用 Integrant 来创建和销毁一个对象。像我平时一样,我定义了 init-keyhalt-key! 的 defmethods。问题是我希望从 init-key 获取初始化对象的引用。有没有什么习惯的做法来做这件事?我应该让它在 init-key 的一个原子中可用吗?

(defmethod ig/init-key :my-space/my-key [_ opts]
  (let [account-id (:account-id opts)
        license-key (:license-key opts)]
    (MyObject. account-id license-key)))

;;How do I use the instantiated my object?

2 个答案

+1 投票

调用 (ig/init config) 时,它根据您的配置映射的依赖顺序调用 ig/init-key,并返回一个映射,其中每个键是定义的初始化键中的一个。在您的示例中,它将返回 {:my-space/my-key #<MyObject…>}。根据您的应用结构,您可以将这个映射放入 var 或 atom,或者您可以将其作为参数传递给您的 ring 中间件,以便每个请求都有一个引用等。

要调用 MyObject 的方法,您将编写 (.someMethod (:my-space/my-key system))

0 投票

您把该 :my-space/my-key 用作另一个组件的参数,该组件将收到由 MyObject 创建的实例。

例如,如果您使用 Integrant 与 Aero,它会看起来像这样

;; my_space.clj
(defmethod ig/init-key ::my-key [_ opts]
  (let [account-id (:account-id opts)
        license-key (:license-key opts)]
    (MyObject. account-id license-key)))

(defmethod ig/init-key ::other-key [_ {:keys [my-object]}]
  (println "Got object" my-object))

;; config.edn
{:ig/system
 {:my-space/my-key    {:account-id  1
                       :license-key 2}
  :my-space/other-key {:my-object #ig/ref :my-space/my-key}}}
我想在 defmethod 外面使用它。我想在普通函数中使用 `MyObject`。
这样就会滥用 Integrant,基本上把整件事都抛出了。您可以向普通函数提供一个额外的来自某处的参数,该参数包含该对象,您可以在 `::other-key` 组件中创建这些函数作为封闭体,您可以让它们成为协议的一部分,并从 `::other-key` 组件返回一个实现对象。所以,您的问题有解决方案,创建一个全局单例并不是一个好的做法。
我不太确定我理解了关于“带额外参数的普通函数...可以将其作为封闭体创建”的解决方案。你能给我一个例子吗?
每个函数都有一个调用者。您无需依赖某个全局可用的单例,而是可以为每个调用者额外传递一个参数,将 `MyObject` 的实例传递给需要它的函数。闭包是一种不同的方法,其中包含一个值,例如在 `(let [x 1] (fn [] x))` 中,`fn` 是一个封装 `x` 的闭包。在 `::other-key` 组件中,您可以创建封装 `MyObject` 实例的函数,而无需将其作为参数传递。
我知道闭包是什么,但我无法在这里连接这些点。因此,我想使用作为 integrant 的 `init-key` 部分实例化的 `MyObject` 对象的方法。如果写得过长,请见谅。我将尝试阅读更多关于“组件”应该如何工作的内容。非常感谢您的耐心!
...