##// END OF EJS Templates
service locator refactoring
cin -
r69:48763f3b5db8 default
parent child
Show More
@@ -8,5 +8,6 namespace Implab {
8 public interface IServiceLocator: IServiceProvider {
8 public interface IServiceLocator: IServiceProvider {
9 T GetService<T>();
9 T GetService<T>();
10 bool TryGetService<T>(out T service);
10 bool TryGetService<T>(out T service);
11 bool TryGetService (Type serviceType, out object service);
11 }
12 }
12 }
13 }
@@ -2,6 +2,7
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Web;
4 using System.Web;
5 using System.Diagnostics;
5
6
6 namespace Implab {
7 namespace Implab {
7 /// <summary>
8 /// <summary>
@@ -18,7 +19,7 namespace Implab {
18 }
19 }
19
20
20 // словарь существующих сервисов
21 // словарь существующих сервисов
21 Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
22 readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
22
23
23 /// <summary>
24 /// <summary>
24 /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
25 /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
@@ -27,7 +28,10 namespace Implab {
27 /// <returns>Объект, реализующий сервис</returns>
28 /// <returns>Объект, реализующий сервис</returns>
28 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
29 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
29 public T GetService<T>() {
30 public T GetService<T>() {
30 return (T)GetService(typeof(T));
31 object result;
32 if (TryGetService(typeof(T), out result))
33 return (T)result;
34 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T)));
31 }
35 }
32
36
33
37
@@ -39,16 +43,13 namespace Implab {
39 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
43 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
40 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
44 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
41 public bool TryGetService<T>(out T service) {
45 public bool TryGetService<T>(out T service) {
42 AssertNotDisposed();
46 object result;
43
47 if (TryGetService(typeof(T), out result)) {
44 var result = GetService(typeof(T), false);
45 if (result == null) {
46 service = default(T);
47 return false;
48 } else {
49 service = (T)result;
48 service = (T)result;
50 return true;
49 return true;
51 }
50 }
51 service = default(T);
52 return false;
52 }
53 }
53
54
54 /// <summary>
55 /// <summary>
@@ -58,10 +59,19 namespace Implab {
58 /// <returns>Объект, реализующий сервис</returns>
59 /// <returns>Объект, реализующий сервис</returns>
59 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
60 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
60 public object GetService(Type serviceType) {
61 public object GetService(Type serviceType) {
61 return GetService (serviceType, true);
62 object result;
63 if (TryGetService(serviceType, out result))
64 return result;
65 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType));
62 }
66 }
63
67
64 public virtual object GetService(Type serviceType, bool throwOnError) {
68 /// <summary>
69 /// Пытается получить требуемый сервис или совместимый с ним.
70 /// </summary>
71 /// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns>
72 /// <param name="serviceType">Тип запрашиваемого сервиса.</param>
73 /// <param name="service">Искомый сервис.</param>
74 public virtual bool TryGetService(Type serviceType, out object service) {
65 if (serviceType == null)
75 if (serviceType == null)
66 throw new ArgumentNullException("serviceType");
76 throw new ArgumentNullException("serviceType");
67 AssertNotDisposed();
77 AssertNotDisposed();
@@ -73,8 +83,12 namespace Implab {
73 foreach (var t in m_services.Keys)
83 foreach (var t in m_services.Keys)
74 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
84 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
75 pt = t;
85 pt = t;
76 if (pt == null)
86
77 throw new ApplicationException(String.Format("{0} doesn't provide {1} service",this,serviceType));
87 if (pt == null) {
88 // нет нужного сервиса
89 service = null;
90 return false;
91 }
78
92
79 var pe = m_services[pt];
93 var pe = m_services[pt];
80
94
@@ -104,14 +118,17 namespace Implab {
104 }
118 }
105
119
106 // запись содержит в себе информацию о сервисе
120 // запись содержит в себе информацию о сервисе
107 if (se.service != null)
121 if (se.service != null) {
108 return se.service;
122 service = se.service;
123 return true;
124 }
109
125
110 // текущая запись является ссылкой
126 // текущая запись является ссылкой
111 if (se.origin != null) {
127 if (se.origin != null) {
112 se.service = GetService(se.origin);
128 se.service = GetService(se.origin);
113 m_services[serviceType] = se;
129 m_services[serviceType] = se;
114 return se.service;
130 service = se.service;
131 return true;
115 }
132 }
116
133
117 // текущая запись не является ссылкой и не имеет информации о сервисе
134 // текущая запись не является ссылкой и не имеет информации о сервисе
@@ -121,12 +138,12 namespace Implab {
121
138
122 m_services[serviceType] = se;
139 m_services[serviceType] = se;
123
140
124 return se.service;
141 service = se.service;
142 return true;
125 }
143 }
126
144
127 if (throwOnError)
145 service = null;
128 throw new Exception("Unable to create a service instance");
146 return false;
129 return null;
130 }
147 }
131
148
132 /// <summary>
149 /// <summary>
General Comments 0
You need to be logged in to leave comments. Login now