diff --git a/Implab/IServiceLocator.cs b/Implab/IServiceLocator.cs --- a/Implab/IServiceLocator.cs +++ b/Implab/IServiceLocator.cs @@ -8,5 +8,6 @@ namespace Implab { public interface IServiceLocator: IServiceProvider { T GetService(); bool TryGetService(out T service); + bool TryGetService (Type serviceType, out object service); } } diff --git a/Implab/ServiceLocator.cs b/Implab/ServiceLocator.cs --- a/Implab/ServiceLocator.cs +++ b/Implab/ServiceLocator.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using System.Diagnostics; namespace Implab { /// @@ -18,7 +19,7 @@ namespace Implab { } // словарь существующих сервисов - Dictionary m_services = new Dictionary(); + readonly Dictionary m_services = new Dictionary(); /// /// Получает объект предоставляющий сервис . @@ -27,7 +28,10 @@ namespace Implab { /// Объект, реализующий сервис /// Сервис не зарегистрирован public T GetService() { - 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 @@ namespace Implab { /// Объект реализующий сервис, или default(T) если такового нет. /// true - сервис найден, false - сервис не зарегистрирован. public bool TryGetService(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; } /// @@ -58,10 +59,19 @@ namespace Implab { /// Объект, реализующий сервис /// Сервис не зарегистрирован 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) { + /// + /// Пытается получить требуемый сервис или совместимый с ним. + /// + /// true, если сервис был найден, false в противном случае.. + /// Тип запрашиваемого сервиса. + /// Искомый сервис. + public virtual bool TryGetService(Type serviceType, out object service) { if (serviceType == null) throw new ArgumentNullException("serviceType"); AssertNotDisposed(); @@ -73,8 +83,12 @@ namespace Implab { 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 @@ namespace Implab { } // запись содержит в себе информацию о сервисе - 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 @@ namespace Implab { 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; } ///