Inject Arrays and Collectionsโ
Sometimes you need to inject an array or collection of beans into another bean, for example, when you need to inject listeners into a publisher, or caches into a cache manager.
Clawject has some reserved types for arrays and collections:
- array:
ReadonlyArray<T> | Array<T> | readonly T[] | T[]
- set:
ReadonlySet<T> | Set<T>
- map:
ReadonlyMap<string, T> | Map<string, T>
Note that all arrays and collections that are injected are non-singletons, so mutating one of them will not affect other beans.
Let's look at how we can inject arrays and collections with Clawject:
- Array literal
- Array
- ReadonlyArray
- Set
- ReadonlySet
- Map
- ReadonlyMap
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: Cache<any>[],
) {}
clearAll(): void {
this.caches.forEach(cache => cache.clear());
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: Array<Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach(cache => cache.clear());
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: ReadonlyArray<Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach(cache => cache.clear());
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: Set<Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach(cache => cache.clear());
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: ReadonlySet<Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach(cache => cache.clear());
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: Map<string, Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach((cache, beanName) => {
console.log(`Clearing cache ${beanName}`);
cache.clear();
});
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
class Cache<T> {
clear(): void { /* ... */ }
}
class CacheManager {
constructor(
private caches: ReadonlyMap<string, Cache<any>>,
) {}
clearAll(): void {
this.caches.forEach((cache, beanName) => {
console.log(`Clearing cache ${beanName}`);
cache.clear();
});
}
}
@ClawjectApplication
class Application {
stringCache = Bean(Cache<string>)
numberCache = Bean(Cache<number>)
booleanCache = Bean(Cache<boolean>)
cacheManager = Bean(CacheManager)
}
Defining Bean with Array or Collection typeโ
If you want to define Bean with type Array or Collection - you can safely do that. To access such beans โ you should match the type of collection and bean name.
@ClawjectApplication
class Application {
@Bean myCollection = new Set(['foo', 'bar', 'baz']);
@Bean string1 = 'quux';
@Bean string2 = 'quuux';
@PostConstruct
postConstruct(
myCollection: Set<string>, // myCollection bean will be injected
otherStrings: Set<string>, // Set of string1 and string2 beans will be injected
): void {}
}