Mercurial > pub > ImplabNet
comparison Implab/ServiceLocator.cs @ 69:48763f3b5db8
service locator refactoring
author | cin |
---|---|
date | Thu, 28 Aug 2014 19:38:39 +0400 |
parents | 9dd6a896a385 |
children | b33832ab0262 |
comparison
equal
deleted
inserted
replaced
68:9dd6a896a385 | 69:48763f3b5db8 |
---|---|
1 using System; | 1 using System; |
2 using System.Collections.Generic; | 2 using System.Collections.Generic; |
3 using System.Linq; | 3 using System.Linq; |
4 using System.Web; | 4 using System.Web; |
5 using System.Diagnostics; | |
5 | 6 |
6 namespace Implab { | 7 namespace Implab { |
7 /// <summary> | 8 /// <summary> |
8 /// Коллекция сервисов, позволяет регистрировать и получать сервисы. | 9 /// Коллекция сервисов, позволяет регистрировать и получать сервисы. |
9 /// </summary> | 10 /// </summary> |
16 public List<Type> associated; // ссылки на текущую запись | 17 public List<Type> associated; // ссылки на текущую запись |
17 public Type origin; // ссылка на оригинальную запись о сервисе | 18 public Type origin; // ссылка на оригинальную запись о сервисе |
18 } | 19 } |
19 | 20 |
20 // словарь существующих сервисов | 21 // словарь существующих сервисов |
21 Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>(); | 22 readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>(); |
22 | 23 |
23 /// <summary> | 24 /// <summary> |
24 /// Получает объект предоставляющий сервис <typeparamref name="T"/>. | 25 /// Получает объект предоставляющий сервис <typeparamref name="T"/>. |
25 /// </summary> | 26 /// </summary> |
26 /// <typeparam name="T">Тип запрашиваемого сервиса</typeparam> | 27 /// <typeparam name="T">Тип запрашиваемого сервиса</typeparam> |
27 /// <returns>Объект, реализующий сервис</returns> | 28 /// <returns>Объект, реализующий сервис</returns> |
28 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception> | 29 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception> |
29 public T GetService<T>() { | 30 public T GetService<T>() { |
30 return (T)GetService(typeof(T)); | 31 object result; |
32 if (TryGetService(typeof(T), out result)) | |
33 return (T)result; | |
34 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T))); | |
31 } | 35 } |
32 | 36 |
33 | 37 |
34 /// <summary> | 38 /// <summary> |
35 /// Пытается получить указанный сервис, в случае, если компонента не предоставляет требуемый сервис | 39 /// Пытается получить указанный сервис, в случае, если компонента не предоставляет требуемый сервис |
37 /// </summary> | 41 /// </summary> |
38 /// <typeparam name="T">Тип требуемого сервиса.</typeparam> | 42 /// <typeparam name="T">Тип требуемого сервиса.</typeparam> |
39 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param> | 43 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param> |
40 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns> | 44 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns> |
41 public bool TryGetService<T>(out T service) { | 45 public bool TryGetService<T>(out T service) { |
42 AssertNotDisposed(); | 46 object result; |
43 | 47 if (TryGetService(typeof(T), out result)) { |
44 var result = GetService(typeof(T), false); | 48 service = (T)result; |
45 if (result == null) { | 49 return true; |
46 service = default(T); | 50 } |
47 return false; | 51 service = default(T); |
48 } else { | 52 return false; |
49 service = (T)result; | |
50 return true; | |
51 } | |
52 } | 53 } |
53 | 54 |
54 /// <summary> | 55 /// <summary> |
55 /// Получает объект предоставляющий сервис <paramref name="serviceType"/> | 56 /// Получает объект предоставляющий сервис <paramref name="serviceType"/> |
56 /// </summary> | 57 /// </summary> |
57 /// <param name="serviceType">Тип запрашиваемого сервиса</param> | 58 /// <param name="serviceType">Тип запрашиваемого сервиса</param> |
58 /// <returns>Объект, реализующий сервис</returns> | 59 /// <returns>Объект, реализующий сервис</returns> |
59 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception> | 60 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception> |
60 public object GetService(Type serviceType) { | 61 public object GetService(Type serviceType) { |
61 return GetService (serviceType, true); | 62 object result; |
63 if (TryGetService(serviceType, out result)) | |
64 return result; | |
65 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType)); | |
62 } | 66 } |
63 | 67 |
64 public virtual object GetService(Type serviceType, bool throwOnError) { | 68 /// <summary> |
69 /// Пытается получить требуемый сервис или совместимый с ним. | |
70 /// </summary> | |
71 /// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns> | |
72 /// <param name="serviceType">Тип запрашиваемого сервиса.</param> | |
73 /// <param name="service">Искомый сервис.</param> | |
74 public virtual bool TryGetService(Type serviceType, out object service) { | |
65 if (serviceType == null) | 75 if (serviceType == null) |
66 throw new ArgumentNullException("serviceType"); | 76 throw new ArgumentNullException("serviceType"); |
67 AssertNotDisposed(); | 77 AssertNotDisposed(); |
68 | 78 |
69 ServiceEntry se; | 79 ServiceEntry se; |
71 // ищем ближайщий объект, реализующий нужный сервис | 81 // ищем ближайщий объект, реализующий нужный сервис |
72 Type pt = null; | 82 Type pt = null; |
73 foreach (var t in m_services.Keys) | 83 foreach (var t in m_services.Keys) |
74 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt))) | 84 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt))) |
75 pt = t; | 85 pt = t; |
76 if (pt == null) | 86 |
77 throw new ApplicationException(String.Format("{0} doesn't provide {1} service",this,serviceType)); | 87 if (pt == null) { |
88 // нет нужного сервиса | |
89 service = null; | |
90 return false; | |
91 } | |
78 | 92 |
79 var pe = m_services[pt]; | 93 var pe = m_services[pt]; |
80 | 94 |
81 // найденная запись может ссылаться на оригинальную запись с сервисом | 95 // найденная запись может ссылаться на оригинальную запись с сервисом |
82 if(pe.origin != null) { | 96 if(pe.origin != null) { |
102 | 116 |
103 m_services[serviceType] = se; | 117 m_services[serviceType] = se; |
104 } | 118 } |
105 | 119 |
106 // запись содержит в себе информацию о сервисе | 120 // запись содержит в себе информацию о сервисе |
107 if (se.service != null) | 121 if (se.service != null) { |
108 return se.service; | 122 service = se.service; |
123 return true; | |
124 } | |
109 | 125 |
110 // текущая запись является ссылкой | 126 // текущая запись является ссылкой |
111 if (se.origin != null) { | 127 if (se.origin != null) { |
112 se.service = GetService(se.origin); | 128 se.service = GetService(se.origin); |
113 m_services[serviceType] = se; | 129 m_services[serviceType] = se; |
114 return se.service; | 130 service = se.service; |
131 return true; | |
115 } | 132 } |
116 | 133 |
117 // текущая запись не является ссылкой и не имеет информации о сервисе | 134 // текущая запись не является ссылкой и не имеет информации о сервисе |
118 // она должна сожержать информацию об активации | 135 // она должна сожержать информацию об активации |
119 if (se.activator != null) { | 136 if (se.activator != null) { |
120 se.service = se.activator(); | 137 se.service = se.activator(); |
121 | 138 |
122 m_services[serviceType] = se; | 139 m_services[serviceType] = se; |
123 | 140 |
124 return se.service; | 141 service = se.service; |
125 } | 142 return true; |
126 | 143 } |
127 if (throwOnError) | 144 |
128 throw new Exception("Unable to create a service instance"); | 145 service = null; |
129 return null; | 146 return false; |
130 } | 147 } |
131 | 148 |
132 /// <summary> | 149 /// <summary> |
133 /// Регистрирует фабрику для активации сервиса по первому требованию. | 150 /// Регистрирует фабрику для активации сервиса по первому требованию. |
134 /// </summary> | 151 /// </summary> |