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

欢迎!请参阅关于页面以了解更多关于此如何工作的情况。

+1
Libs

hi folks,我在尝试Integrant库用于状态管理。当涉及到管理(启动/停止)服务器时非常直观,但对于某个特定用例我感到困惑。

我想使用 integrant 实例化和销毁一个对象。像我通常定义一样,我定义了 defmethods init-keyhalt-key!。问题是我想从 init-key 获得已初始化对象的引用。是否有这种习惯的方式?我应该将它作为 atom 在 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,并返回一个地图,其中每个键都是定义的 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` 实例的函数。
by
我知道什么是闭包,但是我在这里无法建立连接。所以我想要使用 `MyObject` 对象的方法,这个对象是作为 integrant 的 `init-key` 实例化的。如果拖得太长了,请见谅。我将尝试阅读更多关于组件应该如何工作的内容。非常感谢您的耐心!
...