2017-02-07 10 views
3

私はAureliaとDependency Injectionに精通しています。しかし、私はPacktpub.comの「Learning Aurelia」のDependency Injectionの章の次の行については理解していません。Aurelia Dependency Injectionの容器は何ですか

Aureliaでは、コンテナーは子コンテナーを作成することができます。子コンテナーはそれ自体で子を作成し、アプリケーションのルートコンテナーから始まるコンテナーのツリーを形成します。各子コンテナは親のサービスを継承しますが、親コンテナをオーバーライドするために独自のコンテナを登録できます。

私は本の中の例のようにDIを使用

import {PersonService} from 'app-services'; 
import {Person} from 'models'; 
import {autoinject} from 'aurelia-framework'; 

@autoinject 
export class PersonList { 

constructor(private personService: PersonService) { 
} 

getPeople(){ 
    return this.personService.getAll(); 
} 
} 

しかし、コンテナは、このに収まるのでしょうか?私はコードでコンテナを参照したことはありません。子コンテナは作成していません。それは、 "それぞれの子コンテナは、親のサービスを継承します。私は別々のビューとビューモデルである多くの子コンポーネントを持つコンポーネントを持っています。私はコンテナがどのようにそれに収まるか理解していません。ビューモデルが親のサービスにどのようにアクセスしますか?

何か不足していますか?

答えて

4

オーレリアは、それがのviewmodelsをインスタンス化するために使用する依存性注入コンテナの実装を持っており、フレームワークの一部または書き込まれたアプリケーションサービスの多く開発者によって。 Aureliaの慣習体系ではコンテナを使用してビューモデルとサービスを作成し、@inject@autoinjectはコンテナを手動で設定する必要がないため、コンテナを直接使用する必要はありません。

依存性注入コンテナとは何ですか?まあコンテナインジェクタのために別の単語です:

インジェクタは、クライアントへのサービスを紹介しています。多くの場合、クライアントも構築されます。インジェクタは、クライアントのようなオブジェクトを処理し、後で別のクライアントのためのサービスとして扱うことによって、非常に複雑なオブジェクトグラフを一緒に接続することができる。インジェクタは実際には多くのオブジェクトが一緒に働いているかもしれませんが、クライアントではないかもしれません。インジェクタは、アセンブラ、プロバイダ、コンテナ、工場、ビルダー、スプリング、建設コード、またはメインなどの他の名前で参照されてもよい。 - https://en.wikipedia.org/wiki/Dependency_injection

アウレリアのコンテナシステムは、あなた@injectまたは@autoinject何か、現在の(子)コンテナはアイテムが検索され、それが見つからない場合は、親コンテナが検索される時を意味し、階層化され、アイテムが見つかるまで、またはルートコンテナにヒットするまで続けます。この場合、Aureliaは要求されたアイテムの新しいインスタンスを作成します。あなたのコードで

はあなたが持っているスニペット:

import {PersonService} from 'app-services'; 
import {Person} from 'models'; 
import {autoinject} from 'aurelia-framework'; 

@autoinject 
export class PersonList { 

    constructor(private personService: PersonService) { 
    } 

    getPeople(){ 
    return this.personService.getAll(); 
    } 
} 

が、これは、あなたがこのように使用しているカスタム要素のビューモデルであると仮定すると:<person-list></person-list>、ここアウレリアはPersonListをインスタンス化する際に何が起こるかです。

  1. 子コンテナは現在のコンテナから作成されます(詳細については、後ほど「現在のコンテナ」を参照)。 container.createChildContainer()と同等です。この子コンテナを "childContainer"と呼びます。
  2. コンテキストアイテムは、PersonList用のviewmodelのDOM要素(ビュー)などの子コンテナに登録されます。これはchildContainer.registerInstance(Element, personListDomElement)を呼び出すのと同じです。どうして?これにより、開発者は@inject(Element)(または@autoinject相当)になります。子コンテナを設定すると
  3. PersonListのインスタンスを作成するために使用されます。呼び出しに相当:

    personList = childContainer.invoke(PersonList); 
    childContainer.registerInstance(PersonList, personList); 
    
  4. を、それが親コンテナですので、子コンテナがキー「PersonService」に登録されて何も持っていませんが、それが発見されるまで、検索されるか、見つけることができない、オーレリアが構築されます。その場合にはPersonServiceという新しいインスタンスを作成し、それをルートコンテナに登録して、その後のルックアップでインスタンスを再利用できるようにします。

  5. 者リストのviewmodelとビューがライフサイクルイベントが起こるなどのテンプレートエンジンと作成、バインド、接続、で構成されています。

ボーナス:以前の私は、子コンテナが現在のコンテナから作成されますを述べた...すべてオーレリア・アプリケーションは、直接的または間接的に、すべての子コンテナから下降「ルートレベル」のコンテナがあります。 BindingEngineObserverLocatorTaskQueueと、より多く:オーレリアのコアアプリケーションサービスは、ルートコンテナに登録されています。これは、開発者が@inject(TaskQueue)と記述し、Aureliaフレームワークが内部的に使用しているのと同じTaskQueueインスタンスを取得できるようにするものです。とにかく、カスタム要素またはカスタム属性がインスタンス化されると、カスタム要素またはカスタム属性を作成するために子コンテナが使用されます。そのカスタム要素に他のカスタム要素が含まれている場合、子コンテナは現在の子コンテナから作成され、子カスタム要素のインスタンス化などに使用されます。つまり、「現在のコンテナ」は、コンポーネントがネストされたカスタム要素とカスタム属性の階層にどの程度深いかによって異なります。

リンク:

2

通常、コンテナを直接参照する必要はありません。あなたのコンポーネント(ページ、カスタムelments、カスタム属性、バリューコンバータなど)をインスタンス化する必要があるとき、Aureliaはそれを処理します。

DIコンテナは、ファミリーツリーと考えることができます。他のすべてのコンテナが子であるアプリレベルのコンテナが1つあります。各コンポーネントには新しい子コンテナが作成されます。

コンテナに物事を処理する方法に関する情報を与えるために使用できるヘルパーがあります。 @autoinjectを使用してデフォルトの動作を取得しますが、より具体的にする必要がある場合は、@injectデコレータに切り替えて、@inject(Parent.of(Foo), Optional.of(Bar))などの処理を行うことができます。これにより、親コンテナに作成されたFooクラスのインスタンスが作成され、コンテナには「バーのインスタンスが必要ですが、作成できない場合はクールです」というインスタンスが表示されます。

親のVMにアクセスする必要がある場合は、Parent.of()を使用して子コンポーネントに取り込むことができます。親コンポーネントのVMの実装に子コンポーネントを直接関連付けるため、これを「注意して処理する」タイプのものの1つであることに注意してください。コンポーネントを内部で使用するとコンポーネントの作成に失敗する(場合によってはアプリケーションがクラッシュする可能性があります) VMクラスが異なるページ/コンポーネント。

詳細については、当社のドキュメントをチェックアウトしてください:http://aurelia.io/hub.html#/doc/article/aurelia/dependency-injection/latest/dependency-injection-basics

関連する問題