I don't follow, is DependencyInterface a proper interface (as in OOP)? If so, then, the code appears more complicated compared to just implementing two classes SocketLogger and FileLogger which implement LoggerInterface (by providing log(...) method) and accept Socket and File in their constructors respectively (at least 1 method each) - 7 concepts so far (if we count the methods, too). You have 2 implementations of DependencyInterface - FileImplementation and SocketImplementation, they must have at least 1 method each, then you have 2 functions logFile and logSocket, 1 FunctionType, 1 global log function - at least 8 concepts, with no immediately clear relation between them (syntax doesn't help us). We are also forced to pass DependencyInterface through all functions explicitly when we could just create a new dependency tree for our request.
If DependencyInterface is a function pointer then it's not clear how it actually retrieves its socket without resorting to casting from void* (unsafe) or using global state (not thread-safe).
In any case generalLogFunction is global state. What if I want to use a different implementation for a different use case? As a client, I can't use this global function anymore => leaking abstraction. In OOP I'd be happy to work with whichever logger was injected into my instance.
What will happen if the current global function is SocketLogger but I pass a file as a DependencyInterface?
What if the log function needs a second dependency? You have to add another argument to doStuff and anywhere where the log function is used.
I see no benefits here, it's more complicated and more code.
>Golang is an popular example with their CTX that they pass all over the place.
You lose static typing with this, because key/values stored in a context have to be cast from interface{} to the target type at runtime and there are no compile-time guarantees the value is present or of appropriate type. Usually contexts are used for cancellation.
>you inject your dependency in the constructor of your class
>Doesn't this change the signature of the class and therefore break the interface?
It doesn't break the interface because interfaces don't have constructors. We do have to change the signature of the concrete class' constructor when dependencies change but method calls are far more common than constructor calls. When we change code due to new requirements we have to change something by definition, what we do is trying to minimize the amount of code which has to be modified. A method call is a more common case than an object construction.