Advice on where to define dependency injection providers
See original GitHub issueI am writing an xmlboiler
program, especially its core library xmlboiler.core
.
I define ExecutionContext
in xmlboiler.core.execution_context
module.
ExecutionContext
is meant to contain a common “environment” suitable for different kinds of tasks.
Currently ExecutionContext
contains a logger and a translator of messages:
class ExecutionContext(object):
def __init__(self, logger, translations):
"""
:param logger: logger
:param translations: usually should be gettext.GNUTranslations
"""
self.logger = logger
self.translations = translations
Now I want to define some providers using dependency_injector.providers
module.
Where (in which module) should I define default factories for loggers, translations, and execution contexts? (Default logger should log to stderr, default translations should respect LANG environment variable.)
The only quite clear thing is that providers should be defined somewhere in xmlboiler.core.*
namespace, because it is the namespace for the core library (to be used by several applications).
Should I define providers in xmlboiler.core.execution_context
module or in something like xmlboiler.core.execution_context_build
, or maybe in something like xmlboiler.core.providers.execution_context
?
Note that I think, that it should be in xmlboiler.core.execution_context*
rather than in xmlboiler.core.providers*
, because in this case the naming rules would not prevent (incorrect) move event to xmlboiler.providers*
. Also I don’t want to define the providers in xmlboiler.core.execution_context
not to add additional dependencies for this module. However, I am not sure.
The documentation should explicitly address such a question.
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
Dependency Injector is designed to be a micro framework, not an application framework. This means that there could be different points of view on how application architecture should look like. However, the goal of “Dependency Injector” is to deliver minimal functional blocks that one can play with for implementing some particular vision.
It does not mean that I do not have my personal vision on using “Dependency Injector for creating applications, but it means more that it’s sort of my own preferences.
Going back to your particular case, I, personally, thinking about next things:
providers
module anywhere in your library. The thing is thatProvider
is a strategy of retrieving an object. Typical providers areFactory
,Singleton
,Object
,Configuration
etc… So, basically, you need to subclass providers once you see a certain, not yet covered, way to provide objects. There could be two such situations:Factory
provider -Factory(create_object_with_complex_initialization, <injections>)
.Singleton
could lead to “double initialization”, so there is a need to useThreadSafeSingleton
. Another example with multithreading is aThreadLocalSingleton
that creates singleton objects in the scope of each thread. Still, a lot of cases are already covered bydependency_injector.providers
module, so there is a big chance to find needed provider there. Also it’s possible to add providers to standard library while there is anything not yet covered, but still common.DeclarativeContainers
fromdependency_injector.containers
to group providers, instead of putting provider instances into modules.And, finally, talking about design approach for “xmlboiler” library, I would be doing next things:
Also, I think you might be interested on taking a look on “Movie lister” example:
I’m not sure if it’s super beneficial for your case, but hope it helps.
Victor, I’m closing this question cause it looks like that it’s answered. Please, feel free to reopen it, if needed.