0

Suppose I have a loop (in Python syntax):

xml = "<x>...</x>"
for i in arr:
    j = f(x)  # some complex computation
    obj = Class(i, j)
    xml = obj.run(xml)

Does it make sense to use dependency injection for Class in this situation? If yes, what is the proper way to use DI in this context? Please provide an example.

Maybe I should replace Class with a factory creating this class?

Or should I not use dependency injection in this situation but leave Class(i, j) as is?

12
  • 1
    I see from the real code that the sample is part of a method; this context should be reflected in the sample, as it has consequences based on the injection surface (constructor arguments, setter, method arguments). It leads to one question in particular: is Class reusable?
    – outis
    Commented Nov 24, 2018 at 20:49
  • 1
    I too am confused as to what you mean by "dependency injection" here. obj = Class(i, j) involves injecting the two dependencies, i & j into Class. So you are using dependency injection here. So I'm unclear as to what you are asking.
    – David Arno
    Commented Nov 24, 2018 at 21:02
  • 1
    OK. What is the problem you're trying to solve with the IoC container? Commented Nov 24, 2018 at 21:28
  • 2
    You don't need an IoC container to do that. Commented Nov 24, 2018 at 22:02
  • 1
    IOC containers help by formalizing the separation of construction code and using code by making you write construction code in a different language (xml or whatever). If you and your team are disciplined enough to do that on your own you can avoid having to mention an IOC framework when you advertise for your maintenance coders job. Commented Nov 24, 2018 at 23:44

2 Answers 2

4

Likely, you really don't need any dependency injection here. But if you do, then simply injecting via a function parameter is the simplest way to go in Python. Remember: in Python, all variables incl. class names are resolved at run time, so you can pass class objects around as ordinary variables. For example:

def transform_the_xml(xml, arr, StepClass=DefaultClass):
    for i in arr:
        j = f(x)  # some complex computation
        obj = StepClass(i, j)
        xml = obj.run(xml)

Alternatively, you could “inject” a factory function that creates an object, but that doesn't look differently from the above case (you'd only use a different naming convention for the argument).

Note that an object with a single method is just a complicated way to write a function. We could equivalently write:

def transform_the_xml(xml, arr, step=None):

    if step is None:
        def step(i, j, xml):
            return DefaultClass(i, j).run(xml)

    for i in arr:
        j = f(x)  # some complex computation
        xml = step(i, j, xml)

Then, you can easily inject whatever step implementation you want during unit testing.

1
  • 1
    "Note that an object with a single method is just a complicated way to write a function." Actually that would be a complicated way to write a closure. It only degenerates to a "complicated way to write a function" when it has a single method and it has no state setting constructors. Commented Nov 24, 2018 at 23:02
-2

It definitely makes sense (think unit tests, among other reasons). The counterargument would be exposing the dependency can expose implementation details. Exposure can be mitigated by providing a sensible default (set default field values within constructors, or default arguments to methods/functions, depending on language capabilities; fortunately, with Python you can do either).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.