##// END OF EJS Templates
ServiceLocator: added a cleanup callback to the service registration method
cin -
r86:b33832ab0262 v2
parent child
Show More
@@ -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() as object
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 if (!entry.shared && entry.service is IDisposable)
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