Я нахожусь в подобной ситуации, и у меня есть то, что я считаю хорошей реализацией с соответствующими абстракциями. Является ли мое решение наилучшей практикой или нет, я не могу этого гарантировать, но оно довольно легкое. Вот как у меня это устроено:
Мой уровень пользовательского интерфейса должен выполнять вызовы в мою службу REST, поэтому я создал абстракцию под названием ServiceManagers.Interfaces.IAccountManager. Интерфейс имеет методы, называемые GetAccounts (Int64 userId).
Затем я создал Rest.AccountManager, который реализовал этот интерфейс, и внедрил его в свой AccountController. Rest.AccountManager - это то, что охватывает специфику REST (URL, get / post / put ..., параметры и т. Д.).
Итак, теперь мой код пользовательского интерфейса должен вызывать только accountManager.GetAccounts (userId). Вы можете создать всеобъемлющий интерфейс, чтобы у вас был только Get, но я чувствую, что он менее выразителен. Можно использовать много разных интерфейсов для каждого компонента (например, PersonManager, HouseManager, AutoManager), поскольку каждый из них представляет собой отдельную задачу, возвращающую разные данные. Не бойтесь иметь много интерфейсов и классов, если ваши имена выразительны.
В моем примере в моем пользовательском интерфейсе имеется отдельный менеджер для каждого контроллера, и выполненные вызовы соответствуют каждому контроллеру (т. Е. GetAccounts for AccountController, GetPeople for PeopleController).
Кроме того, что касается корневых данных конфигурации, вы можете просто использовать класс configurationCreationFactory или что-то еще. Таким образом, все реализации имеют соответствующую конфигурацию с базовой логикой в одном месте.
Это может быть трудно объяснить, и я знаю, что я не справился идеально, но, надеюсь, это немного поможет. Я постараюсь вернуться и очистить его позже, особенно если вы не поняли мою точку зрения:)