Changes between v3 & v4 of the Bot Framework are often subtle but important. One area is the basic life cycle of a conversation. For example, in v3 the life cycle looks something like this;
The user types in “Hello” and that goes via a Web Controller and onto a default dialog. In this example the dialog replies with, “Welcome”. One thing that immediately looks odd is that the return message from the dialog does NOT go via the calling Web Controller. In this example a Direct Line invocation is made to send the “Welcome” message directly to the user’s client. However, the controller is still waiting, so its ‘activation time’ is still the total time for the response to be constructed. Things also get a little confusing when a specialized dialog is used, e.g. when placing an order. The initial sequence is the same, the root dialog invokes the specialized form dialog and it’s the form dialog that responds with the message to the user, again directly. However, now when the user responds, the root dialog will (almost) invisibly pass on the next user message directly to the active form dialog. This continues until the specialized dialog completes and the stack returns to the root dialogs control.
V4 hides some of this slightly confusing plumbing from us;
V4 hides away the Web Controller, so already the sequence (and code) is easier to follow. In my view, the real change is that now everything is very clearly funneled through the root dialog. Even when the specialized form dialog is active the control still obviously flows through the root. The root dialog does not have to do anything particularly clever for the sequence to work, it merely calls DialogContinue on the context. But now you can add code, breakpoints, etc. in the root and it is clear they will be hit. BTW. if you want to write some type of always-invoked-intercept code then you would use the middleware mechanisms in v4 rather than bloating the root dialog.
So yes it’s a subtle change, but I think it is an improvement.