1: | <?php declare(strict_types=1); |
2: | |
3: | namespace Salient\Contract\Container; |
4: | |
5: | use Psr\Container\ContainerInterface as PsrContainerInterface; |
6: | use Salient\Contract\Container\Event\BeforeGlobalContainerSetEvent; |
7: | use Salient\Contract\Container\Exception\InvalidServiceException; |
8: | use Salient\Contract\Container\Exception\ServiceNotFoundException; |
9: | use Salient\Contract\Container\Exception\UnusedArgumentsException; |
10: | use Salient\Contract\Core\Chainable; |
11: | use Salient\Contract\Core\Instantiable; |
12: | use Salient\Contract\Core\Unloadable; |
13: | use Closure; |
14: | |
15: | /** |
16: | * @api |
17: | */ |
18: | interface ContainerInterface extends |
19: | PsrContainerInterface, |
20: | Chainable, |
21: | Instantiable, |
22: | Unloadable, |
23: | HasServiceLifetime |
24: | { |
25: | /** |
26: | * Creates a new service container |
27: | */ |
28: | public function __construct(); |
29: | |
30: | /** |
31: | * Check if the global container is set |
32: | */ |
33: | public static function hasGlobalContainer(): bool; |
34: | |
35: | /** |
36: | * Get the global container, creating it if necessary |
37: | */ |
38: | public static function getGlobalContainer(): ContainerInterface; |
39: | |
40: | /** |
41: | * Set or unset the global container |
42: | * |
43: | * Dispatches {@see BeforeGlobalContainerSetEvent} if the global container |
44: | * will change. |
45: | */ |
46: | public static function setGlobalContainer(?ContainerInterface $container): void; |
47: | |
48: | /** |
49: | * Apply contextual bindings to a copy of the container |
50: | * |
51: | * @param class-string $id |
52: | * @return static |
53: | */ |
54: | public function inContextOf(string $id): ContainerInterface; |
55: | |
56: | /** |
57: | * Resolve a service from the container |
58: | * |
59: | * Values in `$args` are passed to constructor parameters after: |
60: | * |
61: | * 1. matching objects to parameters with compatible type declarations |
62: | * 2. matching keys in `$args` to parameters with the same name |
63: | * 3. matching values to parameters by type and position |
64: | * |
65: | * @template T |
66: | * |
67: | * @param class-string<T> $id |
68: | * @param mixed[] $args |
69: | * @return T&object |
70: | * @throws ServiceNotFoundException if `$id` is not instantiable. |
71: | * @throws UnusedArgumentsException if `$args` are given and `$id` resolves |
72: | * to a shared instance. |
73: | */ |
74: | public function get(string $id, array $args = []): object; |
75: | |
76: | /** |
77: | * Resolve a partially-resolved service from the container |
78: | * |
79: | * `$id` is resolved normally, but `$service` is passed to |
80: | * {@see ServiceAwareInterface::setService()} instead of `$id`. |
81: | * |
82: | * @template TService |
83: | * @template T of TService |
84: | * |
85: | * @param class-string<T> $id |
86: | * @param class-string<TService> $service |
87: | * @param mixed[] $args |
88: | * @return T&object |
89: | * @throws ServiceNotFoundException if `$id` is not instantiable. |
90: | * @throws UnusedArgumentsException if `$args` are given and `$id` resolves |
91: | * to a shared instance. |
92: | */ |
93: | public function getAs(string $id, string $service, array $args = []): object; |
94: | |
95: | /** |
96: | * Resolve a service from the container without returning an instance |
97: | * |
98: | * Returns the class name of the object {@see get()} would return. |
99: | * |
100: | * @template T |
101: | * |
102: | * @param class-string<T> $id |
103: | * @return class-string<T> |
104: | */ |
105: | public function getClass(string $id): string; |
106: | |
107: | /** |
108: | * Check if a service is bound to the container |
109: | * |
110: | * @param class-string $id |
111: | */ |
112: | public function has(string $id): bool; |
113: | |
114: | /** |
115: | * Check if a shared service or instance is bound to the container |
116: | * |
117: | * @param class-string $id |
118: | */ |
119: | public function hasSingleton(string $id): bool; |
120: | |
121: | /** |
122: | * Check if a service resolves to a shared instance |
123: | * |
124: | * @param class-string $id |
125: | */ |
126: | public function hasInstance(string $id): bool; |
127: | |
128: | /** |
129: | * Check if a service provider is registered with the container |
130: | * |
131: | * @param class-string $provider |
132: | */ |
133: | public function hasProvider(string $provider): bool; |
134: | |
135: | /** |
136: | * Get a list of service providers registered with the container |
137: | * |
138: | * @return array<class-string> |
139: | */ |
140: | public function getProviders(): array; |
141: | |
142: | /** |
143: | * Bind a service to the container |
144: | * |
145: | * Subsequent requests for `$id` resolve to an instance of `$class`, or |
146: | * `$id` if `$class` is `null`. |
147: | * |
148: | * If `$class` is a closure, it is called every time `$id` is resolved. |
149: | * |
150: | * @template TService |
151: | * @template T of TService |
152: | * |
153: | * @param class-string<TService> $id |
154: | * @param (Closure(self): T&object)|class-string<T>|null $class |
155: | * @return $this |
156: | */ |
157: | public function bind(string $id, $class = null): ContainerInterface; |
158: | |
159: | /** |
160: | * Bind a service to the container if it isn't already bound |
161: | * |
162: | * @template TService |
163: | * @template T of TService |
164: | * |
165: | * @param class-string<TService> $id |
166: | * @param (Closure(self): T&object)|class-string<T>|null $class |
167: | * @return $this |
168: | */ |
169: | public function bindIf(string $id, $class = null): ContainerInterface; |
170: | |
171: | /** |
172: | * Bind a shared service to the container |
173: | * |
174: | * Subsequent requests for `$id` resolve to the shared instance created when |
175: | * `$id` is first requested. |
176: | * |
177: | * @template TService |
178: | * @template T of TService |
179: | * |
180: | * @param class-string<TService> $id |
181: | * @param (Closure(self): T&object)|class-string<T>|null $class |
182: | * @return $this |
183: | */ |
184: | public function singleton(string $id, $class = null): ContainerInterface; |
185: | |
186: | /** |
187: | * Bind a shared service to the container if it isn't already bound |
188: | * |
189: | * @template TService |
190: | * @template T of TService |
191: | * |
192: | * @param class-string<TService> $id |
193: | * @param (Closure(self): T&object)|class-string<T>|null $class |
194: | * @return $this |
195: | */ |
196: | public function singletonIf(string $id, $class = null): ContainerInterface; |
197: | |
198: | /** |
199: | * Bind a shared instance to the container |
200: | * |
201: | * @template TService |
202: | * @template T of TService |
203: | * |
204: | * @param class-string<TService> $id |
205: | * @param T&object $instance |
206: | * @return $this |
207: | */ |
208: | public function instance(string $id, object $instance): ContainerInterface; |
209: | |
210: | /** |
211: | * Remove a shared instance from the container |
212: | * |
213: | * @param class-string $id |
214: | * @return $this |
215: | */ |
216: | public function removeInstance(string $id): ContainerInterface; |
217: | |
218: | /** |
219: | * Add a contextual binding to the container |
220: | * |
221: | * Subsequent requests for `$id` from the given contexts resolve to: |
222: | * |
223: | * - the return value of `$class` (if it is a closure) |
224: | * - an instance of `$class` (if it is a string) |
225: | * - `$class` itself (if it is an object), or |
226: | * - an instance of `$id` (if `$class` is `null`) |
227: | * |
228: | * If `$id` starts with `'$'`, it is matched with constructor parameters of |
229: | * the same name, and `$class` cannot be `null`. |
230: | * |
231: | * @template TService |
232: | * @template T of TService |
233: | * |
234: | * @param class-string[]|class-string $context |
235: | * @param class-string<TService>|non-empty-string $id |
236: | * @param (Closure(self): T&object)|class-string<T>|(T&object)|null $class |
237: | * @return $this |
238: | */ |
239: | public function addContextualBinding( |
240: | $context, |
241: | string $id, |
242: | $class = null |
243: | ): ContainerInterface; |
244: | |
245: | /** |
246: | * Register a service provider with the container, optionally specifying |
247: | * which of its services to bind or ignore |
248: | * |
249: | * For performance reasons, classes bound to the container with |
250: | * {@see bind()} or {@see singleton()} are not loaded until they are |
251: | * resolved. Classes registered with {@see provider()} are loaded |
252: | * immediately to check for {@see HasServices}, {@see SingletonInterface} |
253: | * and other implementations. |
254: | * |
255: | * @param class-string $provider |
256: | * @param class-string[]|null $services Services of `$provider` to bind to |
257: | * the container, or `null` to bind every service returned by |
258: | * {@see HasServices::getServices()} (if implemented). |
259: | * @param class-string[] $excludeServices Services of `$provider` to exclude |
260: | * from binding. |
261: | * @param ContainerInterface::* $providerLifetime |
262: | * @return $this |
263: | * @throws InvalidServiceException if `$provider` returns invalid container |
264: | * bindings or doesn't provide one of the given `$services`. |
265: | */ |
266: | public function provider( |
267: | string $provider, |
268: | ?array $services = null, |
269: | array $excludeServices = [], |
270: | int $providerLifetime = ContainerInterface::LIFETIME_INHERIT |
271: | ): ContainerInterface; |
272: | |
273: | /** |
274: | * Register an array that maps services (usually interfaces) to service |
275: | * providers (classes that extend or implement the mapped service) |
276: | * |
277: | * Multiple services may be mapped to the same service provider. Unmapped |
278: | * providers are mapped to themselves. |
279: | * |
280: | * @param array<class-string|int,class-string> $providers |
281: | * @param ContainerInterface::* $providerLifetime |
282: | * @return $this |
283: | */ |
284: | public function providers( |
285: | array $providers, |
286: | int $providerLifetime = ContainerInterface::LIFETIME_INHERIT |
287: | ): ContainerInterface; |
288: | } |
289: |