Я лично делаю смесь обоих.
Вот мои условные обозначения:
- Из статического контекста - Расположение службы
- Из контекста экземпляра - Внедрение зависимостей
Я чувствую, что это дает мне правильный баланс тестируемости. Мне немного сложнее настроить тесты для классов, которые используют Service Location, чем для DI, поэтому именно поэтому Service Location оказывается скорее исключением, чем правилом. Однако я последовательн в его использовании, поэтому нетрудно вспомнить, какой тип теста мне нужно написать.
Некоторые высказывают опасение, что DI имеет тенденцию мешать конструкторам. Я не чувствую, что это проблема, но если вы чувствуете так, есть ряд альтернатив, которые используют DI, но избегают параметров конструктора. Вот список методов DI от Ninject:
http://ninject.codeplex.com/wikipage?title=Injection%20Patterns
Вы обнаружите, что большинство контейнеров Inversion of Control имеют те же функции, что и Ninject. Я решил показать Ninject, потому что у них самые лаконичные образцы.
Надеюсь, это полезно.
Редактировать: Для ясности, я использую Unity и Common Service Locator . У меня есть одноэлементный экземпляр моего контейнера Unity для DI, и моя реализация IServiceLocator является просто оболочкой для этого одноэлементного контейнера Unity. Таким образом, мне не нужно делать никаких сопоставлений типов дважды или что-то в этом роде.
Я также не нахожу АОП особенно полезным, кроме отслеживания. Мне нравится ручная регистрация лучше просто для ясности. Я знаю, что большинство каркасов логирования AOP способны на оба, но мне больше не нужно первое (хлеб и масло AOP) большую часть времени. Конечно, это всего лишь личное предпочтение.