Clojure - 将组件传递给在启动或停止期间未执行的函数

时间:2015-11-01 20:39:26

标签: clojure architecture

在Stuart Sierra组件的自述文件中,有一个函数add-user作为示例给出,但在其他任何地方都看不到:

(defn add-user [database username favorite-color]
  (execute-insert (:connection database)
    "INSERT INTO users (username, favorite_color)"
    username favorite-color))

我想它可以在Web服务器路由上执行(例如)。我毫不费力地想象usernamefavorite-colour将成为该路线的参数,因此在调用add-user时可以随时使用。

我想有这个会产生database(例如)组件的web-server组件。 但是我在确定database的{​​{1}}组件实例参数应该来自哪里时遇到了一些麻烦。

我觉得直接访问add-user(即做system)来检索它会破坏部分首先使用组件的目的。

例如,如果我使用基座,我可能有我的基座组件(谁有权访问数据库组件)设置此密钥:

(:database my-system-ns/system))

这就是这样的:

::bootstrap/routes #(deref #'my-routes-ns/routes)

如何在此示例中访问我的;; in my-routes-ns (defroutes routes [[[ "/add-user" {:post add-user-handler} ]]]) ;; same function again for clarity (defn add-user [database username favorite-color] (execute-insert (:connection database) "INSERT INTO users (username, favorite_color)" username favorite-color)) ;; my route handler (defn add-user-handler [request] ;; How do I get access to the database component from here ? (add-user database "user" "red")) 组件?

2 个答案:

答案 0 :(得分:2)

在典型的应用程序中,您的web-server组件可能包含component/using组件(请参阅database),以及与{{1}相关联的公共函数集合消费者可以调用的组件来查询数据库。

database组件将负责设置您的请求处理程序并启动侦听器(如Jetty)。这将涉及获取web-server组件并将其注入您的处理程序,可能通过部分应用程序(如果您的处理程序看起来像database),以便它可以在实际上调用(defn handler [database request] …) add-user组件。

请注意,根据您应用的设计,您的设置可能与上述内容完全不符 - 例如,database只能通过一层或多层中间组件使用web-server组件。< / p>

答案 1 :(得分:1)

仅供参考,the README of component建议在一个或多个组件上创建一个闭包,

(defn app-routes
  "Returns the web handler function as a closure over the
  application component."
  [app-component]
  ;; Instead of static 'defroutes':
  (web-framework/routes
   (GET "/" request (home-page app-component request))
   (POST "/foo" request (foo-page app-component request))
   (not-found "Not Found")))

(defrecord WebServer [http-server app-component]
  component/Lifecycle
  (start [this]
    (assoc this :http-server
           (web-framework/start-http-server
             (app-routes app-component))))
  (stop [this]
    (stop-http-server http-server)
    this))

(defn web-server
  "Returns a new instance of the web server component which
  creates its handler dynamically."
  []
  (component/using (map->WebServer {})
                   [:app-component]))