AngularJS의 인기와 함께 JavaScript 분야에서도 종속성 주입이 많은 주목을 받기 시작했습니다. 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 프레임워크는 소프트웨어 장치의 수명 주기를 등록 단계와 실행 단계로 나눕니다. 위의 예에서 foo 및 bar 서비스는 등록 단계에서 제공되며 이러한 서비스는 런타임 단계에서 획득되어 사용됩니다. 대부분의 DI 프레임워크는 게으른 구성 전략을 채택하여 등록 단계에서 구성의 어려움을 방지합니다.
서비스 맞춤화는 등록 단계 이후 및 실행 단계 이전에 수행할 수 있습니다. AngularJS 1에는 이러한 서비스를 사용자 정의하기 위한 구성 단계가 도입되었으며 해당 공급자는 특수한 팩토리 객체로 이해될 수 있습니다. BottleJS는 데코레이터와 미들웨어를 사용하여 서비스 사용자 정의를 지원합니다.
IoC 컨테이너를 사용하여 서비스 인스턴스를 색인화하거나 서비스 제공자를 저장합니다. 누군가 서비스를 제공하면 컨테이너에 추가되고, 누군가 서비스를 사용하면 컨테이너에서 공급자를 찾아 서비스 인스턴스가 생성됩니다. 서비스 인스턴스를 캐시할 수 있는 경우가 많습니다.
먼저 서비스 생성자를 등록하는 데 사용되는 가장 일반적인 인터페이스 함수인 .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의 이러한 전략은 Provider에 의해 구현되고 다른 모든 서비스 등록 방법은 Provider에 의해 구현됩니다.
위 내용은 JavaScript 의존성 주입 구현 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!