I been debating how I want to handle optional dependencies, and this kinda relates to it. I wanted to get some other’s thoughts on how to go about it.
Use Case
The current plan for my Athena shard is that athena
itself will be made from some required components (like DI/Routing), but also some optional shards (like logging or validation) that are independent and can be used outside of athena
itself.
Problem
This setup works just fine with the required shards as I can explicitly add some require
within code that integrates that shard into athena
core; such as registering services for DI, etc. However, things get a bit more tricky when a shard is not required.
An example would be, say someone installs athena-logger
shard. The goal would be by just installing the shard, athena
core sets some stuff up in order to integrate the logging component.
Option 1
Have an ext file within the optional shard that should be required by the user in addition to the shard itself
require "athena-logger"
require "athena-logger/ext/athena"
Not a big fan of this approach since this would make the optional shard depend on additional shards that athena
core requires, mainly DI.
Option 2
Have an ext file within athena
core that should be required by the user if they install the optional shard
require "athena"
require "athena/ext/logger"
This is probably the better more explicit approach
Option 3
Have some file in athena
core that auto does the integration if it sees the optional shard is installed
{% if @type.has_constant? "Athena::Logger::Version" %}
# Do the setup
{% end %}
This would be the most seamless approach as the fact that they installed the other shard says they want to use it within athena
core. This could also be used in conjunction with option 2.
I think having a better way to handle option 3 would be a nice to have.