Bağımlılık Enjeksiyonu

Yaşam Süreleri ve Kapsamlar

singleton, scoped ve transient; gezinme kapsamı ve scoped handle'lar.

Yaşam süreleri (lifetimes)

Yaşam süresi Davranış
singleton Uygulama boyunca tek örnek.
scoped Gezinme başına bir örnek. Aynı gezinmede ekranda olan her şey (layout, sayfa, alt bileşenler, FromService, singleton bağımlılıkları) aynı örneği görür; ayrıntı aşağıda. Router yoksa kök sağlayıcıda tek örnektir.
transient Her çözümlemede yeni örnek (varsayılan).

Yaşam süresi kayıtta verilir (addSingleton / addScoped / addTransient ya da @Injectable({ lifetime }), bkz. Servis Kaydı). Bir rota bileşeninin kendisi DI'da kayıtlıysa kaydın yaşam süresi sayfanın ömrünü belirler (bkz. Rota bileşeninin kurulması).

scoped: gezinme başına tek örnek

Router her gezinmede bir kapsam açar. scoped bir servisi isteyen herkes (getService, inject, deps, FromService) servisin kendisini değil, o servise giden bir handle alır. Handle servis gibi kullanılır (alanlar, metotlar, #private alanlar, instanceof) ve her erişimde doğru gezinmenin örneğine gider. Örnekte layout ile sayfa aynı scoped seçimi kullanır:

import { Injectable, reactive } from "@motifx/core";

@Injectable({ lifetime: "scoped" })
export class Selection {
  ids = reactive<number[]>([]);

  toggle(id: number) {
    const i = this.ids.indexOf(id);
    if (i < 0) this.ids.push(id);
    else this.ids.splice(i, 1);
  }
}
import { Injectable, reactive } from "@motifx/core";

@Injectable({ lifetime: "scoped" })
export class Selection {
  ids = reactive([]);

  toggle(id) {
    const i = this.ids.indexOf(id);
    if (i < 0) this.ids.push(id);
    else this.ids.splice(i, 1);
  }
}

Layout'taki sayaç ve not sayfasındaki düğme aynı servisi ister:

import { Component } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export class SelectedCount extends Component {
  selection = this.getService(Selection)!;

  override view() {
    return <span class="badge">{() => `${this.selection.ids.length} seçili`}</span>;
  }
}

export class SelectButton extends Component<any, { note: Note }> {
  selection = this.getService(Selection)!;

  override view() {
    const { note } = this.props;
    return (
      <button type="button" class="button--sm ghost" onclick={() => this.selection.toggle(note.id)}>
        Seç
      </button>
    );
  }
}
import { Component, ComponentBase, motifComponent } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export class SelectedCount extends Component {
  selection = this.getService(Selection)!;

  override view() {
    return motifComponent("span", (span: ComponentBase) => {
      span.class.add("badge");
      span.bindings.text(() => `${this.selection.ids.length} seçili`);
    });
  }
}

export class SelectButton extends Component<any, { note: Note }> {
  selection = this.getService(Selection)!;

  override view() {
    const { note } = this.props;
    return motifComponent("button", (button: ComponentBase) => {
      button.attr.add({ type: "button" });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => this.selection.toggle(note.id));
      button.setText("Seç");
    });
  }
}
import { FromService } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export function SelectedCount() {
  const selection = FromService(Selection)!;

  return <span class="badge">{() => `${selection.ids.length} seçili`}</span>;
}

export function SelectButton(props: { note: Note }) {
  const selection = FromService(Selection)!;
  const { note } = props;

  return (
    <button type="button" class="button--sm ghost" onclick={() => selection.toggle(note.id)}>
      Seç
    </button>
  );
}
import { ComponentBase, FromService, motifComponent } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export function SelectedCount() {
  const selection = FromService(Selection)!;

  return motifComponent("span", (span: ComponentBase) => {
    span.class.add("badge");
    span.bindings.text(() => `${selection.ids.length} seçili`);
  });
}

export function SelectButton(props: { note: Note }) {
  const selection = FromService(Selection)!;
  const { note } = props;

  return motifComponent("button", (button: ComponentBase) => {
    button.attr.add({ type: "button" });
    button.class.add("button--sm ghost");
    button.motif.on("click", () => selection.toggle(note.id));
    button.setText("Seç");
  });
}
import { motifOptions } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export const SelectedCount = () => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection)!;
    return <span class="badge">{() => `${selection.ids.length} seçili`}</span>;
  },
});

