Dependency Injection: a discussion of the pros and cons

Please supply all of this as an example. You need only supply class names, constructors and relevant methods/properties. However, does this not indicate to you a problem with tight coupling? If everything requires everything else for a simple example surely there is something awry.

Hey Tony, I hate to be the bearer of bad news, but so far no one has used the word “crap” to define your code except you (and @s_molinari when he wrote “Holy Crap!” … but I don’t think that was directed at your code either…)

We understand that you’ve been “bullied” over your code at other places. We are not trying to do that here. We are simply trying to get a better understanding of when a singleton is better than DI. Or really more importantly, the downsides to DI versus its advantages.

Yes, we’ve pasted a few segments of your code, but not to review it, but rather to see if we can interpret why the design decisions were made. Again, consider this a learning experience. A lot of us like to look at what others have done to see what we can gleam from their work in comparison to the practices and works that we have created. It is one of the many ways we enhance our abilities, as someone may have done something we never considered before.

So with that said, @TomB showed a way for your existing logic to handle at least 1 dependency without the use of a singleton pattern. So let’s conceptually talk about the merits of that example.

Does it make sense?
To me it does.

Does it solve the a problem on providing a dependency to an underlying class?
Yes, it does.

What does a singleton provide that the DI implementation doesn’t?
A single instance of the dependency.

Is there a reason why you might not want that?
Yes.

What if you need to ensure all existing properties of the singleton are sufficiently overwritten when a new class needs to use that dependency?
Singletons make that more cumbersome as you’d have to manually overwrite each property, if you add a property, you may have to go and do that in multiple places. Using DI you can be guaranteed a new instance that doesn’t have any remnants of a prior usage hanging around.

If that isn’t a problem, then a singleton still fits the bill (and that very well may be your case, I don’t know, and I really don’t care… as it isn’t about your specific use case, but the concept as a whole that we want to discuss).

1 Like

Actually, this isn’t strictly true. There’s nothing to stop you passing the same instance into multiple constructors:

$dependency = new $dependency_name()
$table = new $table_name($dependency);
$something_else = new something_else($dependency);

This gives you fine-grained control that you don’t get with singletons. You can either choose to use the same instance or pass a new one depending on the circumstance.

1 Like

Right. That is true. You can technically reuse an existing instance in DI as well. :smile:

I don’t think anyone said that. To me, the very intelligent, friendly and very patient people here arguing with you are simply showing you better alternatives. Edit: I say better, because DI is a part of today’s way of programming. If you understand it and can use it, then you leave the door open to a whole sea of readily available work you can use and “inject” yourself. LOL!

[quote=“tony_marston404, post:112, topic:112088”]
I DO use DI in certain places in my framework where it provides benefits that I can see [/quote]

Great, so DI isn’t evil and is useful, and even in some cases, necessary. Glad we could agree on that. :grinning:

Scott

You keep on with the claim that just because DI adds value to a project in some circumstances that it automatically adds value in all circumstances. I dispute this claim. I have shown where I use DI in my application in those places where the benefits are both obvious and measurable, but you keep zeroing in on the one place where I don’t use DI and shout “This is wrong!”.

It is flexible in the places where I deem that it is necessary to be flexible and where the benefits are both obvious and measurable, but in those places where I do not need that flexibility I do not see why I should change my code to allow me to do something that I am never going to do.

I use DI to inject the model and view names into my controllers. I use DI to inject my models into the view. This provides with a high level of reusable code and extremely low coupling. This is supposed to be a “good thing”.

However if any of my models has a dependency I do not use DI as I have absolutely no use for any of the flexibility which it provides. These dependencies are not instantiated outside of the model and injected into the model, they are instantiated within the model with hard-coded names when and only when they need to be used. I do not need to have a facility to switch the names of these dependencies from one class to another as these dependencies don’t ever change. Even if one did, it would be far easier and quicker to amend that dependency in situ than it would be to institute a total DI solution throughout the whole of my application.

Incorrect. What I said was that where I do not need the facility which DI provides - which is the ability to change a dependency from one object to another without having to change the consumer of that dependency - I do not need to implement DI as it would do nothing but complicate the code for zero benefit.

You are the one saying “DI is not the right tool for the job” Until you explain what is a more viable tool, this discussion is dead. You originally stated that DI was more code until I pointed out it isn’t and now you’re evading all my questions.

Tony. Once more: Unless you provide a minimal working code example that we can directly compare DI to, your words are meaningless.

Imagine a drug company telling doctors “We don’t need to use painkillers our new therapy works just as well if not better” then refusing to give any detail, or clinical trial data about the new treatment.

