Choosing between DI (without container) and Composition

I’m working on a classes that are designed to read a defined file format; said format is comprised of 2 separate files (FileA and FileB). For ease of use, the format is referred to as the FileA format, but a valid “file” must have a FileB. The files share the same path prefix, but alter in suffix; therefore my current classes appears as:

class FileReaderA:
    def __init__(self, path: pathlib.Path):
            self.a = path.with_suffix('.fa')
            self.b = FileReaderB(path)
    # methods related to operating on FileA types

class FileReaderB:
    def __init__(self, path: pathlib.Path):
            self.b = path.with_suffix('.fa')
    # methods related to operating on FileB types 

The classes are separated since FileReaderB does not depend on FileReaderA and can be used independently to read FileB types, however a valid FileA requires its associated FileB. Therefore, composition made sense, at first. Now I’m wondering if DI is the more appropriate solution, but it requires that FileReaderB be explicitly instantiated and passed to the constructor of FileReaderA, which is less than ideal form a user standpoint with this API:

>>> frb = FileReaderB(path)
>>> fra = FileReaderA(path, frb)

Thus I am forced to abstract it by using a factory:

def reader(path: pathlib.Path):
    return FileReaderA(path, FileReaderB(path))


>>> fra = reader(path)

This seems verbose and I feel as though I’m introducing more code and layers of abstraction to achieve the same result, all around the guise for better unit testing of decoupled classes.

What is wrong with just using Composition over enforcing DI?

Go to Source
Author: pasta_sauce