Saturday, June 23, 2018

I saw Chris Hardin speak on Dependency Injection in Angular 6 midday Wednesday at the St. Louis Angular Lunch.

Angular dependencies are listed in a declarative (solve a problem at a high level without specific instructions) manner in that they may be in one for three places in the "Injector Tree" and this fuzziness can lead to some behavior a noob would find unpredictable. The three:

  1. First, at the root of the tree is the root injector for the whole of the application. Injectors here are singletons and they get looped in at the outermost module. Once a service (anything injected, the items at the providers metadata property) is setup here its lifecycle will be the whole of the lifecycle of the application. The "root" way of doing things is the default way of doing things and the recommended way of doing things.
  2. Next, at the component level one may similarly have a service (at the providers metadata property) and these are available to that component and child components and have lifecycles tied to the component where they are looped in. Chris gave a rich text editor with a bunch of controls written in a parent-with-a-tree-of-children manner as a good use case for these. If the WYSIWYG editor needed to appear upon clicking in a textarea and then go away again to be refreshed anew when a different textarea is edited, then the lifecycle behavior herein is appropriate to that circumstance. Most of Chris' other experience with dependency injection is of the Java Spring framework and she said that the component level injection felt like what would be a prototype bean in that alternative universe. Alright, the important thing to know here is that when a component service has a conflict with seemingly the same service in a module that the component service wins. This is not the challenging, tricky part.
  3. Finally, services created at lazy loaded modules can "shadow" those created at root and allow you to accidentally get multiple instances of things and here is where the bad creeps in. Augury can even misreport the services from lazy loaded modules as if they are of root.

There is a new providedIn property in Angular 6 for injectors that may be used like this:

@Injectable({ providedIn: 'root' })


...and like this:

@Injectable({ providedIn: HeroModule })


...and that both complicates things and makes them simpler. The 'root' trick, when used with the lazy loading approach, will allow the service to be in the root code (the compiled code) at the dist folder, surviving treeshaking, but nonetheless not instantiated in scope until the lazy loading occurs. That gets rid of the dupes problem. The providedIn thing at the component level can yet stamp over the providedIn stuff of the dupes problem solving as just mentioned. Alright, it is now possible to have a circular reference in which HeroComponent is looped in at HeroModule which provides HeroService which "provides in" (forgive my hamminess) HeroComponent and to get around this you need to inject a middleman as a buffer so that HeroComponent is looped in at HeroModule which provides both MiddlemanService which sucks in HeroService which provides in HeroComponent and furthermore also HeroService which, of course, provides in HeroComponent. I think this is the fix. I haven't tried it firsthand and I was kind of distracted in scribbling other notes when Chris was talking. I am making some assumptions also in Googling against this stuff and finding this. Of course there is an old joke about the word assume. You may use this new syntax with injection tokens which I also haven't really gotten my head around. This seems to have some details. One has to have a class and not an interface for an injecton token and so if you need an "interface" you basically must use an abstract class instead in TypeScript and use the implements keyword instead of the extends keyword to get a class to implement the abstract class. I type this here not yet knowing what I'm talking about as I haven't worked with the injection tokens. Furthermore along the lines of things I don't really get yet, in routing concerns, root() is a way to pass configuration data to a module and forChild() restricts scope for lazy loading but otherwise is the same sort of thing. Chris Hardin, pictured sitting, works at Oasis Digital which does Angular training and this event sort of showed off their teaching tech chops. The last time I attended this group the venue was Oasis Digital itself, but this time it was a bit different. Oasis Digital is in one of a set of three office buildings and this Wednesday's locale was in a conference room in one of the other buildings that I suspect has a communal bowl grab-time-when-you-can thing going on. It's by the Gallagher Bassett office space. The two times now that I've been to this meetup a Kyle Cordes has been the moderator. Kyle is pictured in the Tommy Bahama Hawaiian shirt. I know it's Tommy Bahama because I bought that exact same shirt online myself. The pattern is dubbed "San Juan Fronds" and... anyways...

No comments:

Post a Comment