integrant

2018-09-28T01:54:08.000100Z

You could go the other way using :source-paths in project.clj. E.g.

;; project.clj
(defproject project "0.1.0-SNAPSHOT"
  ...
  :profiles
  {:dev          [:project/dev :profiles/dev]
   :profiles/dev {}
   :project/dev  {:source-paths   ["dev/src"]
                  :resource-paths ["dev/resources"]}})
;; dev/src/project/external/service.clj
(ns project.external.service
  (:require [integrant.core :as ig]))

;; Public interface
(defprotocol ExternalService
  (get-smth [this arg]))

(defrecord Boundary [config]
  ExternalService
  (get-smth [_ arg] (prn arg))

(defmethod ig/init-key :project.external/service [_ config]
  (->Boundary config))
;; src/project/external/service.clj
(ns project.external.service
  (:require [integrant.core :as ig]))

;; Public interface
(defprotocol ExternalService
  (get-smth [this arg]))

(defrecord Boundary [config]
  ExternalService
  (get-smth [_ arg] (implementation-for arg))

(defmethod ig/init-key :project.external/service [_ config]
  (->Boundary config))

2018-09-28T01:55:56.000100Z

I'd be tempted to write two keys, :project.external.service/fake and :project.external.service/live, both inheriting from :project.external/service. Then just replace the live key with the fake one in development.