@@ -97,13 +97,14 @@ namespace sb::di
9797 */
9898 template <class TService > TService *tryGetService ()
9999 {
100- auto _ = tryUniqueLock ();
101- if (const auto instancePtr = getInstanceProvider ().tryGetInstance (typeid (TService));
102- instancePtr && *instancePtr)
103- {
104- return instancePtr->getAs <TService>();
105- }
106- return nullptr ;
100+ return safeAction ([&] -> TService * {
101+ if (const auto instancePtr = getInstanceProvider ().tryGetInstance (typeid (TService));
102+ instancePtr && *instancePtr)
103+ {
104+ return instancePtr->getAs <TService>();
105+ }
106+ return nullptr ;
107+ });
107108 }
108109
109110 /* *
@@ -120,13 +121,14 @@ namespace sb::di
120121 */
121122 template <class TService > TService *tryGetKeyedService (const std::string_view serviceKey)
122123 {
123- auto _ = tryUniqueLock ();
124- if (const auto instancePtr = getInstanceProvider ().tryGetKeyedInstance (typeid (TService), serviceKey);
125- instancePtr && *instancePtr)
126- {
127- return instancePtr->getAs <TService>();
128- }
129- return nullptr ;
124+ return safeAction ([&] -> TService * {
125+ if (const auto instancePtr = getInstanceProvider ().tryGetKeyedInstance (typeid (TService), serviceKey);
126+ instancePtr && *instancePtr)
127+ {
128+ return instancePtr->getAs <TService>();
129+ }
130+ return nullptr ;
131+ });
130132 }
131133
132134 /* *
@@ -143,10 +145,11 @@ namespace sb::di
143145 */
144146 template <class TService > TService &getService ()
145147 {
146- auto _ = tryUniqueLock ();
147- auto &instance = getInstanceProvider ().getInstance (typeid (TService));
148- details::RequireInstance::valid (instance);
149- return *instance.getAs <TService>();
148+ return *safeAction ([&] -> TService * {
149+ auto &instance = getInstanceProvider ().getInstance (typeid (TService));
150+ details::RequireInstance::valid (instance);
151+ return instance.getAs <TService>();
152+ });
150153 }
151154
152155 /* *
@@ -164,10 +167,11 @@ namespace sb::di
164167 */
165168 template <class TService > TService &getKeyedService (const std::string_view serviceKey)
166169 {
167- auto _ = tryUniqueLock ();
168- auto &instance = getInstanceProvider ().getKeyedInstance (typeid (TService), serviceKey);
169- details::RequireInstance::valid (instance);
170- return *instance.getAs <TService>();
170+ return *safeAction ([&] -> TService * {
171+ auto &instance = getInstanceProvider ().getKeyedInstance (typeid (TService), serviceKey);
172+ details::RequireInstance::valid (instance);
173+ return instance.getAs <TService>();
174+ });
171175 }
172176
173177 /* *
@@ -186,15 +190,16 @@ namespace sb::di
186190 */
187191 template <class TService > std::vector<TService *> getServices ()
188192 {
189- auto _ = tryUniqueLock ();
190- if (auto instancesPtr = getInstanceProvider ().tryGetInstances (typeid (TService)))
191- {
192- return instancesPtr->map ([](const ServiceInstance &instance) {
193- details::RequireInstance::valid (instance);
194- return instance.getAs <TService>();
195- });
196- }
197- return {};
193+ return safeAction ([&] -> std::vector<TService *> {
194+ if (auto instancesPtr = getInstanceProvider ().tryGetInstances (typeid (TService)))
195+ {
196+ return instancesPtr->map ([](const ServiceInstance &instance) {
197+ details::RequireInstance::valid (instance);
198+ return instance.getAs <TService>();
199+ });
200+ }
201+ return {};
202+ });
198203 }
199204
200205 /* *
@@ -214,15 +219,16 @@ namespace sb::di
214219 */
215220 template <class TService > std::vector<TService *> getKeyedServices (const std::string_view serviceKey)
216221 {
217- auto _ = tryUniqueLock ();
218- if (auto instancesPtr = getInstanceProvider ().tryGetKeyedInstances (typeid (TService), serviceKey))
219- {
220- return instancesPtr->map ([](const ServiceInstance &instance) {
221- details::RequireInstance::valid (instance);
222- return instance.getAs <TService>();
223- });
224- }
225- return {};
222+ return safeAction ([&] -> std::vector<TService *> {
223+ if (auto instancesPtr = getInstanceProvider ().tryGetKeyedInstances (typeid (TService), serviceKey))
224+ {
225+ return instancesPtr->map ([](const ServiceInstance &instance) {
226+ details::RequireInstance::valid (instance);
227+ return instance.getAs <TService>();
228+ });
229+ }
230+ return {};
231+ });
226232 }
227233
228234 /* *
@@ -238,12 +244,13 @@ namespace sb::di
238244 */
239245 template <class TService > std::unique_ptr<TService> tryCreateService ()
240246 {
241- auto _ = tryUniqueLock ();
242- if (auto instance = getInstanceProvider ().tryCreateInstance (typeid (TService)))
243- {
244- return instance.moveOutAsUniquePtr <TService>();
245- }
246- return nullptr ;
247+ return safeAction ([&] -> std::unique_ptr<TService> {
248+ if (auto instance = getInstanceProvider ().tryCreateInstance (typeid (TService)))
249+ {
250+ return instance.moveOutAsUniquePtr <TService>();
251+ }
252+ return nullptr ;
253+ });
247254 }
248255
249256 /* *
@@ -260,12 +267,13 @@ namespace sb::di
260267 */
261268 template <class TService > std::unique_ptr<TService> tryCreateKeyedService (const std::string_view serviceKey)
262269 {
263- auto _ = tryUniqueLock ();
264- if (auto instance = getInstanceProvider ().tryCreateKeyedInstance (typeid (TService), serviceKey))
265- {
266- return instance.moveOutAsUniquePtr <TService>();
267- }
268- return nullptr ;
270+ return safeAction ([&] -> std::unique_ptr<TService> {
271+ if (auto instance = getInstanceProvider ().tryCreateKeyedInstance (typeid (TService), serviceKey))
272+ {
273+ return instance.moveOutAsUniquePtr <TService>();
274+ }
275+ return nullptr ;
276+ });
269277 }
270278
271279 /* *
@@ -282,10 +290,11 @@ namespace sb::di
282290 */
283291 template <class TService > std::unique_ptr<TService> createService ()
284292 {
285- auto _ = tryUniqueLock ();
286- auto instance = getInstanceProvider ().createInstance (typeid (TService));
287- details::RequireInstance::valid (instance);
288- return instance.moveOutAsUniquePtr <TService>();
293+ return safeAction ([&] -> std::unique_ptr<TService> {
294+ auto instance = getInstanceProvider ().createInstance (typeid (TService));
295+ details::RequireInstance::valid (instance);
296+ return instance.moveOutAsUniquePtr <TService>();
297+ });
289298 }
290299
291300 /* *
@@ -303,10 +312,11 @@ namespace sb::di
303312 */
304313 template <class TService > std::unique_ptr<TService> createKeyedService (const std::string_view serviceKey)
305314 {
306- auto _ = tryUniqueLock ();
307- auto instance = getInstanceProvider ().createKeyedInstance (typeid (TService), serviceKey);
308- details::RequireInstance::valid (instance);
309- return instance.moveOutAsUniquePtr <TService>();
315+ return safeAction ([&] -> std::unique_ptr<TService> {
316+ auto instance = getInstanceProvider ().createKeyedInstance (typeid (TService), serviceKey);
317+ details::RequireInstance::valid (instance);
318+ return instance.moveOutAsUniquePtr <TService>();
319+ });
310320 }
311321
312322 /* *
@@ -323,17 +333,18 @@ namespace sb::di
323333 */
324334 template <class TService > TService createServiceInPlace ()
325335 {
326- auto _ = tryUniqueLock ();
327- auto instance = getInstanceProvider ().createInstanceInPlace (typeid (TService));
328- details::RequireInstance::valid (instance);
329- if constexpr (std::is_move_constructible_v<TService>)
330- {
331- return instance.moveOutAs <TService>();
332- }
333- else
334- {
335- return instance.copyAs <TService>();
336- }
336+ return safeAction ([&] -> TService {
337+ auto instance = getInstanceProvider ().createInstanceInPlace (typeid (TService));
338+ details::RequireInstance::valid (instance);
339+ if constexpr (std::is_move_constructible_v<TService>)
340+ {
341+ return instance.moveOutAs <TService>();
342+ }
343+ else
344+ {
345+ return instance.copyAs <TService>();
346+ }
347+ });
337348 }
338349
339350 /* *
@@ -351,17 +362,18 @@ namespace sb::di
351362 */
352363 template <class TService > TService createKeyedServiceInPlace (const std::string_view serviceKey)
353364 {
354- auto _ = tryUniqueLock ();
355- auto instance = getInstanceProvider ().createKeyedInstanceInPlace (typeid (TService), serviceKey);
356- details::RequireInstance::valid (instance);
357- if constexpr (std::is_move_constructible_v<TService>)
358- {
359- return instance.moveOutAs <TService>();
360- }
361- else
362- {
363- return instance.copyAs <TService>();
364- }
365+ return safeAction ([&] -> TService {
366+ auto instance = getInstanceProvider ().createKeyedInstanceInPlace (typeid (TService), serviceKey);
367+ details::RequireInstance::valid (instance);
368+ if constexpr (std::is_move_constructible_v<TService>)
369+ {
370+ return instance.moveOutAs <TService>();
371+ }
372+ else
373+ {
374+ return instance.copyAs <TService>();
375+ }
376+ });
365377 }
366378
367379 /* *
@@ -380,11 +392,12 @@ namespace sb::di
380392 */
381393 template <class TService > std::vector<std::unique_ptr<TService>> createServices ()
382394 {
383- auto _ = tryUniqueLock ();
384- auto instances = getInstanceProvider ().tryCreateInstances (typeid (TService));
385- return instances.map ([&](ServiceInstance &instance) {
386- details::RequireInstance::valid (instance);
387- return instance.moveOutAsUniquePtr <TService>();
395+ return safeAction ([&] -> std::vector<std::unique_ptr<TService>> {
396+ auto instances = getInstanceProvider ().tryCreateInstances (typeid (TService));
397+ return instances.map ([&](ServiceInstance &instance) {
398+ details::RequireInstance::valid (instance);
399+ return instance.moveOutAsUniquePtr <TService>();
400+ });
388401 });
389402 }
390403
@@ -406,19 +419,24 @@ namespace sb::di
406419 template <class TService >
407420 std::vector<std::unique_ptr<TService>> createKeyedServices (const std::string_view serviceKey)
408421 {
409- auto _ = tryUniqueLock ();
410- auto instances = getInstanceProvider ().tryCreateKeyedInstances (typeid (TService), serviceKey);
411- return instances.map ([&](ServiceInstance &instance) {
412- details::RequireInstance::valid (instance);
413- return instance.moveOutAsUniquePtr <TService>();
422+ return safeAction ([&] -> std::vector<std::unique_ptr<TService>> {
423+ auto instances = getInstanceProvider ().tryCreateKeyedInstances (typeid (TService), serviceKey);
424+ return instances.map ([&](ServiceInstance &instance) {
425+ details::RequireInstance::valid (instance);
426+ return instance.moveOutAsUniquePtr <TService>();
427+ });
414428 });
415429 }
416430
417431 private:
418- std::optional<std::unique_lock<std::recursive_mutex>> tryUniqueLock ( )
432+ template < class TAction > auto safeAction (TAction action )
419433 {
420- const auto mutexPtr = getInstanceProvider ().tryGetSyncMutex ();
421- return mutexPtr ? std::make_optional (std::unique_lock{*mutexPtr}) : std::nullopt ;
434+ if (const auto mutexPtr = getInstanceProvider ().tryGetSyncMutex ())
435+ {
436+ std::lock_guard lock{*mutexPtr};
437+ return action ();
438+ }
439+ return action ();
422440 }
423441 };
424442} // namespace sb::di
0 commit comments