Dependency Injection: a discussion of the pros and cons

In your own words you want to use a solution which is “less complex, less lines of code” and therefore less prone to bugs. The winner in this game is DI. Funny you shut up about that the moment I pointed it out…

I’m still waiting for those examples.

I disagree. A singleton is not restricted to providing an instance of a single class, it can provide instances of any number of classes. I have built a static class which provides single instances, so the use of the term “singleton” is perfectly valid.

If you want to talk about “layers” then you should read my article called http://www.tonymarston.net/php-mysql/infrastructure.html#3tier
All Model classes exist in the Business layer, all Views and Controllers exist in the Presentation layer, and all Data Access Objects exist in the Data Access layer.

“Usually” is not the same as “must be”. There is no rule which states that my controllers MUST be OO classes and not procedural scripts so by using procedural scripts I am not breaking any rules.

Tony, code examples. Forget everything else until you can provide a working code example.

You obviously do not understand how a layered architecture, such as the 3-Tier architecture, actually works, or what the term “dependency” actually means. Where a module requires to call a second module in order to carry out its functionality, the first module is dependent on the second module. There is a dependency from the first module to the second module, but not from the second module to the first.

The 3-Tier architecture has three layers - the Presentation, Business and Data Access layers - as shown in the following diagram:

diagram of the 3-Tier Arcitecture

A component in the Presentation layer calls a component in the Business layer, so the Presentation layer is dependent on the Business layer.

A component in the Business layer calls a component in the Data Access layer, so the Business layer is dependent on the Data Access layer.

If there were no dependencies between the various layers then the layered application simply would not work

Tony. If you can’t decouple your code enough to provide a simple example this just proves once and for all that your implementation is flawed, inflexible and impossible to reuse.

??? Who said there was?! I just want a minimal code example where you are using an approach other than DI so I can analyse it and compare the pros/cons of it with DI.

You can’t even decouple the concept from your codebase let alone some actual code!

I don’t understand this topic or why it has 145 replies. It’s like 1 guy against everyone else. Because it’s almost like arguing fixed length variables are better.

01 something PIC 9(9)

vs

int something;

Nope.

1 Like

Excuse me, but when someone says “your code is in need of some serious refactoring” it is the same as saying “your code is crap”.

I never said that a singleton is always better than DI. Where I can make use of the facilities offered by DI then I actually use DI. Where I do not have the need for those facilities then I do not use DI, I use in situ instantiation using hard-code names, usually via a singleton.

Using DI when you can take advantage of the facilities offered by DI is a good idea. Using DI when you will never use those facilities is not such a good idea. If you spend time in refactoring your code in order to provide a facility that you know you will never use, then you are in serious violation of the YAGNI principle.

I have already said many times that I am never going to use DI to inject dependencies into my Model classes for the simple reason that I will never have a need to change any of those dependencies.

If I ever need a separate instance instead of a single then I would use new $class instead of getInstance($class).

Simple. Each class has an sqlSelectInit() method which is automatically called by the singleton in order to initialise all the existing object properties so that a “clean” copy is always returned.

Which (without seeing the code) sounds a lot like a hacky workaround for not being able to instantiate multiple objects.

1 Like

Not really. I take that as there is room for improvement or someone may have a potentially better idea on how to accomplish what I did. I hardly consider that “your code is crap”.

And here lies the rub. I even mentioned this in the post you are quoting. This is conceptual thinking! I don’t care if you won’t implement it. Conceptually, what are the merits/flaws with @TomB’s approach? Regardless of whether you choose to implement any changes or not is (as you like to say) irrelevant.

We are conceptually looking at the two methodologies and trying to identify the merits/flaws in each. I don’t give a damn about your framework and what if any changes you choose to make to it. I simply care about the conceptual idea between the two different processes taken and how one may choose to go with idea 1 versus idea 2.

If you can’t engage in this discussion on a conceptual level, then please step out so the rest of us can. We aren’t trying to bend your arm and force you to change your code. We are simply trying to engage in the idea of two different techniques and how one would determine the best use for either technique when developing their application.

2 Likes

Incorrect. It is you who keeps saying that DI should be used to handle ALL dependencies and me who argues in favour of “only those dependencies which need the facilities that DI provides”. I use DI in those places where I can see the benefits, and I don’t use DI in those places where I don’t.

And I pointed out that I could not use your method as it would replace some highly reusable loosely coupled code with a huge amount of unreusable tightly coupled code.

I have provided in a previous post code samples which show where I use DI, and explained why I use DI in those samples.
I have provided in a previous post a code sample which shows where I use a singleton instead of DI, and explained why I do not use DI in that sample.
I suggest you look back in this thread to find those posts as I am not going to repeat them.

If you’re not using DI you’re using somethig else and you chose that for a reason, I’d hope because you thought it was the best tool for the job.

And I showed you that you could…

All your code examples are highly coupled to components inside your framework and use extra code that is irrelevant the topic at hand. They also miss important features needed to run the code and important details. You drip-fed them when pushed but have never provided a working, minimalist example that we can use as a demonstration of the concept.

I’ve been asking for a minimal working example that demonstrates your implementation for the last 50+ posts. Why is this so difficult to provide?!

I have to agree with this. Which is where the post you quoted from me began. Now seeing @TomB’s implementation and the one you created (again, I don’t care that you won’t change it – that is your decision to make). Let’s discuss the merits/flaws between the two approaches and how a developer would determine which approach they would take.

I attempted that with my post

So let’s start there. What lead you to the decision? Why is @TomB’s example flawed? etc.

It is obvious that I have invented a new variety. This is called “thinking outside the box” or “stretching the envelope”. If you look at the concept of DI instead of a particular implementation you should see that where a module consumes another module (giving us a “consumer” and a “dependent”), the critical detail is the identity of the dependent module, not where it is instantiated. So by injecting a different name for the dependent module into the consumer the end result is still that a different module is instantiated and used in the consumer. In my opinion it is the result that counts, not the means by which that result was obtained.

No. Your method would totally destroy any reusability that I current have in my controllers and require the refactoring of 2,500 scripts FOR ABSOLUTELY ZERO BENEFIT. That is why it is not going to happen.

CODE EXAMPLES

Tony. If you’re argument is that you don’t want to rewrite 2500 files, that is FAIR ENOUGH. But we are talking about the concepts at play here. Again you seem unable to differentiate between a concept and your bulbous codebase.

I have already shown you that your DI solution which supposedly uses less lines of code is totally unworkable, yet you fail to understand that.

I have already shown you that your DI solution which supposedly uses less lines of code is totally unworkable, yet you fail to understand that.

You said, effectively that “But then I would have to rewite 2500 files” . This is not an argument against the concepts I was demonstrating. Please realise the distinction!

Let’s makes this dead simple then, shall we?

@tony_marston404, if you were to “conceptually” alter your 2500 files to use the DI implementation @TomB previously described, what issues would you run into?

Ignore the fact that your code would churn out the same data it does today, so there isn’t any “real user demonstration of changes”.

Ignore the fact that it requires 2,500 files to be changed – in fact, pretend I altered the 2500 files for you for free (if that helps).

1 Like

No. If I ant to create multiple objects instead of a singleton then I would use new $class instead of singleton::getInstance($class)

I’ll just leave this here…

1 Like