i was asking the Opus 4.5 Anthropic model: > how to switch between different implementations of a polylith-interface at runtime, as opposed to polylith-base configuration time? its assessment was: > In Polylith, the standard approach wires implementations at build time (via bases selecting which components to include). For runtime switching, you need to add a layer of indirection. is it a correct assessment?
Yeah I put them in separate components. Technically I could put it all in one component, but I like the code organization and the ability to run tests for those components. I started with the convention to put protocol definitions in some-component.interface.protocols. I also put multimethods definitions there. Then I wrap the protocol ns from the interface ns. This setup allows me to have something close to a circular dependency between components. So other components implement the protocol, but also call the interface. Hope that makes sense. I don't have a small example to share unfortunately. The other convention I have is to put implementations of protocols and multimethods in a namespace named some-component.interface.extensions Note that the interface nesting is required to keep polylith happy It works well for me.
unfortunately we are using cursive, which doesn't handle the back-n-forth code navigation between protocol and multi-method declarations and implementations. even if it would, it's quite painful to not being able to see an actual implementation directly from a call-site, if it goes thru an interface function call.
my use-case is running tests in the same repl instance as the one running a local web server version of the app, so i can seamlessly switch between automated an manual testing, without the need to load the latest code into 2 repls or having some file watcher mechanism do it for me.
I think the assessment is correct. Polylith allows to have multiple components that define the same namespace (interface) so swapping this at runtime is something clojure doesn't support without problems. If you are talking about mixing components that are not conflicting, this is possible and supported by the development project where you include all the components you want to have available during development. As far as I know you still have to include path to the test directories manually. But often you can evaluate a test namespace (I use cider and emacs) without actually having it on the classpath.
I have a workflow like you are describing. I use different implementations of some protocols for development, testing and production but they don't have conflicting namespaces so I can include them in the same process. I use this process to run a local server as well as repl evaluations for tests (just repl evaluation)
do u put those dev/test/prod implementations into their own polylith components or just polylith libraries? in other words, do u even utilize interface namespaces?
i guess u must use interface namespaces, otherwise the tooling wouldn't be happy, but when u just have a single implementation, then u bake that implementation into the interface ns, to avoid indirection, when going to references or definitions in an ide. right?