Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the basic concepts in Angular dependency injection system

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "what are the basic concepts in the Angular dependency injection system". In the daily operation, I believe that many people have doubts about the basic concepts in the Angular dependency injection system. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "what are the basic concepts in the Angular dependency injection system?" Next, please follow the editor to study!

Dependency injection

Now that we are going to introduce the dependency injection design of the Angular framework, let's lay the groundwork for the basic concepts of dependency injection. We often confuse the concepts of dependency inversion principle (DIP), inversion of Control (IoC), and dependency injection (DI), so let's start with a brief introduction.

Dependency inversion principle, control inversion, dependency injection

Low coupling and high cohesion is probably one of the design goals of every system, and a lot of design patterns and ideas have been produced, including the design idea of relying on inversion principle and control inversion.

(1) rely on the principle of inversion (DIP).

The original definition of the principle of dependency inversion is:

High-level modules should not rely on lower-level modules, both should rely on their abstraction

Abstraction should not rely on details, details should rely on abstractions.

To put it simply: modules should not directly rely on each other, should rely on an abstract rule (interface or time abstract class).

(2) inversion of control (IoC).

The definition of control inversion is that the dependency between modules is instantiated from the inside of the program to the outside of the program. That is, when an object is created, it is controlled by an external entity that regulates all objects in the system and passes (injects) the references of the objects it depends on.

There are two main ways to achieve control inversion:

Dependency injection: passively receiving dependent objects

Dependency search: take the initiative to ask for dependent objects

(3) dependency injection.

Dependency injection is one of the most common techniques for control inversion.

Dependency inversion and control inversion complement each other and can often be used together to effectively reduce the coupling between modules.

Dependency injection in Angular

In Angular, dependency injection is also used, and the DI framework instantiates a class by providing it with the dependencies declared by that class (dependencies: services or objects that are required when the class needs to perform its functions).

Dependency injection in Angular basically revolves around components or modules and is mainly used to provide dependencies for newly created components.

The main dependency injection mechanism in Angular is the injector mechanism:

Any dependencies required in the application must use the application's injector to register a provider so that the injector can use this provider to create a new instance

Angular creates a full application-level injector and other injectors as needed during startup

There are two main concepts involved, namely the Injector injector and the Provider provider. Let's take a look.

Injector injector

The Injector injector is used to create dependencies and maintains a container to manage these dependencies and reuse them as much as possible. The injector provides a singleton of dependencies and injects the singleton object into multiple components.

Obviously, as a container for creating, managing, and maintaining dependencies, the function of the injector is simple: create dependency instances, obtain dependency instances, and manage dependency instances. We can also see it in the source code of the abstract class Injector:

Export abstract class Injector {/ / cannot find dependency static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND; / / NullInjector is the top of the tree / / if you go so far up the tree that you want to look for services in NullInjector, you will receive an error message, or for @ Optional (), return null static NULL: Injector = new NullInjector () / / retrieve the instance abstract get (token: Type | AbstractType | InjectionToken, notFoundValue?: T, flags?: InjectFlags) from Injector according to the provided Token: t; / / create a new Injector instance that provides one or more dependencies static create (options: {providers: StaticProvider []; parent?: Injector; name?: string;}): Injector / the subscription defineInjectable is used to construct an InjectableDef / / it defines how the Token will be constructed by the DI system, and in which Injector static is available: token: Injector, providedIn: "any" as any, / / instructions generated by the inject: inject Token factory from the currently active Injector: () = > currently active inject (INJECTOR),}); static _ _ NG_ELEMENT_ID__ = InjectorMarkers.Injector;}

That is, we can add the dependent instances that need to be shared to the injector, and obtain the corresponding dependent instances by querying and retrieving the injector through Token.

It is important to note that the injector in Angular is hierarchical, so the process of finding dependencies is also the process of walking up the injector tree.

This is because in Angular, applications are organized as modules, which can be found in 5. 5. Modular organization. Generally speaking, the DOM of the page is a tree structure with html as the root node, on this basis, the components and modules in Angular applications are also accompanied by the tree structure.

While the injector serves components and modules, it is also a tree structure of mounting and module and organization. Therefore, Injector is also divided into module and component levels, which can provide specific instances of dependencies for components and modules, respectively. The injector is inheritable, which means that if the specified injector cannot resolve a dependency, it requests the parent injector to resolve it, as we can see in the code to create the injector above:

