In config/environment.js:
// config/environment.js
'use strict';
/*
 * Mostly this is the stock module config.
 */
const moduleConfiguration = {
  types: {
    application: { definitiveCollection: 'main' },
    component: { definitiveCollection: 'components' },
    'component-test': { unresolvable: true },
    helper: { definitiveCollection: 'components' },
    'helper-test': { unresolvable: true },
    renderer: { definitiveCollection: 'main' },
    template: { definitiveCollection: 'components' },
    /*
     * Add service as a type.
     */
    service: { definitiveCollection: 'services' }
  },
  collections: {
    main: {
      types: ['application', 'renderer']
    },
    components: {
      group: 'ui',
      types: ['component', 'component-test', 'template', 'helper', 'helper-test'],
      defaultType: 'component',
      privateCollections: ['utils']
    },
    styles: {
      group: 'ui',
      unresolvable: true
    },
    utils: {
      unresolvable: true
    },
    /*
     * Add services as a collection.
     */
    services: {
      types: ['service'],
      defaultType: 'service',
      privateCollections: ['utils']
    }
  }
};
module.exports = function(environment) {
  let ENV = {
    modulePrefix: 'bodega-glimmer',
    environment: environment,
    /*
     * Pass the module config here.
     */
    moduleConfiguration
  };
  return ENV;
};// src/ui/components/apple-pay-button/component.ts
import Online from '../../../services/online';
import Component, { tracked } from '@glimmer/component';
import trackService from '../../../utils/tracked';
/*
 * Use `trackService` to both inject the dependency and
 * allow it to dirty the property.
 */
@trackService('online')
export default class ApplePayButton extends Component {
  /*
   * Define the property and type.
   */
  online: Online;
  /*
   * Track the service like any other property.
   */
  @tracked('online', 'args')
  get isDisabled() {
    return !this.online.isOnline || this.args.disabled;
  }
};// src/ui/services/apple-pay.ts
import Service from './-utils/service';
import { tracked } from '@glimmer/component';
export default class ApplePay extends Service {
  /*
   * If you use this property in a template, ala `{{applePay.tracked}}`,
   * you will want to `@tracked` it. However you don't need this for
   * dirtying the service where it is injected.
   */
  @tracked isAvailable = false;
  constructor(options) {
    super(options);
    if (self.Stripe && self.Stripe.applePay) {
      self.Stripe.applePay.checkAvailability((result) => {
        /*
         * Set the property like normal.
         */
        this.isAvailable = result;
        
        /*
         * This dirties all properties where this service is injected.
         */
        this.notify();
      });
    }
  }
}
Note for consumers of this code, when creating derived properties, you should (and can only) state the service its self as a dependency. Declaring dependencies on properties within the service (i.e.,
@tracked('applePay.isAvailable')) will not work the wayEmber.computeddoes.Also, for those interested in injecting multiple services without making their inheritance chain longer with each injection, here's a class decorator that'll allow use like this