changeset 69:48763f3b5db8

service locator refactoring
author cin
date Thu, 28 Aug 2014 19:38:39 +0400
parents 9dd6a896a385
children 0349189d2564
files Implab/IServiceLocator.cs Implab/ServiceLocator.cs
diffstat 2 files changed, 41 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/IServiceLocator.cs	Thu Aug 28 02:28:00 2014 +0400
+++ b/Implab/IServiceLocator.cs	Thu Aug 28 19:38:39 2014 +0400
@@ -8,5 +8,6 @@
     public interface IServiceLocator: IServiceProvider {
         T GetService<T>();
         bool TryGetService<T>(out T service);
+		bool TryGetService (Type serviceType, out object service);
     }
 }
--- a/Implab/ServiceLocator.cs	Thu Aug 28 02:28:00 2014 +0400
+++ b/Implab/ServiceLocator.cs	Thu Aug 28 19:38:39 2014 +0400
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;
+using System.Diagnostics;
 
 namespace Implab {
     /// <summary>
@@ -18,7 +19,7 @@
         }
 
         // словарь существующих сервисов
-        Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
+        readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
 
         /// <summary>
         /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
@@ -27,7 +28,10 @@
         /// <returns>Объект, реализующий сервис</returns>
         /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
         public T GetService<T>() {
-            return (T)GetService(typeof(T));
+            object result;
+            if (TryGetService(typeof(T), out result))
+                return (T)result;
+            throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T)));
         }
 
 
@@ -39,16 +43,13 @@
         /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
         /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
         public bool TryGetService<T>(out T service) {
-            AssertNotDisposed();
-
-			var result = GetService(typeof(T), false);
-			if (result == null) {
-				service = default(T);
-				return false;
-			} else {
-				service = (T)result;
-				return true;
-			}
+            object result;
+            if (TryGetService(typeof(T), out result)) {
+                service = (T)result;
+                return true;
+            }
+            service = default(T);
+            return false;
         }
 
         /// <summary>
@@ -58,10 +59,19 @@
         /// <returns>Объект, реализующий сервис</returns>
         /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
 		public object GetService(Type serviceType) {
-			return GetService (serviceType, true);
+            object result;
+            if (TryGetService(serviceType, out result))
+                return result;
+			throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType));
 		}
 
-		public virtual object GetService(Type serviceType, bool throwOnError) {
+		/// <summary>
+		/// Пытается получить требуемый сервис или совместимый с ним.
+		/// </summary>
+		/// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns>
+		/// <param name="serviceType">Тип запрашиваемого сервиса.</param>
+		/// <param name="service">Искомый сервис.</param>
+		public virtual bool TryGetService(Type serviceType, out object service) {
             if (serviceType == null)
                 throw new ArgumentNullException("serviceType");
             AssertNotDisposed();
@@ -73,8 +83,12 @@
                 foreach (var t in m_services.Keys)
                     if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
                         pt = t;
-                if (pt == null)
-                    throw new ApplicationException(String.Format("{0} doesn't provide {1} service",this,serviceType));
+
+				if (pt == null) {
+					// нет нужного сервиса
+					service = null;
+					return false;
+				}
 
                 var pe = m_services[pt];
 
@@ -104,14 +118,17 @@
             }
 
             // запись содержит в себе информацию о сервисе
-            if (se.service != null)
-                return se.service;
+			if (se.service != null) {
+				service = se.service;
+				return true;
+			}
 
             // текущая запись является ссылкой
             if (se.origin != null) {
                 se.service = GetService(se.origin);
                 m_services[serviceType] = se;
-                return se.service;
+				service = se.service;
+				return true;
             }
 
             // текущая запись не является ссылкой и не имеет информации о сервисе
@@ -121,12 +138,12 @@
 
                 m_services[serviceType] = se;
 
-                return se.service;
+				service = se.service;
+				return true;
             }
 
-			if (throwOnError)
-            	throw new Exception("Unable to create a service instance");
-			return null;
+			service = null;
+			return false;
         }
 
         /// <summary>