То, что вы называете «эвристическим» подходом, - это то, что я называю условностями. Большинство контейнеров IoC позволяют вам переопределить способ разрешения привязок, что означает, что вы можете ввести любое соглашение, которое вы хотите. Нет таких соглашений по умолчанию, о которых я знаю. Скорее, большинство контейнеров ничего не делают по умолчанию; ваша задача - рассказать им, как разрешать типы, либо через файл конфигурации, либо через код.
Пример пользовательского соглашения, которое я нахожу, довольно распространено, что экономит много объявлений: если запрошенный тип является типом интерфейса, начинающимся с «I» и заканчивающимся «Service», то попытайтесь создать и разрешить тип с помощью одно и то же имя, кроме "я". Это автоматически разрешит имена вроде IFooService
до FooService
. Кроме того, вы можете легко внедрить логику для выбора разных сервисов в разных контекстах и управлять временем жизни экземпляров сервисов в общем месте.
Так как вы можете переопределить привязку большинства контейнеров IoC, вы можете также ввести другие способы поведения. Как правило, однако, есть два варианта:
- Настройка во время выполнения (через файлы конфигурации, такие как файлы XML)
- Настройка во время компиляции (либо через декларативный DSL-подобный API, либо через пользовательские соглашения или другую форму пользовательской логики)