You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+42-2Lines changed: 42 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -368,7 +368,7 @@ You can create `ServiceProvider` in several ways:
368
368
You can create `ServiceParamsProvider` by using a factory with parameters (`ServiceParamsFactory`): `ServiceParamsProvider(factory:)` or using closure `ServiceParamsProvider { params in }`.
369
369
370
370
To get the service it is enough to call the function `try Service[Params]Provider.getService()` which returns the service or error.
371
-
You can also use `Service[Params]Provider.getServiceAsOptional()` - then the service is returned as an option (nil in case of an error) or `Service[Params]Provider.getServiceOrFatal()` - in case of an error, there will be a crash with detailed information about the error.
371
+
You can also use `Service[Params]Provider.getServiceAsResult()`, `Service[Params]Provider.getServiceAsOptional()` - then the service is returned as an option (nil in case of an error) or `Service[Params]Provider.getServiceOrFatal()` - in case of an error, there will be a crash with detailed information about the error.
372
372
Use `getServiceOrFatal()` instead of `try! getService()` or `getServiceAsOptional()!`, so that the cause of the crash is not lost and is easily determined.
373
373
374
374
#
@@ -384,7 +384,7 @@ Use `getServiceOrFatal()` instead of `try! getService()` or `getServiceAsOption
384
384
Создать `ServiceParamsProvider` можно используя фабрику с параметрами (`ServiceParamsFactory`) `ServiceParamsProvider(factory:)` или используя кложур `ServiceParamsProvider { params in }`.
385
385
386
386
Для получения сервиса достаточно вызвать функцию `try Service[Params]Provider.getService()` которая возвращает сервис или ошибку.
387
-
Также можно использовать `Service[Params]Provider.getServiceAsOptional()` - тогда сервис возвращается как опционал (nil в случае ошибки) или `Service[Params]Provider.getServiceOrFatal()` - в случае ошибки будет краш с подробной информацией об ошибке.
387
+
Также можно использовать `Service[Params]Provider.getServiceAsResult()`, `Service[Params]Provider.getServiceAsOptional()` - тогда сервис возвращается как опционал (nil в случае ошибки) или `Service[Params]Provider.getServiceOrFatal()` - в случае ошибки будет краш с подробной информацией об ошибке.
388
388
Используйте `getServiceOrFatal()` вместо `try! getService()` или `getServiceAsOptional()!`, чтобы причина краша не потерялась и была легко определима.
389
389
390
390
@@ -402,6 +402,46 @@ do {
402
402
}
403
403
```
404
404
405
+
### Service[Params]SafeProvider
406
+
407
+
In some cases, you may need to get services from different threads. To support multithreading, you can use special thread-safe providers. Their task is to make each service receipt thread-safe by blocking or using synchronously a separate queue for each access to the provider and the factory.
408
+
This is usually not required, because the configuration of services at the start of the application and their receipt in the presentation layer occurs in the main thread. But if there are cases when the service is requested not from the main thread - you should use a secure provider. Getting the service from such a provider may be slower than usual.
409
+
410
+
To create a secure provider, use the `serviceSafeProvider()` or constructor methods.
411
+
The default is `NSLock`, but you can choose `DispatchSemaphore` or a separate queue `DispatchQueue`.
412
+
413
+
`Service[Params]SafeProvider` is a inheritance of regular providers, so the entire standard set of methods is available and you can store and pass such a provider as a regular one. But in addition, there is one method - `getServiceAsResultNotSafe()`, which will ignore any locks and perform the usual non-secure getting of the service.
414
+
415
+
#
416
+
417
+
В некоторых случаях может потребоваться получать сервисы из разных потоков. Чтобы поддержать мультипоточность можно использовать специальные потоко-безопасные провайдеры. Их задача - каждое получение сервиса сделать потоко-безопасным, блокируя или используя синхронно отдельную очередь при каждом обращении к првайдеру и фабрике.
418
+
Обычно это не требуется, т.к. настройка сервисов при старте приложения и их получения в слое презентации происходит в главном потоке. Но если есть случаи когда сервис запрашивается не из главного потока - следует использовать безопасный провайдер. Получение сервиса у такого провайдера может быть медленнее обычного.
419
+
420
+
Для создания безпасного провайдера используются методы `serviceSafeProvider()` или конструктор.
421
+
По умолчанию используется `NSLock`, но вы можете выбрать `DispatchSemaphore` или отдельную очередь `DispatchQueue`.
422
+
423
+
`Service[Params]SafeProvider` является наследником обычных провайдеров, поэтому доступен весь стандартный набор методов и можно хранить и передавать такой провайдер как обычный. Но в дополнение есть один метод - `getServiceAsResultNotSafe()`, который проигнорирует любые блокировки и выполнит обычное не безопасное получение сервиса.
424
+
425
+
426
+
```swift
427
+
structServiceContainer {
428
+
let firstService: ServiceProvider<FirstService>
429
+
}
430
+
431
+
extensionServiceContainer {
432
+
staticfuncmakeDefault() -> ServiceContainer {
433
+
let firstService: ServiceSafeProvider<FirstService> =FirstServiceFactory().serviceSafeProvider(safeThread: .lock)
434
+
435
+
return .init(
436
+
firstService: firstService
437
+
)
438
+
}
439
+
}
440
+
441
+
let service = container.firstService.getServiceAsOptional()
442
+
```
443
+
444
+
405
445
### Support Objective-C
406
446
407
447
Creating and configuring the container is only available for swift code, but for objective-c, you can provide a special wrapper to getting the services.
0 commit comments