kodemore / kink

Dependency injection container made for Python
MIT License
397 stars 25 forks source link

Missing example of using inject as a function on 3rd party code #29

Open skewty opened 2 years ago

skewty commented 2 years ago

It is likely not obvious to many developers that kink's inject decorator function can be used as a regular function (not as a decorator) to make 3rd party classes injectable without needing to modify the 3rd party code at all.

I wrote this bit of code to demonstrate how to do it:

from kink import di, inject

class Some3rdPartyClass:  # notice how the 3rd party class code does not need to be modified
    def __init__(self, captains_name: str) -> None:
        self.value = captains_name

def approach(num: int):
    if num == 1:
        # each injection request for Some3rdPartyClass will get the same instance (singleton)
        inject(Some3rdPartyClass)  # registers this class as injectable and takes care of its parameters
        di["captains_name"] = "Cpt. Obvious"
    elif num == 2:
        # each injection request for Some3rdPartyClass will get the same instance (singleton)
        di["captains_name"] = "Cpt. Obvious"
        di[Some3rdPartyClass] = Some3rdPartyClass(di["captains_name"])
    elif num == 3:
        # each injection request for Some3rdPartyClass will get a different instance
        di.factories[Some3rdPartyClass] = lambda dic: Some3rdPartyClass(dic["captains_name"])
        di["captains_name"] = "Cpt. Obvious"
    else:
        raise ValueError("invalid selection")

approach(3)
print(di[Some3rdPartyClass].value)

Perhaps something like this could be included in the docs to help others recognise this possibility as well.

dkraczkowski commented 1 year ago

@skewty Thanks for pointing this out. I will happily accept any PR :). Please let me know if you would like to create one. If not, I will update the documentation by myself.

To my defence, my assumption was it is clear, but I think you are right - I should explicitly mention this in the documentation.