reagento / dishka

Cute DI framework with agreeable API and everything you need
https://dishka.readthedocs.io
Apache License 2.0
357 stars 39 forks source link

context-data-dependent providing - to enable passing in different configiration sources #225

Open RonnyPfannschmidt opened 2 weeks ago

RonnyPfannschmidt commented 2 weeks ago

based on whats provided in the context i'd like to choose different implementation paths

FORCE_USERNAME = NewType("FORCE_USERNAME", str)
UserDetails = NewType("UserDetails")

Class UserProvider(Provider):
     forced_username = fromContext(FORCE_USERNAME)

     @provide
     def user_lookup(self) -> UserLookup:
         return UserLookup()

    @provide
    def user_forced(self, username: FORCE_USERNAME, lookup: UserProvider) -> UserDetails:
      return lookup[username]

   user_fromcontext = from_context(UserDetails)

   @provide
   def default_user(self, lookup: UserLookup) -> UserDetails:
      return lookup.default_user

c = makeContainer(UserProvider()):

with c(context={FORCE_USERNAME: "bad" ) as sub:
   sub.get(UserDetails) # look up the specific user

with c(context={UserDetails: UserDetails(...)}) as sub:
   sub.get(UserDetails) # use the provided one

with c() as sub:
  sub.get(UserDetails) # get the default one
Tishka17 commented 2 weeks ago

Relates to #9 but suggests selection based on context contents, not only values