DLL следует использовать только в этом контексте, если вы хотите разделить общие функциональные возможности для целей их использования в разных проектах. Если у вас есть только одна программа, для которой вам нужен доступ к функциональности, нет причин выделять ее в библиотеку.
В случае каскадных вызовов вы столкнетесь с большими накладными расходами, чем вызовы из вашего собственного приложения. Это потому, что сборка меняется.
Вот очень грубое представление о том, как выглядит обычный вызов для члена класса:
push 0 ; a parameter
push 1 ; another parameter
push eax ; pointer to the class instance
call Program.SomeMethod ; direct call to the method
Это очень быстро. Когда вы включаете DLL, вы должны выполнить вызов через IAT. Это увеличивает время выполнения. Опять же, это грубое упрощение:
push 0
push 1
push eax
call <Program.IAT_1>
...
Program.IAT_1:
jmp DLL1.SomeCall
...
DLL1.SomeCall:
; more code here
call <DLL1.IAT_1>
...
DLL1.IAT_1:
jmp DLL2.SomeOtherCall
...
DLL2.SomeOtherCall
; actual code here
ret
Поскольку вы вызываете через модули, это вызовет значительные издержки, если вы будете часто вызывать эту функцию.
Существует также множество вопросов, связанных с обслуживанием и развертыванием, которые делают еще более разумным не разделять вещи, когда в этом нет необходимости.
В этом случае единственная причина, по которой вы должны разделить его, - это то, что вы планируете использовать какой-то код в другом приложении. Даже в этом случае вам не нужно больше, чем одна DLL.