Кто не знает, что такое service locator (IoC, ServiceManager) — пусть идет и узнает.
У остальных, надеюсь, следующие рассуждения вызовуд согласие и одобрение.
Когда используешь IoС, постепенно он замусоревается всякой чепухой. Староверы, конечно, скажут, что его нужно использовать только для глобальных сервисов типа логгера. Однако, использовать IoC удобно и для локальных нужд, поэтому староверы идут лесом.
Те, кто хоть раз в жизни видел Smart Client Software Factory, знает, что в ней существует иерархия WorkItem'ов — это такие рабочие лошадки, на которых висит логика работы приложения. У каждого воркайтема там доступен сервис локатор, в который можно добавить свой или взять напосматреть чужой сервис. Фишка в том, что если сервис не найден в локальном сервис локаторе, он ищется в сервис локаторе родительского воркайтема.
Соответственно, в каждом воркайтеме можно а) зарегистрировать новый сервис, который будет виден только для себя и для дочерних объектов; и б) перерегистрировать (owerwrite) существующий сервис, представленный выше по иерархии.
Круты перцы все время используют эти шняги чтобы сделать логику приложения гибкой.
Также, круты перцы не понимают, почему аналогичной функциональности нету не в рамках SCSF.
Внимание, код:
1: class SubClass
2: {
3: public void Test()
4: {
5: Console.WriteLine(this.GetService<string>());
6: }
7: public void RegisterService()
8: {
9: this.AddService<string>("2");
10: }
11: }
12:
13: class Program
14: {
15: static void Main(string[] args)
16: {
17: new Program().Main();
18: }
19:
20: void Main()
21: {
22: this.AddService("1");
23:
24: Console.WriteLine(this.GetService<string>());
25:
26: SubClass child = new SubClass();
27:
28: this.AddChildWorkItem(child);
29:
30: child.Test();
31:
32: child.RegisterService();
33:
34: child.Test();
35:
36: Console.ReadLine();
37: }
38: }
Выводится следующее:
Итак, мы взяли объект Program, зарегистрировали глобальный сервис типа string (22). Попробовали — работает (24).
Дальше, мы добавили дочерний объект, у которого уже свой сервис локатор (28). Попробовали — показался родительский сервис (30).
И вот то, ради чего весь сыр-бор: перерегистрируем сервис и пробуем. Выводится «2», сработал уже локальный сервис(32).
Как работает? Методы на себе можно вызывать с помощью наших любимых экстеншнов.
1: public static TService GetService<TService>(this object owner)
2: {
3: return IoC.Instance.GetService<TService>(owner);
4: }
За счет этого, IoC получает доступ к объекту, вызывающему метод. Дальше все просто — внутри IoC строится и поддерживается иерархия.
Подробности - в коде.
Если кому-то хочется, чтобы я еще про что-то рассказал — добро пожаловать в каменты.