Set of Duct modules and integrant components for a rapid clojure development.
Assuming you already have a Duct project bootstrapped. Add to your leiningen dependencies:
[io.github.parencat/fx "0.1.2"]
:fx.module/autowireAutowire module purpose is to reduce a hassle while configuring your application components. This module will scan your
project namespaces. Whenever Autowire will find some ns members (vars or functions)
with :fx/autowire key in the metadata it will automatically create an integrant key and a configuration map.
To enable autowire module add this key to your Duct config.edn file
{:duct.profile/base
 {:duct.core/project-ns your-project-root-namespace}
 ;; other profiles and modules
 :fx.module/autowire {}}
You can limit a number of scanned namespaces by providing a :root path for some file or folder
{:duct.profile/base
 {:duct.core/project-ns your-project-root-namespace}
 ;; other profiles and modules
 :fx.module/autowire {:root your-project-root-namespace/components}}
After that you can attach :fx/autowire key to any members, e.g.
(ns my-project.core)
(def ^:fx/autowire db-connection
  (jdbc/get-connection {:connection-uri "db-uri"
                        :dbtype         "sqlite"}))
In this case Autowire will create :my-project.core/db-connection component and you can reference and use
it in other components. Notice that autowired components always has a namespaced keyword as its name
(to prevent the components name clashes)
e.g.
(let [db (-> (ig/find-derived-1 system :my-project.core/db-connection)
             (val))]
  (jdbc/execute! db ["SELECT * FROM users ..."]))
Also, you can specify dependencies for your components as arguments metadata:
(defn ^:fx/autowire get-users [^:my-project.core/db-connection db]
  (fn []
    {:status :ok
     :users  (jdbc/execute! db ["SELECT * FROM users ..."])}))
This kind of dependency injection already built-in into the Duct framework, Autowire is just reducing some boilerplate around it.
:fx/halt
By default, Autowire will create only ig/init-key methods for found components.
It is possible to create a ig/halt-key! method as well.
All you need it's to add :fx/halt key with the name of component to the metadata
(ns my-project.core
  (:import
   [java.sql Connection]))
(def ^:fx/autowire db-connection
  (jdbc/get-connection {:connection-uri "db-uri"
                        :dbtype         "sqlite"}))
(defn close-connection
  {:fx/autowire true
   :fx/halt     ::db-connection}
  [^Connection conn]
  (.close conn))
:fx/wrap
You can add :fx/wrap key to wrap a component in the anonymous function for the later usage.
Without wrapping you'll have to return an anonymous function which holds the dependencies as closures:
(defn ^:fx/autowire get-users 
  [^:my-project.core/db-connection db]
  (fn [request]
    {:status  200
     :headers {"Content-Type" "application/json"}
     :body    (jdbc/execute! db ["SELECT * FROM users ..."])}))
with wrapping your component will be initialized with the partially applied function:
(defn ^:fx/autowire ^:fx/wrap get-users
  [^:my-project.core/db-connection db request]
  {:status  200
   :headers {"Content-Type" "application/json"}
   :body    (jdbc/execute! db ["SELECT * FROM users ..."])})
For more examples check  fx.module.stub-functions and fx.module.autowire-test namespaces.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs | 
| ← | Move to previous article | 
| → | Move to next article | 
| Ctrl+/ | Jump to the search field |