@@ -1,21 +1,35 | |||
|
1 | 1 | using System; |
|
2 | 2 | using System.Collections.Generic; |
|
3 | using System.Linq; | |
|
4 | using System.Web; | |
|
5 | using System.Diagnostics; | |
|
6 | 3 | |
|
7 | 4 | namespace Implab { |
|
8 | 5 | /// <summary> |
|
9 | 6 | /// Коллекция сервисов, позволяет регистрировать и получать сервисы. |
|
10 | 7 | /// </summary> |
|
11 | 8 | public class ServiceLocator: Component, IServiceLocator, IServiceProvider { |
|
12 |
// запись о |
|
|
13 | struct ServiceEntry { | |
|
9 | // запись о сервисе | |
|
10 | struct ServiceEntry : IDisposable { | |
|
14 | 11 | public object service; // сервис |
|
15 | 12 | public bool shared; // признак того, что сервис НЕ нужно освобождать |
|
16 | 13 | public Func<object> activator; // активатор сервиса при первом обращении |
|
14 | public Action<object> cleanup; // функция для очистки сервиса | |
|
17 | 15 | public List<Type> associated; // ссылки на текущую запись |
|
18 | 16 | public Type origin; // ссылка на оригинальную запись о сервисе |
|
17 | ||
|
18 | #region IDisposable implementation | |
|
19 | ||
|
20 | public void Dispose() { | |
|
21 | if (shared) | |
|
22 | return; | |
|
23 | if (cleanup != null) | |
|
24 | cleanup(service); | |
|
25 | else { | |
|
26 | var d = service as IDisposable; | |
|
27 | if (d != null) | |
|
28 | d.Dispose(); | |
|
29 | } | |
|
30 | } | |
|
31 | ||
|
32 | #endregion | |
|
19 | 33 | } |
|
20 | 34 | |
|
21 | 35 | // словарь существующих сервисов |
@@ -72,8 +86,7 namespace Implab { | |||
|
72 | 86 | /// <param name="serviceType">Тип запрашиваемого сервиса.</param> |
|
73 | 87 | /// <param name="service">Искомый сервис.</param> |
|
74 | 88 | public virtual bool TryGetService(Type serviceType, out object service) { |
|
75 | if (serviceType == null) | |
|
76 | throw new ArgumentNullException("serviceType"); | |
|
89 | Safe.ArgumentNotNull(serviceType, "serviceType"); | |
|
77 | 90 | AssertNotDisposed(); |
|
78 | 91 | |
|
79 | 92 | ServiceEntry se; |
@@ -151,21 +164,26 namespace Implab { | |||
|
151 | 164 | /// </summary> |
|
152 | 165 | /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam> |
|
153 | 166 | /// <param name="activator">Фабрика для создания/получения объекта, предоставляющего сервис.</param> |
|
167 | /// <param name = "cleanup">Метод для освобождения экземпляра сервиса, будет вызыван при освобождении сервис-локатора.</param> | |
|
154 | 168 | /// <exception cref="InvalidOperationException">Указанный сервис уже зарегистрирован.</exception> |
|
155 | 169 | /// <remarks>При освобождении сервис-локатора, сервисы полученные в результате активации также будут освобождены.</remarks> |
|
156 | public void Register<T>(Func<T> activator) { | |
|
157 | if (activator == null) | |
|
158 | throw new ArgumentNullException("activator"); | |
|
170 | public void Register<T>(Func<T> activator, Action<T> cleanup) { | |
|
171 | Safe.ArgumentNotNull(activator, "activator"); | |
|
159 | 172 | |
|
160 | 173 | AssertNotDisposed(); |
|
161 | 174 | |
|
162 | 175 | Unregister(typeof(T)); |
|
163 | 176 | |
|
164 | 177 | m_services[typeof(T)] = new ServiceEntry { |
|
165 |
activator = () => activator() |
|
|
178 | activator = () => activator(), | |
|
179 | cleanup = instance => cleanup((T)instance) | |
|
166 | 180 | }; |
|
167 | 181 | } |
|
168 | 182 | |
|
183 | public void Register<T>(Func<T> activator) { | |
|
184 | Register(activator, null); | |
|
185 | } | |
|
186 | ||
|
169 | 187 | /// <summary> |
|
170 | 188 | /// Регистрирует объект, предоставляющий сервис. |
|
171 | 189 | /// </summary> |
@@ -185,8 +203,7 namespace Implab { | |||
|
185 | 203 | /// <param name="shared">Признак того, что объект является разделяемым и сервис-локатор не должен его освобождать.</param> |
|
186 | 204 | /// <exception cref="InvalidOperationException">Указанный сервис уже зарегистрирован.</exception> |
|
187 | 205 | public void Register<T>(T service, bool shared) { |
|
188 | if (service == null) | |
|
189 | throw new ArgumentNullException("service"); | |
|
206 | Safe.ArgumentNotNull(service, "service"); | |
|
190 | 207 | |
|
191 | 208 | AssertNotDisposed(); |
|
192 | 209 | |
@@ -196,8 +213,7 namespace Implab { | |||
|
196 | 213 | } |
|
197 | 214 | |
|
198 | 215 | public void Unregister(Type serviceType) { |
|
199 | if (serviceType == null) | |
|
200 | throw new ArgumentNullException("serviceType"); | |
|
216 | Safe.ArgumentNotNull(serviceType, "serviceType"); | |
|
201 | 217 | |
|
202 | 218 | AssertNotDisposed(); |
|
203 | 219 | |
@@ -223,8 +239,7 namespace Implab { | |||
|
223 | 239 | if (disposing) { |
|
224 | 240 | |
|
225 | 241 | foreach (var entry in m_services.Values) |
|
226 |
|
|
|
227 | ((IDisposable)entry.service).Dispose(); | |
|
242 | entry.Dispose(); | |
|
228 | 243 | |
|
229 | 244 | } |
|
230 | 245 | base.Dispose(disposing); |
General Comments 0
You need to be logged in to leave comments.
Login now