/ / create a new Injector instance. Pass parent parent injector static create (options: {providers: StaticProvider [], parent?: Injector, name?: string}): Injector

Within the scope of an injector, the service is singleton. That is, there is at most one instance of a service in the specified injector. If you do not want to use the same instance of the service everywhere, you can share instances of a service dependency on demand by registering multiple injectors and associating them to components and modules as needed.

We can see that when you create a new Injector instance, the parameter passed in includes Provider, because Injector does not create dependencies directly, but through Provider. Each injector maintains a list of providers and uses them to provide instances of services based on the needs of components or other services.

Provider provider

The Provider provider is used to tell the injector how to acquire or create dependencies, and for the injector to be able to create services (or provide other types of dependencies), the injector must be configured with a provider.

A provider object defines how to obtain injectable dependencies associated with a DI token (token), and the injector uses this provider to create instances of those classes it depends on.

About DI tokens:

When the injector is configured using the provider, the provider is associated with a DI token

The injector maintains an internal token-provider mapping table, which is referenced when a dependency is requested, and the token is the key to this mapping table.

There are many types of providers, and their specific definitions can be read in the official documentation:

Export type Provider = | TypeProvider | ValueProvider | ClassProvider | ConstructorProvider | ExistingProvider | FactoryProvider | any []

The parsing process for the provider is as follows:

Function resolveReflectiveFactory (provider: NormalizedProvider): ResolvedReflectiveFactory {let factoryFn: Function; let resolvedDeps: ReflectiveDependency []; if (provider.useClass) {/ / use classes to provide dependencies const useClass = resolveForwardRef (provider.useClass); factoryFn = reflector.factory (useClass); resolvedDeps = _ dependenciesFor (useClass);} else if (provider.useExisting) {/ / use existing dependencies factoryFn = (aliasInstance: any) = > aliasInstance / / get specific dependency resolvedDeps from token = [ReflectiveDependency.fromKey (ReflectiveKey.get (provider.useExisting)),];} else if (provider.useFactory) {/ / use factory method to provide dependency factoryFn = provider.useFactory; resolvedDeps = constructDependencies (provider.useFactory, provider.deps);} else {/ / use provider specific value as dependency factoryFn = () = > provider.useValue ResolvedDeps = _ EMPTY_LIST;} / / return new ResolvedReflectiveFactory (factoryFn, resolvedDeps);}

Depending on the type of provider, after parsing, you get the internal parsed representation of the provider used by the injector Injector:

Export interface ResolvedReflectiveProvider {/ / keys, including system-wide unique id, and a token key: ReflectiveKey; / / factory function that returns an instance of the object represented by the key resolvedFactories: ResolvedReflectiveFactory []; / / indicates whether the provider is a multiple provider or a regular provider multiProvider: boolean;}

The provider can be the service class ClassProvider itself, and if the service class is specified as the provider token, the default behavior of the injector is to instantiate that class with new.

Dependency injection Service in Angular

In Angular, a service is a class with an @ Injectable decorator that encapsulates non-UI logic and code that can be reused in an application. Angular separates components from services to improve modularity and reusability.

Mark a class with @ Injectable to ensure that the compiler will generate the necessary metadata (which is also an important part of Angular) when the class is injected to create dependencies for the class.

The class of the @ Injectable decorator will, after compilation, get the Angular injectable object:

/ / compile Angular injectable objects according to its Injectable metadata, and patch the results export function compileInjectable (type: Type, srcMeta?: Injectable): void {/ / the compilation process depends on @ angular/compiler / / refer to the compileFactoryFunction compileInjectable implementation in the compiler}

Injectable objects (InjectableDef) in Angular define how the DI system will construct token tokens and which injectors, if any, are available:

Export interface injector InjectableDef {/ / specifies that a given type belongs to a specific injector, including root/platform/any/null and a specific NgModule providedIn: InjectorType | "root" | "platform" | "any" | null; / / token to which this definition belongs: token: unknown; / / the factory method to be executed to create an injectable instance factory: (Type: Type) = > T / / in the absence of an explicit injector, store the location of the injectable instance value: t | undefined;}

When using the providedIn of @ Injectable (), the optimization tool can do Tree-shaking optimization to remove unused services from the application to reduce the bundle size.

At this point, the study of "what are the basic concepts in the Angular dependency injection system" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report