Hey -- Dependency Injection in Delphi is available in digital form at:


Hey -- Dependency Injection in Delphi is available in digital form at:

https://leanpub.com/dependencyinjectionindelphi

Thanks to all who have already purchased and to those of you that will.

And a big huge shout-out to Stefan Glienke who did the tech review. The book is about ten times better because of his expertise. Thank you, Stefan.

Comments

  1. Nick Hodges​ I think the link is broken. Gives not found and search also gets me zip.

    Could you please investigate?

    Many thanks!!

    ReplyDelete
  2. Gustavo -- thanks for letting me know. The link should be fixed.

    ReplyDelete
  3. I should add that print copies will be available in a couple of weeks.

    ReplyDelete
  4. Nick Hodges Yeap, indeed it is. Cheers!!

    ReplyDelete
  5. I'm just sad that this month the budget is busted. I would really like to get it on Kindle 😕

    ReplyDelete
  6. AFAIK the table of contents mentions Spring. Also samples at Nick's repos here bitbucket.org - NickHodges / NickDemoCode
    / source / DependencyInjection
    — Bitbucket
    shows the use of the Spring4D container

    ReplyDelete
  7. Agustin Ortu In ToC I don't see about Spring

    ReplyDelete
  8. How many containers for Delphi are there? Btw I cannot imagine a world where Nick would recommend another container 😊

    ReplyDelete
  9. Attila Kovacs No bundle yet, but that is coming.

    And I'm glad you like the colors -- my wife picked them. :-)

    ReplyDelete
  10. Looks like the mORMot has some DI features, are they complete? If yes, would Nick Hodges include it in the book? :)

    ReplyDelete
  11. I am not sure if you can use the DI capabilities in mORMot just as DI container.

    I know there are at least two other containers but both are either deprecated and not being developed or just a prototype. For reference:
    https://github.com/coco1979ka/Ambrosia was being developed for EKON by Christian Metzler a few years ago. I think its architecture was very close to Castle Windsor DI container from .NET.
    The other would be emballo which did not have any development for years: https://bitbucket.org/magnomp/emballo at the time it had some nice interception capabilities though.

    I think there are several other more simple DI containers out there - in fact you can write a basic DI container in like 200 lines of code in Delphi which already does the basics (proof: https://bitbucket.org/snippets/sglienke/7r8bX)

    ReplyDelete
  12. I've bought it yesterday, just finished the chapter on connascence. Very good so far, thank you for writing it.

    ReplyDelete
  13. Stefan Glienke 200 lines + Spring RTL, Collections and Reflection 😉

    ReplyDelete
  14. I much prefer printed materials for programming topics, so I'll wait for the print edition. (It would be nice to get the eBook with the print edition for a few bucks more, tho.)

    Somewhat off-topic ... I haven't encountered the term "connascence" before, so I googled it and looked at the Wikipedia entry. Very interesting.

    I've been reflecting on some code I've been maintaining lately. There's something about how this code is written gives it what I'd call a very LOW signal-to-noise ratio -- ie., there's a very HIGH level of "noise" in the code, making it quite hard to read and follow.

    I started thinking back to the 70's when Pascal was being introduced and spreading like wildfire, and one of the main benefits at the time was how "readable" code written in Pascal supposedly was. I never particularly bought that argument as an attribute of the language per se (although the main competitors back then were BASIC, FORTRAN, and COBOL) but people did seem to go out of their way at the time to write code that WAS particularly easy to read and understand.

    (You can do the same in C/C++, for instance, but people seem to prefer using shorter, more cryptic names and expressions in that family of languages for whatever reason. Although newer versions of C++ seem to have an increasing number of attributes required throughout the code to tell the compiler how to interpret certain types of expressions.)

    Now we've got code that has lines that assign a value from one SQL result field to a parameter in another SQL query that are nearly 150 characters wide just to say, "query1.field3 = query2.field3", just not that eloquently. A half-dozen of such lines with line-wrapping, surrounded by try-except blocks, repeated several times throughout one method, with numerous such methods, makes the code extremely hard to read, understand, and modify.

    And in this particular code, I'm finding a lot of duplicate code blocks within different if..then conditionals, telling me the people who wrote it were more comfortable duplicating large noisy code blocks than trying to ensure the conditions around the duplicated code were correct.

    It's not due to connascence, and not even coupling. Nor is it particularly bad design on the part of any specific authors. It's just the result of many cumulative design choices that ultimately result in code that's extremely verbose, hard to read, with a lot of ... noise that cannot really be suppressed.

    I've found that the use of DI practices (not DI containers) on several levels can potentially serve to clean things up a bit, which is nice. (It doesn't help when people who are allergic to 'with' clauses chime in about how "bad" it is to use them to reduce noise as well.)

    But it's worrisome that there's such a propensity to choose simple, straight-ahead inline code using lengthy, convoluted code expressions that lead inevitably to horribly noisy conditions, as opposed to spending a little time crafting more readable code in a language that was originally praised for its ability to write highly readable code.

    I haven't seen this book yet, but the earlier DI books I've seen spend little if any time addressing this beneficial aspect of DI, probably because it's about the most mundane aspect of DI imaginable. It's a "How to use DI to make your regular code more readable" kind of topic, and there are actually lots of opportunities to leverage it within typical Delphi form-based units, especially when DBs are involved.

    ReplyDelete
  15. Agustin Ortu I think this is only fair, a container with similar features can be written in .NET in approx 100 lines. Most of Spring4D RTL is to close the gap in some areas that you have with the Delphi RTL compared to the .NET runtime

    ReplyDelete
  16. Stefan Glienke I know, my comment wasn't really serious ;).

    Now seriously, if I want to use a DI Container in Delphi, I'd always use Spring4D container over my hand-crafted one

    ReplyDelete
  17. David Schwartz Practicing DI is one of many consequences when aiming for good (readable, maintainable, testable) code and it requires a good understanding of code architecture and design patterns.

    Personally I don't think that pascal is any more readable than any of the other big OO languages out there. It all stands and falls with what code you write in that language. Personally the more I know about other languages the less I like some things that many people claim makes Delphi such a structured and good language. And in fact some are just historical artifacts of technical limitations that died long ago.

    Something I learned over the years is that some software developers think they are super smart and they need to make everyone else feel that when reading their code and give them a hard time understanding whatever the author was doing and then thinking that he is awesome while in reality he was just making the easiest things so complicated and convoluted. And yes, sometimes I read code from past me and realize I did that as well. And that is why constant code review and refactoring is necessary when a code base growths over the years.

    Also verbosity <> expressiveness. Abbreviating your method and variable names is not making the code better but avoiding ceremony does. People in functional programming understood that quite well and better than others.

    ReplyDelete
  18. Stefan Glienke I agree 100%. I guess my point was that since I started learning about DI, it gives me a framework or context of sorts within which to think about how to make code more readable. It impacts my choices of how to create small local methods to simplify various kinds of expressions, and guides me in terms of the level of detail I choose to define as the parameters I pass. I also find myself tending to try to keep this fairly consistent throughout the unit, even to the point of implementing some more global refactors to support consistent localized refactors (if this makes sense).

    Said another way, I don't think simply about hoisting a variable up into the class as a global of sorts; but rather I think of it as a refactor based on DI that has an impact on the entire class / unit.

    It's hard to explain, but it has had an impact on how I both design and refactor code that makes it more readable (for me, anyway).

    ReplyDelete
  19. The thing is that DI makes you think and write code in such a way that is more easy to deal off with, in any aspect (simplicity, testability, readability, maintainability, extensability, ...).

    I'm also now experiencing that somehow implementations are easier as well. I'm not sure if its "I'm a little better than before" or a side effect of DI (or maybe both)

    It can go even more simpler: You think that "program to an interface, not an implementation" is cool? Well, DI helps you achieve that

    ReplyDelete
  20. To me, I guess DI constitutes a bunch of relatively simple design patterns (as opposed to larger, more complex patterns). I'm a lot more conscious about how I set up ALL of my interfaces, not just "interface" types. I mean, when I design objects, what kind of injection do I choose to initialize the object? There are people who consider this some kind of "stylistic" choice, which is silly. Are there just a couple of data items needed, or a bunch? Are they all available when the object is being created, or mostly afterwards, or spread out in time? Sometimes this leads to splitting up parts of the object based on temporal coherency of initialization data.

    I no longer look at simply "passing parameters" to methods, but "injecting values" into an object that are needed to establish an initial state or make it work properly.

    At what point do I stop enumerating parameters in a constructor call or adding properties to assign after creation, and replace the interface with a new or existing object (or record) that contains the values I need to pass?

    These are all things I'm far more cognizant of now than I was before.

    ReplyDelete
  21. Looking forward to the printed copy Nick Hodges congrats.

    ReplyDelete

Post a Comment