Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Dependency Injection/IoC

Dependency Injection/IoC

Scheduled Pinned Locked Moved The Lounge
questioncsshelplearning
23 Posts 14 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TNCaver
    wrote on last edited by
    #1

    I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

    If you think 'goto' is evil, try writing an Assembly program without JMP.

    T R S Sander RosselS M 12 Replies Last reply
    0
    • T TNCaver

      I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

      If you think 'goto' is evil, try writing an Assembly program without JMP.

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #2

      With dependency injection, usually the target code depends on an interface, which is usually in a separate library/dll/assembly from the actual implementation. If not, and your target code references a concrete class, then yeah there's no loose coupling.

      #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

      S T 2 Replies Last reply
      0
      • T TNCaver

        I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

        If you think 'goto' is evil, try writing an Assembly program without JMP.

        R Offline
        R Offline
        RickZeeland
        wrote on last edited by
        #3

        I found a nice series of articles that might clarify things: http://tutorials.jenkov.com/dependency-injection/index.html[^] :-\

        1 Reply Last reply
        0
        • T TNCaver

          I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

          If you think 'goto' is evil, try writing an Assembly program without JMP.

          S Offline
          S Offline
          Slacker007
          wrote on last edited by
          #4

          Interfaces. The implementation is loosely coupled, not the interface. Edit: believe or not, I actually learned a lot about DI via this product: Ninject - Open source dependency injector for .NET[^] Play around with it, use it, and learn from the docs and making mistakes. You will be a DI god in no time. Actually, any good DI product will work, I prefer the one listed for most stuff.

          1 Reply Last reply
          0
          • T TheGreatAndPowerfulOz

            With dependency injection, usually the target code depends on an interface, which is usually in a separate library/dll/assembly from the actual implementation. If not, and your target code references a concrete class, then yeah there's no loose coupling.

            #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

            S Offline
            S Offline
            Slacker007
            wrote on last edited by
            #5

            Exactly. :thumbsup:

            1 Reply Last reply
            0
            • T TNCaver

              I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

              If you think 'goto' is evil, try writing an Assembly program without JMP.

              M Offline
              M Offline
              Marco Bertschi
              wrote on last edited by
              #6

              In my experience, DI as a concept is valuable especially for testing - For example, if you inject your external dependencies you may write unit tests for a given purpose without having to care to setup anything beside the stiff within your test scope. This is especially valueable if you are, for example, accessing a config heavy API, or internal service. With proper DI in place you can mock the test scope to stay within boundaries within seconds. (of course this does not replace proper integration testing, but it gives you a fair chance to validate changes on your side of the code).

              I only have a signature in order to let @DalekDave follow my posts.

              S T 2 Replies Last reply
              0
              • T TNCaver

                I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                If you think 'goto' is evil, try writing an Assembly program without JMP.

                Sander RosselS Offline
                Sander RosselS Offline
                Sander Rossel
                wrote on last edited by
                #7

                An example says more than a thousand words... Let's say you have some class that connects to a database. This class is used by another class that does some business logic with data from a database and uses your database class.

                public class DatabaseClass
                {
                public List GetCustomers()
                {
                // Get customers...
                }
                }

                public class BusinessLogicClass
                {
                public int GetCustomerCount()
                {
                var db = new DatabaseClass();
                var customers = db.GetCustomers();
                // Use customers...
                }
                }

                Now there is no way to unit test GetCustomerCount because you always need your database because there is a tight coupling with DatabaseClass which directly goes to the database. So instead of using new DatabaseClass we can "inject" an interface instead.

                public interface IDatabaseClass
                {
                List GetCustomers();
                }

                public class DatabaseClass : IDatabaseClass
                {
                public List GetCustomers()
                {
                // Get customers...
                }
                }

                public class BusinessLogicClass
                {
                private readonly IDatabaseClass db;

                public BusinessLogicClass(IDatabaseClass db)
                {
                this.db = db;
                }

                public int GetCustomerCount()
                {
                var customers = db.GetCustomers();
                // Use customers...
                }
                }

                Now, we can use the BusinessLogicClass with the DatabaseClass or with some mock object for testing purposes.

                // Production code.
                var bl = new BusinessLogicClass(new DatabaseClass());
                var count = bl.GetCustomerCount();
                // Do something with count.

                // Testing code.
                var bl = new BusinessLogicClass(new MyMockObject()); // Use a mocking framework instead!
                var count = bl.GetCustomerCount();
                // We know our mock object returns 5, but with an actual database we couldn't say.
                Assert.Equals(5, count);

                Now that's a lot better, our business logic does not depend on the DatabaseClass, and by extension the actual database, anymore. However, using new DatabaseClass() everywhere in your code isn't ideal either. You may want to switch database systems at some point or whatever. So that's where a DI framework comes in. It let's your register your concrete types for any interface and that type gets injected. To switch implementations you'll only need to change your registration. How registration is done depends on the framework you use. For example, Unity can do registration by convention (DatabaseClass is injected for IDatabaseClass) or it just injects the first (or only?) class it finds

                1 Reply Last reply
                0
                • M Marco Bertschi

                  In my experience, DI as a concept is valuable especially for testing - For example, if you inject your external dependencies you may write unit tests for a given purpose without having to care to setup anything beside the stiff within your test scope. This is especially valueable if you are, for example, accessing a config heavy API, or internal service. With proper DI in place you can mock the test scope to stay within boundaries within seconds. (of course this does not replace proper integration testing, but it gives you a fair chance to validate changes on your side of the code).

                  I only have a signature in order to let @DalekDave follow my posts.

                  S Offline
                  S Offline
                  Slacker007
                  wrote on last edited by
                  #8

                  Our shop uses the same website for different clients. We use DI for custom logic and UI stuff, that is client specific. Absolutely a work of art. DI is so powerful, yet so simple, really. Edit: that is using DI for non-testing functionality. Of course, testing is benefited as well. :thumbsup:

                  1 Reply Last reply
                  0
                  • T TNCaver

                    I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                    If you think 'goto' is evil, try writing an Assembly program without JMP.

                    M Offline
                    M Offline
                    Marc Clifton
                    wrote on last edited by
                    #9

                    TNCaver wrote:

                    code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword?

                    Imagine a door. On that door is a knocker. Imagine another door. On the side of that door is a doorbell. Imagine an interface. The interface has one method: "Announce" -- Announce someone is waiting at the door." Now go knock on the door or ring the doorbell. They both implement "Announce". I think I'll stop now about injecting knockers.

                    TNCaver wrote:

                    I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue.

                    It does, if you don't abuse it. And boy, have I seen abuse. However, I avoid DI like the plague because it flips the problem on its head. Most DI's that I've seen basically express in metadata (XML, JSON, whatever): Property-of-instance-Foo-gets-initialized-with-interface-Eye. And worse, some of those DI's will instantiate Foo for you if it doesn't exist at the point in time of the injection. Massive entanglement of dependencies ensues -- what if the instance of Foo is itself a dependency? Now, you also have another choice. Foo itself can implement an interface that defines the property (of some interface type) that the DI is told about and can set. That's pretty quick. Otherwise, the DI has to rely on reflection to set the property of Foo, because it doesn't know what type it is and has no interface to map Foo's property to a "known" interface. Reflection is slow. Now magnify that problem with hundreds, if not thousands, of entangled dependencies, all specified in some XML file (yes, I've actually seen this) and you get a nightmare that is impossible to debug, slow to instantiate, and brittle to changes. I'm old fashioned. Give me a factory pattern. DI is a bad solution looking for an already solved problem.

                    Latest Article - A Concise Overview of Threads Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny Artificial intelligence is the only remedy for natural stupidity. - CDP

                    S 1 Reply Last reply
                    0
                    • M Marc Clifton

                      TNCaver wrote:

                      code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword?

                      Imagine a door. On that door is a knocker. Imagine another door. On the side of that door is a doorbell. Imagine an interface. The interface has one method: "Announce" -- Announce someone is waiting at the door." Now go knock on the door or ring the doorbell. They both implement "Announce". I think I'll stop now about injecting knockers.

                      TNCaver wrote:

                      I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue.

                      It does, if you don't abuse it. And boy, have I seen abuse. However, I avoid DI like the plague because it flips the problem on its head. Most DI's that I've seen basically express in metadata (XML, JSON, whatever): Property-of-instance-Foo-gets-initialized-with-interface-Eye. And worse, some of those DI's will instantiate Foo for you if it doesn't exist at the point in time of the injection. Massive entanglement of dependencies ensues -- what if the instance of Foo is itself a dependency? Now, you also have another choice. Foo itself can implement an interface that defines the property (of some interface type) that the DI is told about and can set. That's pretty quick. Otherwise, the DI has to rely on reflection to set the property of Foo, because it doesn't know what type it is and has no interface to map Foo's property to a "known" interface. Reflection is slow. Now magnify that problem with hundreds, if not thousands, of entangled dependencies, all specified in some XML file (yes, I've actually seen this) and you get a nightmare that is impossible to debug, slow to instantiate, and brittle to changes. I'm old fashioned. Give me a factory pattern. DI is a bad solution looking for an already solved problem.

                      Latest Article - A Concise Overview of Threads Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny Artificial intelligence is the only remedy for natural stupidity. - CDP

                      S Offline
                      S Offline
                      Slacker007
                      wrote on last edited by
                      #10

                      I think you may have scared him off. I know I would be if I didn't know any better. Just saying...

                      M T 2 Replies Last reply
                      0
                      • T TNCaver

                        I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                        If you think 'goto' is evil, try writing an Assembly program without JMP.

                        J Offline
                        J Offline
                        Jon McKee
                        wrote on last edited by
                        #11

                        DI is a very useful tool as many others have already pointed out. But it's just that, a tool. Don't fall into the "everything looks like a nail because I just learned how to use a hammer" trap. Also don't confuse DI the concept with DI frameworks. DI frameworks are not required to implement the concept of DI. The frameworks are for a very specific situation (very complex DI "webs") and are grossly overused. All you're doing is offloading coupling to external code you have no control over and incorporating extra dependencies into your software. Make sure that trade-off is worth it. So consider the details of the situation. In the case of a database class, even if your software only uses a single database now, there are multiple kinds that may be supported in the future. So an interface would be the way to go. Since we're using an interface anyways, why couple a class that uses the database class with a concrete derivative of that interface? DI is the way to go here... maybe. You also need to consider how your software is going to be used. Is it an application, framework, library, service, etc? If the end-user isn't using the class directly and you want to keep things as loosely coupled as possible internally, you may not have an issue with needing to type something like new Something(new MssqlDb(new AccessInfo()), new RegionFormatter(someRegion), ...more stuff). If the end-user is going to be using this class directly, they'll probably appreciate some default new Something() which is going to require coupling to concrete classes in that constructor. Consider how ugly and bloated code would look if, say, .NET removed all but the most complex constructors for their entire framework just to be "less coupled." I guess what it boils down to is that whether it's useful depends on the specifics. Use common sense, use experience, and use others' advice. There is no perfect solution to every problem; it's often a cost-benefit analysis. EDIT: Also as Marc above pointed out, sometimes the factory pattern is the best solution. I tend to think of this as a form of DI except instead of needing a concrete class passed in, you need information that can be used to generate that concrete class. In both cases, the class using the interface isn't coupled to the concrete class.

                        1 Reply Last reply
                        0
                        • T TNCaver

                          I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                          If you think 'goto' is evil, try writing an Assembly program without JMP.

                          M Offline
                          M Offline
                          Matthew Dennis
                          wrote on last edited by
                          #12

                          Where the coupling is reduced is the dependencies of the interfaces/classes that are being injected. If your class needs a IWidgetService to run, you don't have to know that the implementation IWidgetService requires an instance of the WonderfulApiClient class, a WhatchamacallitRepository, and a AppConfiguration object, or any or their dependencies. You don't have to worry about the construction. Furthermore, if the implementation of IWidgetService changes to require different dependencies, your code that uses the IWidgetService doesn't have to change, unless you've changed the API for the IWidgetService. This keeps minor changes in your code from requiring a cascading set of changes to the users of your classes.

                          "Time flies like an arrow. Fruit flies like a banana."

                          1 Reply Last reply
                          0
                          • T TNCaver

                            I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                            If you think 'goto' is evil, try writing an Assembly program without JMP.

                            G Offline
                            G Offline
                            GuyThiebaut
                            wrote on last edited by
                            #13

                            I think that's a good question and you do have something of a good point regarding loose coupling. However no matter how loosely coupled you want the code to be, at some point there needs to be some agreement between the calling code and the called code as to which methods/functions are called and are available. That's where interfaces come in - all they do is define the available operations and not the actual implementation. That then means that as long as your external library implements what is specified by the interface you can then use that library. There is always going to be some form of coupling in code - it's just that it's generally better to aim for less dependency between different areas of code.

                            “That which can be asserted without evidence, can be dismissed without evidence.”

                            ― Christopher Hitchens

                            1 Reply Last reply
                            0
                            • S Slacker007

                              I think you may have scared him off. I know I would be if I didn't know any better. Just saying...

                              M Offline
                              M Offline
                              Marc Clifton
                              wrote on last edited by
                              #14

                              Slacker007 wrote:

                              I think you may have scared him off. I know I would be if I didn't know any better. Just saying...

                              That was the idea. :-D

                              Latest Article - A Concise Overview of Threads Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny Artificial intelligence is the only remedy for natural stupidity. - CDP1802

                              T 1 Reply Last reply
                              0
                              • T TheGreatAndPowerfulOz

                                With dependency injection, usually the target code depends on an interface, which is usually in a separate library/dll/assembly from the actual implementation. If not, and your target code references a concrete class, then yeah there's no loose coupling.

                                #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                                T Offline
                                T Offline
                                TNCaver
                                wrote on last edited by
                                #15

                                Seems to me that regardless of whether you're using an interface or concrete object, you still need to know what's available in the object so you can write the code that uses it. I think maybe I'm misunderstanding what is meant by loose coupling in this context. And maybe that's the least important advantage of DI anyway.

                                If you think 'goto' is evil, try writing an Assembly program without JMP.

                                K 1 Reply Last reply
                                0
                                • M Marco Bertschi

                                  In my experience, DI as a concept is valuable especially for testing - For example, if you inject your external dependencies you may write unit tests for a given purpose without having to care to setup anything beside the stiff within your test scope. This is especially valueable if you are, for example, accessing a config heavy API, or internal service. With proper DI in place you can mock the test scope to stay within boundaries within seconds. (of course this does not replace proper integration testing, but it gives you a fair chance to validate changes on your side of the code).

                                  I only have a signature in order to let @DalekDave follow my posts.

                                  T Offline
                                  T Offline
                                  TNCaver
                                  wrote on last edited by
                                  #16

                                  I agree, I understand all the other advantages of DI, I think I just misunderstand what loose coupling means in this context.

                                  If you think 'goto' is evil, try writing an Assembly program without JMP.

                                  1 Reply Last reply
                                  0
                                  • M Marc Clifton

                                    Slacker007 wrote:

                                    I think you may have scared him off. I know I would be if I didn't know any better. Just saying...

                                    That was the idea. :-D

                                    Latest Article - A Concise Overview of Threads Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny Artificial intelligence is the only remedy for natural stupidity. - CDP1802

                                    T Offline
                                    T Offline
                                    TNCaver
                                    wrote on last edited by
                                    #17

                                    :laugh:

                                    If you think 'goto' is evil, try writing an Assembly program without JMP.

                                    1 Reply Last reply
                                    0
                                    • S Slacker007

                                      I think you may have scared him off. I know I would be if I didn't know any better. Just saying...

                                      T Offline
                                      T Offline
                                      TNCaver
                                      wrote on last edited by
                                      #18

                                      LOL Nah, but Marc's comment does give me an alternate perspective, which gives me choices.

                                      If you think 'goto' is evil, try writing an Assembly program without JMP.

                                      S 1 Reply Last reply
                                      0
                                      • T TNCaver

                                        I'm learning about DI, and it kind of makes sense, but I'm not convinced it solves the loose coupling issue. So, here's my stupid question of the week: code that uses an external object still has to know about it's properties and methods in order to use them, so how does passing the object or interface to the constructor or a setter make the code any less dependent than using the concrete object with the 'new' keyword? I'm sure I'm missing the point somewhere.

                                        If you think 'goto' is evil, try writing an Assembly program without JMP.

                                        E Offline
                                        E Offline
                                        englebart
                                        wrote on last edited by
                                        #19

                                        Think of the different pieces of your code as "services" for the other parts. If you can imagine module X as a service for module Y, then that is a good place to introduce an X interface that is injected into module Y. Even if you do not use IOC, it is still a cleaner design. I like lazy initialization with IOC concepts. If nothing has been injected when you need it, go ahead and new() the Production service by default.

                                        1 Reply Last reply
                                        0
                                        • T TNCaver

                                          LOL Nah, but Marc's comment does give me an alternate perspective, which gives me choices.

                                          If you think 'goto' is evil, try writing an Assembly program without JMP.

                                          S Offline
                                          S Offline
                                          Slacker007
                                          wrote on last edited by
                                          #20

                                          Yeah, lot's of feedback on this, which is good.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups