これは少し長いかもしれませんが、わずかな設計上の障壁にぶつかりました。
手始めに、依存性注入ではなく、サービス ロケーターに特化した IoC (制御の反転) を作成しました。(また、これは node.js で動作する coffee-script で書かれており、ハーモニー プロキシが有効になっています)
コンテナはかなり簡単です。コンテナー オブジェクトの新しいインスタンスを作成し、その変数をグローバルまたはローカルに格納します。
Context = require('ettore').Context
AppContext = new Context()
App = AppContext.create 'App'
この場合、サブコンテキストを管理するコンテキスト オブジェクトも実装しました (ただし、おそらくそれを削除します)。
コンテナ内に情報を保存するには、次を使用します。
App.set 'Namespace.Controller.Action', 'Value goes here'
App.set 'Namespace.Controller.Action.Index', 'Value goes here x2'
これは完全に機能し、依存関係の解決も同様に簡単です (非同期アプローチを使用することもできます)。
App.resolve 'Namespace.Controller.Action' # 'Value goes here'
App.get 'Namespace.Controller.Action' # 'Value goes here'
これは優れたシステムですが、ボイラープレート コードが必要であり、「舞台裏」ではなく、前もって IoC コンテナーを通過する必要があります。そこで、前のコードを次のように機能させるエイリアス システムの実装を開始しました。
NM = App.alias "Namespace"
NM.Controller.Action # 'Value goes here'
これは、V8 エンジンが提供する調和プロキシを使用して動作します (ライブラリの使用へのフォールバックあり)。
問題
問題は単純ですが、同時に複雑でもあります (考えすぎない限り...)。前のセットの例でも、2 つのコンポーネントがあります。
Namespace.Controller.Action Namespace.Controller.Action.Index
私のシステムは最初の例で問題なく動作し、解決された依存関係が見つかった場合はそれを返します。そうしないと、エラーが発生するか、false が返されます。問題は、依存関係または別のプロキシ オブジェクトを返す必要があるかどうかを知ることで発生します。
これを明確にするために:
システムはプロキシを介してオブジェクトごとに移動し、(通常) 同じプロキシ オブジェクトを返します。これにより、長い名前空間または選択した命名スキームを使用できます。次のステートメントを呼び出す場合:
Namespace.Controller.Action
システムを 2 回通過します。1 つはコントローラー用で、もう 1 つはアクション用です。問題は、現在のオブジェクトに別のオブジェクトが接続されているかどうかが正直にわからないことです。(例: Action の後に .Index を呼び出していますか?)
今、私はあまり良くない一種のプロミス システムを実装しました。現在の「ループ」について、完全修飾名に依存関係が存在するかどうかを確認します。その場合、通常のプロキシとは別に「then」というミキシング メソッドを追加します。
したがって、次の名前空間がある場合:
Namespace.Controller.Action
Namespace.Controller.Action.Index
「Namespace.Controller.Action」コンポーネントのコンテンツにアクセスするには、名前付けに「競合」があるため、promise を使用する必要があります。
Namespace.Controller.Action.then ->
@get # 'Value goes here'
Namespace.Controller.Action.Index # 'Value goes here x2'
質問
この問題を達成または修正するためのより良い方法はありますか? 時間の経過とともに近づいていますが、すべてが少しハッキリしているように見えることがあります。
ソース コード 当然のことながら、ソース コード全体は非常に長いので、ここには掲載しませんでした。エイリアシングとコンテナーのメイン コードは、https ://github.com/TheHydroImpulse/Ettore/blob/master/lib/Container.coffee にあります。
ここで同じ原則 (エイリアシング) を使用するサンプル ファイルが見つかります: https://github.com/TheHydroImpulse/Ettore/blob/master/examples/alias.coffee
注: もっと詳しく説明する必要がある場合は、お知らせください... 説明するのはちょっと変わった問題です。