export const SelectButton = (props: { note: Note }) => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection)!;
    const { note } = props;
    return (
      <button type="button" class="button--sm ghost" onclick={() => selection.toggle(note.id)}>
        Seç
      </button>
    );
  },
});
import { ComponentBase, motifComponent, motifOptions } from "@motifx/core";
import { Selection } from "../services/selection";
import type { Note } from "../services/notes";

export const SelectedCount = () => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection)!;
    return motifComponent("span", (span: ComponentBase) => {
      span.class.add("badge");
      span.bindings.text(() => `${selection.ids.length} seçili`);
    });
  },
});

export const SelectButton = (props: { note: Note }) => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection)!;
    const { note } = props;
    return motifComponent("button", (button: ComponentBase) => {
      button.attr.add({ type: "button" });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => selection.toggle(note.id));
      button.setText("Seç");
    });
  },
});
import { Component } from "@motifx/core";
import { Selection } from "../services/selection";

export class SelectedCount extends Component {
  selection = this.getService(Selection);

  view() {
    return <span class="badge">{() => `${this.selection.ids.length} seçili`}</span>;
  }
}

export class SelectButton extends Component {
  selection = this.getService(Selection);

  view() {
    const { note } = this.props;
    return (
      <button type="button" class="button--sm ghost" onclick={() => this.selection.toggle(note.id)}>
        Seç
      </button>
    );
  }
}
import { Component, motifComponent } from "@motifx/core";
import { Selection } from "../services/selection";

export class SelectedCount extends Component {
  selection = this.getService(Selection);

  view() {
    return motifComponent("span", (span) => {
      span.class.add("badge");
      span.bindings.text(() => `${this.selection.ids.length} seçili`);
    });
  }
}

export class SelectButton extends Component {
  selection = this.getService(Selection);

  view() {
    const { note } = this.props;
    return motifComponent("button", (button) => {
      button.attr.add({ type: "button" });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => this.selection.toggle(note.id));
      button.setText("Seç");
    });
  }
}
import { FromService } from "@motifx/core";
import { Selection } from "../services/selection";

export function SelectedCount() {
  const selection = FromService(Selection);

  return <span class="badge">{() => `${selection.ids.length} seçili`}</span>;
}

export function SelectButton(props) {
  const selection = FromService(Selection);
  const { note } = props;

  return (
    <button type="button" class="button--sm ghost" onclick={() => selection.toggle(note.id)}>
      Seç
    </button>
  );
}
import { FromService, motifComponent } from "@motifx/core";
import { Selection } from "../services/selection";

export function SelectedCount() {
  const selection = FromService(Selection);

  return motifComponent("span", (span) => {
    span.class.add("badge");
    span.bindings.text(() => `${selection.ids.length} seçili`);
  });
}

export function SelectButton(props) {
  const selection = FromService(Selection);
  const { note } = props;

  return motifComponent("button", (button) => {
    button.attr.add({ type: "button" });
    button.class.add("button--sm ghost");
    button.motif.on("click", () => selection.toggle(note.id));
    button.setText("Seç");
  });
}
import { motifOptions } from "@motifx/core";
import { Selection } from "../services/selection";

export const SelectedCount = () => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection);
    return <span class="badge">{() => `${selection.ids.length} seçili`}</span>;
  },
});

export const SelectButton = (props) => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection);
    const { note } = props;
    return (
      <button type="button" class="button--sm ghost" onclick={() => selection.toggle(note.id)}>
        Seç
      </button>
    );
  },
});
import { motifComponent, motifOptions } from "@motifx/core";
import { Selection } from "../services/selection";

export const SelectedCount = () => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection);
    return motifComponent("span", (span) => {
      span.class.add("badge");
      span.bindings.text(() => `${selection.ids.length} seçili`);
    });
  },
});

export const SelectButton = (props) => motifOptions({
  el: null,

  view() {
    const selection = this.getService(Selection);
    const { note } = props;
    return motifComponent("button", (button) => {
      button.attr.add({ type: "button" });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => selection.toggle(note.id));
      button.setText("Seç");
    });
  },
});

Layout sayacı <SelectedCount />, not sayfası düğmeyi <SelectButton note={note} /> ile yerleştirir.

Layout sayacı new SelectedCount(), not sayfası düğmeyi new SelectButton({ note }) ile yerleştirir.

Layout sayacı motifComponent(SelectedCount), not sayfası düğmeyi motifComponent(SelectButton, { note }) ile yerleştirir.

Serbest bırakılan bir bileşenin alanları temizlendiği için, uzun süren bir işte bileşenin isDisposed alanını kontrol etmek yine iyi bir alışkanlıktır.

Sonraki adım

Servislerin nereden ve nasıl alındığını öğrenmek için Servis Çözümleme bölümüne geçin.