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