IonIon
Packages
  • next
  • current
Changelog
GitHub
Packages
  • next
  • current
Changelog
GitHub
  • Version 0.x

    • Release Notes
    • Upgrade Guide
    • Contribution Guide
    • Security Policy
    • Code of Conduct
    • Origin
  • Packages

    • Introduction
    • Container

      • Introduction
      • Prerequisites
      • How to install
      • Container Instance
      • Bindings
      • Dependencies
      • Resolving
      • Contextual Bindings
    • Contracts

      • Introduction
      • How to install
    • Support

      • Introduction
      • How to install
      • Arrays

        • About Arrays
        • Includes All
        • Includes Any
        • Is Array Like
        • Is Concat Spreadable
        • Is Safe Array Like
        • Is Typed Array
        • Merge
      • Concerns

        • About Concerns
        • Prerequisites
        • Concern Class
        • Using Concerns
        • Aliases
        • Conflict Resolution
        • Booting
        • Hooks
        • Edge Cases
        • JSDoc
      • Exceptions

        • About Exceptions
        • Configure Custom Error
        • Configure Stack Trace
        • Get Error Message
        • Custom Errors
      • Facades

        • About Facades
      • Meta

        • About Meta
        • Prerequisites
        • Supported Elements
        • Set & Get
        • Inheritance
        • Outside Changes
        • TC39 Proposal
        • Target Meta
      • Mixins

        • About Mixins
        • New Mixin
        • Apply Mixins
        • Instanceof
        • Inheritance
        • Onward
      • Object

        • About Objects
        • Forget
        • Forget All
        • Get
        • Has
        • Has All
        • Has Any
        • Has Unique ID
        • Is Cloneable
        • Is Populatable
        • Isset
        • Merge
        • Populate
        • Set
        • Unique ID
      • Reflections

        • About reflections
        • Assert Has Prototype Prop.
        • Class Looks Like
        • Class Own Keys
        • Get All Parents Of Class
        • Get Class Prop. Descriptor
        • Get Class Prop. Descriptors
        • Get Constructor Name
        • Get Name Or Desc. Tag
        • Get Parent Of Class
        • Has All Methods
        • Has Method
        • Has Prototype Property
        • Is Callable
        • Is Class Constructor
        • Is Class Method Reference
        • Is Constructor
        • Is Key Safe
        • Is Key Unsafe
        • Is Method
        • Is Subclass
        • Is Subclass Or Looks Like
        • Is WeakKind
      • Misc

        • About Misc.
        • Desc. Tag
        • Empty
        • Is Key
        • Is Primitive
        • Is Property Key
        • Isset
        • Merge Keys
        • To Weak Ref.
      • Callback Wrapper
    • Vuepress Utils

      • Introduction
      • How to install
      • Navigation

        • Archive
      • Plugins

        • Last Updated
      • Components

        • Version Disclaimer
    • XYZ (test package)

How to use Concerns

  • Using Concerns
  • Inheritance
  • Manual interaction
    • Determine if target uses concerns

Using Concerns

The class decorator use() is used to inject one or more concern classes into a target class.

import { use } from "@aedart/support/concerns";

@use(
    ApiConnection,
    Serialization,
    Collections
)
class Flight {}

When concern classes are injected, the target class is transformed and all concerns are made available inside a private CONCERNS property. See Manual interaction and Aliases for additional details.

Inheritance

All concerns that are used by a parent class are automatically available (inherited), by child classes.

@use(
    ApiConnection,
    Serialization,
    Collections
)
class ApiService {}

class Flight extends ApiService {} // Uses ApiConnection, Serialization, ...etc

warning

A concern class may ONLY occur once in a target class' prototype chain. An InjectionError is thrown, if this is violated!

@use(
    ApiConnection,
    Serialization,
    Collections
)
class ApiService {}

@use(Serialization) // InjectionError
class Flight extends ApiService {}

See also Conflict Resolution for additional details.

Manual interaction

When concerns are injected into a target, they are defined inside a "Concerns Container", which is available in the target instance via the CONCERNS symbol. Should you require to perform more advanced interaction with a concern class instance, then you can obtain a concern instance via the container's get() method. It will automatically ensure to boot a concern, if not already booted.

import {
    use,
    CONCERNS,
    AbstractConcern
} from "@aedart/support/concerns";

class Encryption extends AbstractConcern {
    encrypt(value) { /* ...not shown... */ }
}

@use(Encryption)
class CookieStore {
    constructor() {
        const container = this[CONCERNS];
        const value = container.get(Encryption).encrypt('Lorum lipsum');
        
        // ...remaining not shown...
    }
}

You can achieve the same result by using the getContainer() utility method.

import { use, getContainer } from "@aedart/support/concerns";

// ...Encryption concern not shown...

@use(Encryption)
class CookieStore {
    constructor() {
        const value = getContainer(this)
            .get(Encryption)
            .encrypt('Lorum lipsum');
        
        // ...remaining not shown...
    }
}
CONCERNS symbol, getContainer(), and getConcernsContainer()

There are 3 ways to obtain the concerns container instance:

A) CONCERNS symbol

Inside your target class, if you know that concerns are used (if target is a "concern owner"), then you can use the CONCERNS symbol to gain access to the container.

import { CONCERNS } from "@aedart/support/concerns";

// Inside your target class...
const container = this[CONCERNS];

B) getContainer()

getContainer() is essentially a just a wrapper for: return this[CONCERNS].

import { getContainer } from "@aedart/support/concerns";

// Inside your target class...
const container = getContainer(this);

C) getConcernsContainer()

The getConcernsContainer() achieves the same result as the previous shown methods. However, it does perform a check of the provided target instance, which ensures that it is a "concern owner". If the target does not pass this test, then a TypeError is thrown. This might can be useful in situations when you might now know if the target is a concern owner, e.g. when situated in a child class or outside a target class.

import { getConcernsContainer } from "@aedart/support/concerns";

// Inside your target class...
const container = getConcernsContainer(this);

Determine if target uses concerns

To determine if a target uses one or more concerns, use the usesConcerns() method. It accepts the following arguments:

  • instance: object|Owner - The target class instance.
  • ...concerns: ConcernConstructor[] - Concern classes to test for.
import {
    use,
    AbstractConcern,
    usesConcerns
} from "@aedart/support/concerns";

class A extends AbstractConcern {}
class B extends AbstractConcern {}
class C extends AbstractConcern {}

@use(
    A,
    B
)
class Game {}

const instance = new Game();

usesConcerns(instance, A); // true
usesConcerns(instance, B); // true
usesConcerns(instance, A, B); // true

usesConcerns(instance, C); // false
usesConcerns(instance, A, C); // false
usesConcerns(instance, B, C); // false
usesConcerns(instance, A, B, C); // false
Edit page
Last Updated:
Contributors: alin
Prev
Concern Class
Next
Aliases