While I agree that where you need the features that DI provides then using DI is a good idea, I will never agree that using DI is a good idea in those places where you do not need those features. I provided a code sample from one of my model classes where I don’t use DI and your immediate reaction was to jump down my throat and tell me that my code was in urgent need of refactoring (or “crap” in other words). My viewpoint on DI is quite simple - where I need the facilities that DI provides then I will use it, but where I don’t need those facilities I will not use it.

Again, you’re making a claim but not backing it up with anything concrete. You drip feed snippets from your framework that don’t give a full picture but don’t give us anything complete or useful. Why isn’t DI useful? What is the alternative? The only way you can answer this is a code example so we can compare the two approaches

The fact that I am using global variables is irrelevant. The fact that I am passing in the names of objects which will be instantiated within the consumer instead of passing in pre-instantiated objects is also irrelevant. This is a mere implementation detail.

If you had a more complete understanding of the concept of DI you would realise that the minimum requirement is that the name of the dependent object should not be hard-coded in the consumer so that this name can be changed without having to change the consumer. That is precisely what I have achieved.

I’m done with this discussion.

So far:

  1. Tony said DI has no benefits

  2. It was pointed out several times that there are many real benefits of DI

  3. Tony said the benefits of DI are not something he uses and he uses singletons because it’s less code and faster execution time

  4. I demonstrated that DI is actually less code and faster

  5. Tony changed his argument saying that it wasn’t possible to use DI in his use-case and finally provided some code

  6. I proved that DI is easy to implement in this use-case.

  7. Tony again changed his argument to now saying he simply doesn’t want to use DI and that " I will never agree that using DI is a good idea in those places where you do not need those features" without ever explaining a reason.

As I said earlier. DI is less code, faster to execute and less complex that your posted alternative. Unless you can provide a complete code example that shows a situation where a singleton is more flexible, less code or otherwise measurably superior there is no point in continuing.

Despite asking on at least 5 occasions, tony has refused point blank to supply a minimal example that demonstrates the point he is making.

Edit-Just pointing from a spectator point of view. Been following this conversation since the beginning.

In context. in comparison to using singletons.

1 Like

Perhaps you could take a look at the wikipedia page for Dependency Injection and point out which variety it is that you believe you’re using?

Are the constant insults (subtle or otherwise) really necessary to get your point across?

I have provided a sample of a transaction script and a controller script to show how one passes control into the other. How those scripts are created should be irrelevant. It is what they do and how they work together which is relevant. You have already tried to tell me how those scripts should be refactored and I have already told you why your ideas do more harm than good.

If you don’t know what a “user transaction” is then how can you possibly build an application which has users? A person uses a computer application because they want to “do something useful”. This “something” is known as a “unit of work” or a “user transaction”. In an application which contains 2,500 options, the mechanism by which you show the user a list of options so he can choose one is called a “menu”.

As for models, views and controllers having nothing to do with DI I have to disagree. DI is all about injecting a dependent component into its consuming component so that the consuming component can be reused with a different dependent component. Rather than using abstract terms such as “consumer” and “dependent” all the time I find it useful to use concrete terms such as “Model” “View” and “Controller”. I assume you are familiar with those terms? Using DI I can inject the names of the model and view components into my controllers so that I can reuse those controllers with any models and any views.

Dependencies can either be hard-coded in the objects which consume them, or they can be defined outside the consuming object and injected into it. I cannot show two code samples which achieve the same thing, one using DI and another not, for the simple reason that DI is supposed to be used to provide a particular facility. I use DI when I need that facility, and where I don’t use DI it is because I don’t need that facility. That is why I use a mixture of injected and non-injected dependencies.

And still no working minimal code examples. How hard can it be? I knocked up several minimal examples throughout this topic. As we’re talking about programming example code is the quickest and easiest way to demonstrate your point.

Why is this such a challenge for you? It’s a very simple request, provide some examples to demonstrate your point.

I have already told you that I am not going to use DI to inject any dependencies into my model because it would require too much work for absolutely zero benefit.

And I already proved to you that it’s less code and a design flaw in your application not a problem with DI.

Tony. Please answer this: Do you understand why I am asking for examples? We are essentially comparing different methodologies here and the only way to do that is to fully understand them with a bare-bones example that is separated from anything unrelated.

In science this is known as a “fair test” by only changing one variable at a time. To analyse the benefits of one method over another we must be able to see both methods producing the same result knowing that nothing else is interfering with the test. We can then analyse how well they performed relative to one another.

Just saying “My method is better” without this due process is arrogant and ultimately pointless.

You keep ignoring the point that I don’t need that level of flexibility in my models so I am not going to waste my time in refactoring my code in order to provide a facility that I will never use.

I did not say “cannot be used” but “pointless” as in the case of dependencies within my model classes I have no use for the facilities which DI provides. So why should I refactor my code to provide a facility that I am never going to use?