ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript 依存関係注入の実装

JavaScript 依存関係注入の実装

黄舟
黄舟オリジナル
2017-02-21 11:53:181776ブラウズ



AngularJS の人気に伴い、JavaScript 分野では依存関係注入が大きな注目を集め始めています。 DI の最も顕著な利点は、再利用可能でテスト可能なコード ユニットの開発です。 この記事では、簡単なコードを使用して DI の実装メカニズムを説明します。DI の長所と短所について詳しくは、「依存性注入をいつ使用する必要がありますか?」を参照してください。

基本的な DI の使用例

各モジュールは独自の依存関係を宣言し、独自のサービスを提供します。例:

di.service('foo', ['bar'], function foo(bar){ function Foo(){ this.bar = bar;
    } this.prototype.greeting = function(){ console.log('hello, world');
    } return Foo;
}); var foo = di.container.get('foo');
foo.greeting();

依存関係注入と CommonJS (または AMD) の違いに注意してください。foo は依存関係バーを積極的に取得せずに宣言するだけで済みます。 これにより、関数 foo は依存関係の場所と構築方法を完全に認識しなくなり、関数 foo がテスト可能で再利用可能なコード単位になります。

DIフレームワークの設計

サービスの登録とサービスの使用は、別のタイミングで行う必要があります。 特別な依存関係解決ツールとして、DI フレームワークはソフトウェア ユニットのライフ サイクルを登録フェーズと実行フェーズに分割します。 上記の例では、foo サービスと bar サービスが登録フェーズで提供され、これらのサービスは実行フェーズで取得および使用されます。 ほとんどの DI フレームワークは遅延構築戦略を採用しており、これにより登録フェーズでの構築の困難さも回避されます。

サービスのカスタマイズは、登録フェーズの後、運用フェーズの前に行うことができます。 AngularJS 1 では、これらのサービスをカスタマイズするための構成フェーズが導入されており、そのプロバイダーは特殊なファクトリ オブジェクトとして理解できます。 BottleJS は、デコレーターとミドルウェアを使用してサービスのカスタマイズをサポートします。

IoC コンテナを使用して、サービス インスタンスのインデックスを作成したり、サービス プロバイダーを保存したりします。 誰かがサービスを提供すると、そのサービスがコンテナに追加され、誰かがサービスを使用すると、コンテナからプロバイダが検索され、サービス インスタンスが生成されます。 多くの場合、サービス インスタンスはキャッシュできます。

DI フレームワークの実装

まず、サービスのコンストラクターを登録するために使用される、最も一般的なインターフェイス関数 .service() を実装します。 渡された関数は新たに操作されます。

var di = {
    container: {}
};

di.service = function(name, Constructor) {
    defineLazyProperty(name, () => new Constructor());
}; function defineLazyProperty(name, getter){ Object.defineProperty(di.container, name, {
        configurable: true,
        get: function() { var obj = getter(container); Object.defineProperty(di.container, name, {
                configurable: false value: obj
            }); return obj;
        }
    });
}

Object.defineProperty はここでサービスのキャッシュに使用されます。 コンストラクターはサービスが初めて構築されるときにのみ呼び出され、その後のアクセスでは IoC コンテナーのプロパティが直接読み取られます。 ES5の標準方式であり、互換性が非常に良いです。 defineLazyProperty() メソッドを使用すると、これらの一般的に使用される登録インターフェイスの実装が非常に直感的になります:

di.factory = function(name, factory) { return defineLazyProperty(name, factory);
};

di.provider = function(name, Provider) { return defineLazyProperty(name, function(){ var provider = new Provider(); return provider.$get();
    });
};

di.value = function(name, val) { return defineLazyProperty(name, () => val);
};

サービスのカスタマイズされたインターフェイスについては詳しく説明しません。統合されたサービスのカスタマイズには統合されたサービス構築メソッドが必要であることに言及する価値があります。直接ではなく、 .defineLazyProperty() を呼び出してプロパティを生成します。 AngularJS のこれらの戦略はプロバイダーによって実装され、他のすべてのサービス登録メソッドはプロバイダーによって実装されます。

上記は JavaScript 依存関係注入の実装の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。