• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.
  • Want to receive the latest contracting news and advice straight to your inbox? Sign up to the ContractorUK newsletter here. Every sign up will also be entered into a draw to WIN £100 Amazon vouchers!

Overarchitected Projects

Collapse
X
  •  
  • Filter
  • Time
  • Show
Clear All
new posts

    #41
    Overarchitected Projects

    Originally posted by firestarter View Post
    Never seen so much hate for DI frameworks. Is there a similar disdain for loose coupling and unit testing as well?
    This isn't LinkedIn BS corner. We tell it as we see it.
    "I can put any old tat in my sig, put quotes around it and attribute to someone of whom I've heard, to make it sound true."
    - Voltaire/Benjamin Franklin/Anne Frank...

    Comment


      #42
      I am working on one now. It is purely a PnL system. Take data out of source systems. Slice and dice.

      You would think they were building a nuclear war simulation.

      Why do banks subscribe to theses white elephants?

      Of course, on the plus side, I can invoice lots. I suppose I shouldn't bite the hand that feeds me swans wings and champagne....

      Comment


        #43
        Originally posted by cojak View Post
        This isn't LinkedIn BS corner. We tell it as we see it.
        I'd be interested to know what the alternative to DI is.

        Would it be new'ing things up on the fly or just making everything static?

        Comment


          #44
          Originally posted by firestarter View Post
          I'd be interested to know what the alternative to DI is.

          Would it be new'ing things up on the fly or just making everything static?
          One alternative, rather than having lots of I*Service implementations and injecting those, is to make extensive use of the command pattern. It's quite testable newing up command instances by providing the means for the developer to intercept where the command is actually executed. You could do this by passing in an ICommandRunner style implementation (DI - oops) or use a static CommandRunner class with say a static delegate property which you can override while testing. A variation could be used for queries also. (To test you just check how the command object has been configured then don't actually execute it, you can write different tests to test the command in isolation).

          Personally don't have too much of a problem with dependency injection but thought I'd present an alternative I use myself which ends up with a very small amount of DI container configuration (or none at all).

          Comment


            #45
            Originally posted by Jaws View Post
            One alternative, rather than having lots of I*Service implementations and injecting those, is to make extensive use of the command pattern. It's quite testable newing up command instances by providing the means for the developer to intercept where the command is actually executed. You could do this by passing in an ICommandRunner style implementation (DI - oops) or use a static CommandRunner class with say a static delegate property which you can override while testing. A variation could be used for queries also. (To test you just check how the command object has been configured then don't actually execute it, you can write different tests to test the command in isolation).

            Personally don't have too much of a problem with dependency injection but thought I'd present an alternative I use myself which ends up with a very small amount of DI container configuration (or none at all).
            Interesting idea but I see a few potential problems:

            -Consumers are still tightly coupled with commands the they rely on

            -Consumers still need to construct each command (including supplying of dependencies). If those dependencies also have dependencies then your code will get messy very quickly

            -If an I*Service would normally expose 2+ methods, then this would presumably be 2+ commands? How would state that would have been encapsulated by said service be encapsulated across multiple commands?

            -Can't easily restrict the number of instances of a particular command

            Comment


              #46
              Originally posted by firestarter View Post
              Interesting idea but I see a few potential problems:
              -Consumers are still tightly coupled with commands the they rely on
              Yes although I can't think where I've ever needed to replace the command with something else. If it became necessary to have that level of flexibility, sure I'd take a different approach - but _only_ when it became necessary. Due to the way the commands are executed elsewhere, things can still be tested easily.

              Originally posted by firestarter View Post
              -Consumers still need to construct each command (including supplying of dependencies). If those dependencies also have dependencies then your code will get messy very quickly
              Actually, the dependencies are supplied by the command runner. The class creating the command will just provide its basic parameters, there is a little bit of logic in the runner to supply dependencies where needed (such as data access components). Typically there will not be many different types of dependencies so this logic is very straight forward. It just depends on how you have set up your application.

              Originally posted by firestarter View Post
              -If an I*Service would normally expose 2+ methods, then this would presumably be 2+ commands? How would state that would have been encapsulated by said service be encapsulated across multiple commands?
              Hm the state is really held in whatever the commands are operating on, so most likely they will have a shared dependency. If you are describing a transaction across multiple calls to your service, then this entire transaction could be either encapsulated within a command or just within the method that is creating these commands depending on the level of reuse required.

              Originally posted by firestarter View Post
              -Can't easily restrict the number of instances of a particular command
              You don't need this with the commands, they are extremely light weight. You don't need to share state or anything like that, they are disposed of as soon as they are executed. The commands are more like delegates but with the benefit that they all follow the same basic interface and can have dependencies injected into them just before they are executed.

              The dependencies might be longer lived and I expect these to be managed by a factory or IoC container but the commands themselves represent tiny bits of logic to perform updates and are not holding onto resources any longer than their execute method takes to run.

              Although I mention dependencies being injected into commands you still end up with a much simpler configuration because you don't have to deal with entity specific services like IUserUpdateService, IUserDeletionService etc, just a few abstractions like ICommand, IDatabase (or data context), IEmailService which are more general.

              It's worked for me on a few projects and they're all easy to maintain looking back. Like with all things though it depends on your requirements. For my own projects it's mostly about keeping the number of layers to a minimum and the number of abstractions per layer to a minimum as well.

              Edit: by the way this isn't something I've come up with myself, it's actually from a series of blog posts by Ayende: h ttps://ayende.com/blog/154209/limit-your-abstractions-refactoring-toward-reduced-abstractions - which I believe is well worth the read if you haven't already.
              Last edited by cojak; 28 February 2016, 19:52. Reason: Removed link

              Comment


                #47
                Originally posted by firestarter View Post
                I'd be interested to know what the alternative to DI is.

                Would it be new'ing things up on the fly or just making everything static?
                The hate hasn't been for DI. It's been for DI frameworks.

                Although I did mention that people take DI unnecessarily far too.

                Comment


                  #48
                  Originally posted by firestarter View Post
                  So ComponentA has a bunch of logic in it, including calling ComponentB.

                  You don't see any value in being able to test ComponentA in isolation?
                  Lets suppose you're doing the TDD thing... if you isolate every class you're throwing away 50% of the value of TDD, as TDD is all about emerging relationships between classes & components.

                  If you have complicated logic in A coupled to complicated logic in B, then most of the time you've got a bad design. If you have complicated logic in A coupled to more trivial logic in B, then testing A & B together with a mocked C is often even better.

                  There is a time and a place, which is the point being made. Getting more benefit from isolating a single class, as opposed to from a small gaggle of cohesive classes operating together is, in my opinion, fairly rare. Hence I'd expect to see things like factories which return pre-assembled components being injected more than I would expect to see every single dependency being wired up in some layer of indirection.

                  Comment


                    #49
                    Originally posted by firestarter View Post
                    Never seen so much hate for DI frameworks. Is there a similar disdain for loose coupling and unit testing as well?
                    No hate from DI frameworks here, but just adds yet another layer of abstraction/indirection to cope with when debugging and troubleshooting. Through in 12 layers, 47 microservices and 12 VM's to processes a record in a database and it kind of starts to wear a bit thin.

                    But who cares, Bob in India can sort it all out soon for $10 an hour.

                    Comment


                      #50
                      Originally posted by Jaws View Post
                      ....
                      Read through some of the blog posts. Sounds like the general idea is to have a BaseCommand which is actually just a big ballbag of mutable dependencies, which are all (hopefully) set prior to execution, with each command implementation able to access any of them.

                      A complete antipattern and a bizarre attempt at avoiding DI. I could only ever see this working for small projects.

                      Comment

                      Working...
                      X