129 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| extends ../../../ts/_cache/guide/dependency-injection.jade
 | |
| 
 | |
| block includes
 | |
|   include ../_util-fns
 | |
|   - var _thisDot = '';
 | |
| 
 | |
| block ctor-syntax
 | |
|   .l-sub-section
 | |
|     :marked
 | |
|       We also leveraged Dart's constructor syntax for declaring parameters and
 | |
|       initializing properties simultaneously.
 | |
| 
 | |
| block injectable-not-always-needed-in-ts
 | |
|   //- The [Angular 2 Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer)
 | |
|   //- generates static code to replace the use of dart:mirrors. It requires that types be
 | |
|   //- identified as targets for static code generation. Generally this is achieved
 | |
|   //- by marking the class as @Injectable (though there are other mechanisms).
 | |
| 
 | |
| block always-include-paren
 | |
|   :marked
 | |
|     Always write `@Injectable()`, not just `@Injectable`.
 | |
|     A metadata annotation must be either a reference to a
 | |
|     compile-time constant variable or a call to a constant
 | |
|     constructor such as `Injectable()`.
 | |
|     
 | |
|     If we forget the parentheses, the analyzer will complain:
 | |
|     "Annotation creation must have arguments". If we try to run the
 | |
|     app anyway, it won't work, and the console will say
 | |
|     "expression must be a compile-time constant".
 | |
| 
 | |
| block real-logger
 | |
|   .l-sub-section
 | |
|     :marked
 | |
|       A real implementation would probably use the
 | |
|       [logging package](https://pub.dartlang.org/packages/logging).
 | |
| 
 | |
| block provider-shorthand
 | |
|   :marked
 | |
|     This is actually a shorthand expression for a provider registration
 | |
|     that creates a new instance of the
 | |
|     [Provider](../api/angular2.core/Provider-class.html) class:
 | |
| 
 | |
| block provider-ctor-args
 | |
|   - var _secondParam = 'named parameter, such as <code>useClass</code>' 
 | |
|   :marked
 | |
|     We supply two arguments (or more) to the `Provider` constructor.
 | |
| 
 | |
| block dart-diff-const-metadata
 | |
|   .callout.is-helpful
 | |
|     header Dart difference: Constants in metadata
 | |
|     :marked
 | |
|       In Dart, the value of a metadata annotation must be a compile-time constant.
 | |
|       For that reason, we can't call functions to get values
 | |
|       to use within an annotation.
 | |
|       Instead, we use constant literals or constant constructors.
 | |
|       For example, a TypeScript program will use the
 | |
|       object literal `{ provide: Logger, useClass: BetterLogger }`.
 | |
|       A Dart annotation would instead use the constant value 
 | |
|       `const Provider(Logger, useClass: BetterLogger)`.
 | |
| 
 | |
| block dart-diff-const-metadata-ctor
 | |
|   .callout.is-helpful
 | |
|     header Dart difference: Constants in metadata
 | |
|     :marked
 | |
|       Because Dart annotations must be compile-time constants,
 | |
|       `useValue` is often used with string or list literals.
 | |
|       However, `useValue` works with any constant object.
 | |
| 
 | |
|       To create a class that can provide constant objects,
 | |
|       ensure all its instance variables are `final`,
 | |
|       and give it a `const` constructor.
 | |
|       
 | |
|       Create a constant instance of the class by using `const` instead of `new`.
 | |
| 
 | |
| // - var stylePattern = { otl: /(useValue.*\))/gm };
 | |
| // +makeExample('dependency-injection/dart/lib/providers_component.dart','providers-9','', stylePattern)(format='.')
 | |
| 
 | |
| block non-class-dep-eg
 | |
|   span string, list, map, or maybe a function.
 | |
| 
 | |
| block config-obj-maps
 | |
|   | . They can be 
 | |
|   | <b><a href="https://api.dartlang.org/stable/dart-core/Map-class.html">Map</a></b>
 | |
|   | literals
 | |
| 
 | |
| block what-should-we-use-as-token
 | |
|   :marked
 | |
|     But what should we use as the token? 
 | |
|     While we _could_ use **[Map][]**, we _should not_ because (like
 | |
|     `String`) `Map` is too general. Our app might depend on several maps, each
 | |
|     for a different purpose.
 | |
| 
 | |
|     [Map]: https://api.dartlang.org/stable/dart-core/Map-class.html
 | |
| 
 | |
|   .callout.is-helpful
 | |
|     header Dart difference: Interfaces are valid tokens
 | |
|     :marked
 | |
|       In TypeScript, interfaces don't work as provider tokens.
 | |
|       Dart doesn't have this limitation;
 | |
|       every class implicitly defines an interface,
 | |
|       so interface names are just class names.
 | |
|       `Map` is a *valid* token even though it's the name of an abstract class;
 | |
|       it's just *unsuitable* as a token because it's too general.
 | |
| 
 | |
| block dart-map-alternative
 | |
|   :marked
 | |
|     As an alternative to using a configuration `Map`, we can define
 | |
|     a custom configuration class:
 | |
| 
 | |
|   +makeExcerpt('lib/app_config.dart (alternative config)','config-alt')
 | |
| 
 | |
|   :marked
 | |
|     Defining a configuration class has a few benefits. One key benefit
 | |
|     is strong static checking: we'll be warned early if we misspell a property
 | |
|     name or assign it a value of the wrong type.
 | |
|     The Dart [cascade notation][cascade] (`..`) provides a convenient means of initializing
 | |
|     a configuration object. 
 | |
| 
 | |
|     If we use cascades, the configuration object can't be declared `const` and
 | |
|     we can't use a [value provider](#value-provider). 
 | |
|     A solution is to use a [factory provider](#factory-provider).
 | |
|     We illustrate this next. We also show how to provide and inject the
 | |
|     configuration object in our top-level `AppComponent`:
 | |
| 
 | |
|     [cascade]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#cascade
 | |
| 
 | |
|   +makeExcerpt('lib/app_component.dart','providers')
 | |
|   +makeExcerpt('lib/app_component.dart','ctor')
 |