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 {}
}