Application dependency injection method, system and device, electronic equipment and storage medium
By introducing application dependency injection methods and frameworks in mobile applications, the problem of high coupling between modules during business iteration is solved, decoupling and dependency injection between components is realized, and maintainability and scalability of the system is improved.
Patent Information
- Application Number
- CN202510142594.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-02-08
- Publication Date
- 2025-05-16
AI Technical Summary
During the business iteration of mobile applications, the coupling relationship between various business module components gradually intensifies, resulting in an increase in maintenance and iteration costs. Especially in the lack of dependency injection technology in Hongmeng mobile applications, it is difficult to reduce the coupling between modules.
Provides an application dependency injection method and framework, which can determine the dependency provision component by receiving dependency call requests from dependent requirements components, generate dependency injection instances, and return it to dependent requirements components, realize decoupling and dependency injection between components.
It reduces the coupling between modules, improves the maintainability and scalability of the system, simplifies dependency management, reduces the complexity of manual coding, and improves development efficiency and system operation efficiency.
Smart Images

Figure CN120010819A_ABST
Abstract
Description
Technical Field
[0001] The present disclosure relates to the field of computer technology, and in particular to the fields of mobile applications (Application, APP), software development, etc., and can be used in application scenarios such as mobile application product business iteration, and specifically relates to application dependency injection methods, systems, devices, electronic devices and storage media. Background Art
[0002] During the business iteration process of application products, as time goes by and the business grows, the coupling relationship between the components of each business module will gradually intensify, leading to increased maintenance and iteration costs. Summary of the invention
[0003] The present disclosure provides an application dependency injection method, system, device, electronic device and storage medium.
[0004] According to a first aspect of the present disclosure, a method for application dependency injection is provided, comprising: receiving a dependency call request of a dependency requirement component; determining a dependency provider component according to the dependency call request and a known dependency provider mapping relationship; generating a dependency injection instance based on the dependency provider component; and returning the dependency injection instance to the dependency requirement component.
[0005] According to a second aspect of the present disclosure, an application dependency injection framework is provided, including: a coding construction unit, used to define multiple decorators and use multiple decorators to mark dependency requirement components and dependency provider components; a first compilation unit, used to construct a provider component mapping relationship; a second compilation unit, used to generate a dependency provider mapping relationship based on the provider component mapping relationship; and a running loading unit, used to dynamically generate dependency instances and perform dependency injection.
[0006] According to a third aspect of the present disclosure, an application dependency injection device is provided, including: a request receiving module, used to receive a dependency call request of a dependency requirement component; a mapping parsing module, used to determine a dependency providing component according to the dependency call request and a known dependency providing mapping relationship; an instance generating module, used to generate a dependency injection instance based on the dependency providing component; and an instance returning module, used to return the dependency injection instance to the dependency requirement component.
[0007] According to a fourth aspect of the present disclosure, an electronic device is provided, comprising: at least one processor; and a memory communicatively connected to the at least one processor; wherein the memory stores instructions executable by the at least one processor, and the instructions are executed by the at least one processor so that the at least one processor can execute any method in the embodiments of the present disclosure.
[0008] According to a fifth aspect of the present disclosure, a non-transitory computer-readable storage medium storing computer instructions is provided, wherein the computer instructions are used to cause the computer to execute any method according to the embodiments of the present disclosure.
[0009] According to a sixth aspect of the present disclosure, a computer program product is provided, comprising a computer program, which implements any method according to the embodiments of the present disclosure when executed by a processor.
[0010] The solution disclosed in the present invention can reduce the coupling degree between modules and facilitate the maintenance and expansion of applications.
[0011] It should be understood that the content described in this section is not intended to identify the key or important features of the embodiments of the present disclosure, nor is it intended to limit the scope of the present disclosure. Other features of the present disclosure will become easily understood through the following description. BRIEF DESCRIPTION OF THE DRAWINGS
[0012] The accompanying drawings are used to better understand the present solution and do not constitute a limitation of the present disclosure.
[0013] Figure 1 is a schematic diagram of the structure of an application dependency injection framework according to an embodiment of the present disclosure;
[0014] Figure 2 is another structural diagram of an application dependency injection framework according to an embodiment of the present disclosure;
[0015] Figure 3 is an application schematic diagram of an application dependency injection framework according to an embodiment of the present disclosure;
[0016] Figure 4 is a flowchart of an application dependency injection method according to an embodiment of the present disclosure;
[0017] Figure 5 is a schematic diagram of the working principle of a decorator according to an embodiment of the present disclosure;
[0018] Figure 6 is a flow chart of the second compilation stage according to an embodiment of the present disclosure;
[0019] Figure 7 is a schematic diagram of a process of obtaining an instance of a dependency requirement component according to an embodiment of the present disclosure;
[0020] Figure 8 is a structural diagram of an application dependency injection device according to an embodiment of the present disclosure;
[0021] Fig. 9 It is a structural diagram of an electronic device used to implement the application dependency injection method of the embodiment of the present disclosure. DETAILED DESCRIPTION
[0022] The following is a description of exemplary embodiments of the present disclosure in conjunction with the accompanying drawings, including various details of the embodiments of the present disclosure to facilitate understanding, which should be considered as merely exemplary. Therefore, it should be recognized by those of ordinary skill in the art that various changes and modifications may be made to the embodiments described herein without departing from the scope of the present disclosure. Similarly, for the sake of clarity and conciseness, the description of well-known functions and structures is omitted in the following description.
[0023] The term "and / or" in this article is only a description of the association relationship of associated objects, indicating that there may be three relationships. For example, E and / or F can mean: E exists alone, E and F exist at the same time, and F exists alone. The term "at least one" in this article means any combination of at least two of any one or more of a plurality of. For example, including at least one of E, F, and G can mean including any one or more elements selected from the set consisting of E, F and G. The terms "first" and "second" in this article refer to multiple similar technical terms and distinguish them. They do not mean to limit the order or to limit them to only two. For example, the first feature and the second feature refer to two types / two features. The first feature can be one or more, and the second feature can also be one or more.
[0024] In addition, in order to better illustrate the present disclosure, numerous specific details are given in the following specific embodiments. It should be understood by those skilled in the art that the present disclosure can also be implemented without certain specific details. In some examples, methods, means, components and circuits well known to those skilled in the art are not described in detail in order to highlight the subject matter of the present disclosure.
[0025] Before introducing the technical solutions of the embodiments of the present disclosure, the technical terms that may be used in the present disclosure are further explained:
[0026] Dependency injection: is a design pattern that achieves inversion of control by dynamically injecting the dependencies of an object by an external container or framework, rather than creating or managing the object itself. Its core purpose is to decouple the dependencies between components and improve the maintainability, testability and scalability of the code. Dependency injection enables objects to only declare their dependencies without having to worry about the specific implementation and lifecycle management of the dependencies. In modern development, dependency injection is often automatically handled by the framework, which further simplifies dependency configuration and makes the system architecture more flexible and modular.
[0027] Dependency injection container: It is the core component of the dependency injection process and can be used to manage the creation, initialization, dependency injection and life cycle of objects in the system. The main function of this container is to resolve the dependencies between objects in an automated way, so that objects no longer directly create or depend on other objects, but instead leave the resolution and injection of dependencies to the container. The container identifies the components that need to be managed and their dependencies by scanning the code, parsing the configuration files or annotations. Subsequently, the container creates instances of the objects based on the dependency requirements and automatically injects the required dependencies into them.
[0028] Dependency requirement component: refers to a module or object that requires specific functions or services in a software system. It usually obtains the required resources from the outside through dependency injection, rather than creating these resources directly inside the component. The purpose of this design is to improve the testability, reusability and flexibility of the module. Dependency requirement components achieve low coupling between modules by explicitly declaring their dependencies so that the framework or container automatically injects the required objects for them.
[0029] Dependency provider component: refers to a module that can provide functions, services or resources to other components. In the dependency injection scenario, the dependency provider component is the object that the dependency requirement component depends on. The dependency provider component can be a specific class instance, an interface implementation class, or even other external resources such as database connections and configuration files. The dependency provider component needs to be explicitly configured by the developer or automatically scanned and registered in the dependency container by the framework so that it can be provided to the requirement component in a timely manner when the program is running.
[0030] In recent years, with the release of Hongmeng system electronic products and the rapid development of Hongmeng ecosystem, the de-dependency, decoupling and componentization of Hongmeng mobile applications have become particularly important. In the related technologies, there is no dependency injection technology for Hongmeng mobile applications, which makes it difficult to reduce the coupling between modules, and maintenance and expansion are relatively difficult.
[0031] In order to at least partially solve one or more of the above-mentioned problems and other potential problems, the present disclosure proposes an application dependency injection method, which can implement instance injection through a dependency injection framework, so that there is no substantial engineering code dependency relationship between dependency requirement components and dependency provider components, thereby realizing dependency understanding, decoupling and componentization, thereby effectively reducing the coupling between modules and improving the maintainability and scalability of the system.
[0032] The present disclosure provides an application dependency injection framework, such as Figure 1As shown, the framework may include: a coding construction unit 101, used to define multiple decorators and use multiple decorators to mark dependency requirement components and dependency providing components; a first compilation unit 102, used to build a providing component mapping relationship; a second compilation unit 103, used to generate a dependency providing mapping relationship based on the providing component mapping relationship; and a running loading unit 104, used to dynamically generate dependency instances and perform dependency injection.
[0033] Here, dependency-providing components refer to those components that provide specific services or functions for use by other components. These components are usually code modules that implement some core logic or functions.
[0034] Here, dependency demand components refer to those components that need to rely on services or functions provided by other components to complete their work. These components interact with dependency providing components through dependency injection, service location or other mechanisms.
[0035] In the application dependency injection framework of the disclosed embodiment, the dependency requirement component can initiate a dependency call request without the user having to manually instantiate the dependency component or manage complex dependency relationships, which can reduce the complexity of manual coding and improve development efficiency. By providing a mapping relationship through dependencies, the most appropriate dependency provider component can be dynamically matched according to the dependency call request, and the choice of dependency can be dynamically determined. New dependency implementations can also be added or replaced to improve the scalability of the system. By generating a dependency injection instance based on the dependency provider component, the instantiation process can be standardized to improve the maintainability, readability and testability of the code. By dynamically injecting the generated dependency instance into the dependency requirement component, low-coupling dependency injection can be achieved, improving module reusability, and after the injection is completed, the dependency injection instance can be returned directly to the dependency requirement component, reducing waiting and complex operations during initialization and improving the operating efficiency of the system.
[0036] In some embodiments, the coding construction unit 101 includes: a framework definition subunit for defining multiple decorators; a first marking subunit for marking dependency providing components using the first type of decorators among the multiple decorators; and a second marking subunit for marking dependency requiring components using the second type of decorators among the multiple decorators.
[0037] In some embodiments, the coding construction unit 101 refers to a structured module for organizing and constructing code during the software development process. It usually includes multiple sub-units that work together to implement specific functions or logic. In object-oriented programming, functional programming or other programming paradigms, the coding construction unit 101 can be a class, module, package, function or any other reusable code component.
[0038] In some embodiments, the framework definition subunit is a component of the code construction unit 101 and is responsible for defining multiple decorators. A decorator is a design pattern that allows adding new functionality to an object without modifying the original code structure. In this context, the framework definition subunit may include the definition, registration, and management logic of the decorator.
[0039] In some embodiments, the first type of decorator refers to a decorator used to mark dependency providing components among multiple decorators. These decorators are usually used to identify components that provide specific services or functions so that other components can rely on them.
[0040] In some embodiments, the second type of decorator refers to a decorator used to mark dependent components among multiple decorators. These decorators are used to identify components that need to rely on other component services. In this way, the dependency relationship between components can be clearly indicated.
[0041] In this way, by defining multiple decorators to mark dependencies, the code structure can be made clearer. The clear identification of dependency-providing components and dependency-required components helps developers understand how components interact with each other, making it easier to maintain and modify the code. The decorator pattern allows new features to be added without modifying the original code, which means that dependency-providing components and dependency-required components can be reused in different contexts without a lot of code modification. Using decorators to mark dependencies can make dependency management more flexible. For example, dependencies can be dynamically added, deleted, or modified programmatically without manually editing the code. By dividing components into dependency-providing components and dependency-required components and marking them with decorators, modular development can be promoted so that each component can be developed, tested, and deployed independently, thereby improving development efficiency and quality. When you need to add new dependencies or features, you only need to create a new decorator and apply it to the corresponding component without making large-scale modifications to the existing code, improving the scalability of the system.
[0042] In some embodiments, the first compiling unit 102 includes: a first compiling sub-unit, configured to construct a provided component mapping relationship according to relevant data of the dependent provided components; and a first storage sub-unit, configured to store the provided component mapping relationship.
[0043] In some embodiments, the first compilation subunit is a core component of the first compilation unit, and is responsible for building a mapping relationship of provided components according to the relevant data of the dependent provided components. These relevant data may include the identification, type, function description, interface definition, etc. of the components. By parsing these data, the first compilation subunit can generate a mapping relationship between components, thereby helping the system understand which components provide which services or functions.
[0044] In some embodiments, the component providing mapping relationship refers to a data structure or representation method that describes the association and dependency relationship between dependent providing components. This mapping relationship may exist in the form of a graph, table, tree or other form to represent the service provision and dependency relationship between components.
[0045] In some embodiments, the first storage subunit is responsible for storing the provided component mapping relationships constructed by the first compilation subunit. It may be a database, a file system, a memory data structure, or other storage mechanism. The first storage subunit ensures that these mapping relationships are accessible and usable during system operation.
[0046] In this way, by building and storing the mapping relationship of provided components, the system can more easily understand and maintain the dependencies between components, which helps developers quickly locate related components and dependencies when modifying or expanding the system. When it is necessary to add new dependent provided components, the system can use the existing mapping relationship to quickly identify and integrate new components, reducing the complexity and cost of system expansion. The mapping relationship of provided components enables the system to dynamically manage dependencies at runtime. For example, when a component is no longer available, the system can automatically find an alternative provided component and update the mapping relationship. By clarifying the dependencies between components, the system can more easily reuse existing components, which helps reduce the workload of repeated development and improve development efficiency. Building the mapping relationship of provided components helps to divide the system into smaller, independent modules. These modules can be developed, tested and deployed independently, thereby improving the testability and deployability of the system. At the same time, this also makes the components of the system easier to understand and maintain.
[0047] In some embodiments, the second compilation unit 103 includes: a second compilation sub-unit, used to traverse the provided component mapping relationship to obtain a provided component mapping relationship set corresponding to each dependent provided component; merge the provided component mapping relationship set to generate a dependent provided mapping relationship; a second storage sub-unit, used to generate a dependent provided mapping relationship.
[0048] In some implementations, the provider component mapping relationship set refers to a collection of all related provider component mapping relationships collected for a single dependent provider component. This collection may contain multiple entries, each of which describes a mapping relationship between the dependent provider component and another component.
[0049] In some implementations, merging provider component mapping relationship sets refers to a process of combining multiple provider component mapping relationship sets into a unified dependency provider mapping relationship.
[0050] In this way, by generating dependency provider mapping relationships, the system can more clearly display the dependencies between components, which helps developers better understand the structure and behavior of the system, making it easier to maintain and expand. Dependency provider mapping relationships provide a comprehensive understanding of the dependencies between system components, allowing the system to more accurately identify and respond to these changes when components change or fail, thereby improving the robustness and stability of the system. The second compilation unit can process and analyze complex provider component mapping relationships and generate high-level dependency provider mapping relationships, which enables the system to support more complex dependency management scenarios, such as circular dependencies, multiple dependencies, etc. By automatically generating dependency provider mapping relationships, the second compilation unit reduces the workload of developers to manually build and maintain these relationships, improves development efficiency, and enables developers to focus more on business logic and function implementation. Dependency provider mapping relationships help divide the system into smaller, independent modules that can be independently developed, tested, and deployed, and integrated through dependency provider mapping relationships when needed, which promotes modular development and flexible expansion of the system.
[0051] In some embodiments, the running loading unit 104 includes: an interface management subunit for defining a dependency injection interface; a mapping and parsing subunit for providing a mapping relationship based on the dependency and determining the implementation class of the dependency; and a dynamic loading subunit for dynamically loading the corresponding implementation class based on the interface type.
[0052] In some embodiments, the interface management subunit is responsible for defining the dependency injection interface. These interfaces are contracts for interaction between different components in the system, and they define the communication methods and required data types between components. By defining these interfaces, the system can ensure loose coupling and high cohesion between components.
[0053] In some embodiments, the mapping and parsing subunit determines the implementation class of the dependency based on the dependency-provided mapping relationship. In software or systems, the dependency-provided mapping relationship describes the dependency relationship between components, including which components provide which services or functions. The mapping and parsing subunit uses this information to find and determine the specific implementation class of each dependency.
[0054] In some implementations, the dynamic loading subunit is responsible for dynamically loading the corresponding implementation class according to the interface type. At runtime, when the system needs a service or function of a component, the dynamic loading subunit is used.
[0055] Thus, through dynamic loading and dependency injection, the runtime loading unit enables the system to flexibly add, replace or delete components at runtime, which improves the scalability and maintainability of the system and enables the system to adapt to changing needs more easily. The dependency injection interface defined by the interface management subunit provides a clear contract for the interaction between components, which makes it easier for developers to write unit tests for components and verify the behavior of components by simulating dependencies. The dynamic loading subunit can automatically load the required components, reducing the workload of developers to manually configure and manage dependencies, improving development efficiency, and allowing developers to focus more on business logic and function implementation. The runtime loading unit supports modular development, allowing the system to be divided into smaller, independent modules that can be independently developed, tested and deployed, and integrated through dependency injection and dynamic loading when needed, which promotes flexible expansion and integration of the system. By accurately parsing and loading dependencies, the runtime loading unit can ensure that the system correctly calls the required components at runtime, reducing the risk of system crashes or instability caused by dependency errors, and improving the stability and reliability of the system.
[0056] For the description of specific functions and examples of each unit and sub-unit of the application dependency injection framework in the embodiment of the present disclosure, please refer to the relevant description of the corresponding steps in the method embodiment below, which will not be repeated here.
[0057] Figure 2 Another structural diagram of the application dependency injection framework is shown, Figure 2 As shown in the figure, the framework is divided into the encoding stage, the Harmony Archive (HAR) compilation stage, the Harmony Ability Package (HAP) or Harmony Shared Package (HSP) compilation stage, and the runtime stage.
[0058] In the coding phase, framework components, dependency requirement components, and dependency provider components are included. In the framework component, define the autowire (@Autowired) decorator, injection (@Inject) decorator, business service (@Service) decorator, dependency provider (@Providers) decorator, and dynamically load modules. Define interfaces in dependency requirement components, use the @AutoWired decorator to decorate injectable runtime classes, and use the @Inject decorator to decorate properties / constructor parameters / methods. In dependency provider components, use the @Service decorator to mark the implementation class and the @Providers decorator to mark the provided injection capabilities.
[0059] In the HAR compilation phase, the Harmony vigor (Hvigor) project construction tool performs the following operations: According to the @Service and @Providers annotation tags, the files used to build the user interface and interaction logic from the dependent provider components (such as Enhanced TypeScript (ets) format files) are parsed to build the mapping relationship files of the interface class and the implementation class, and the mapping relationship files are saved for dynamic loading. Among them, the HAR package is used to package and share code, resources, and configuration files.
[0060] During the HAP or HSP compilation phase, the Hvigor plug-in is used to perform the following operations: Traverse and merge all mapping relationship files generated during the HAR compilation phase, merge these mapping relationship files into a global mapping relationship, and ensure that the dependencies of all components are correctly recorded. Based on the merged global mapping relationship, one or more full interface and implementation class mapping files are generated. These files will contain complete mapping information of all interfaces and their corresponding implementation classes in the project, and are stored in an easy-to-parse format (such as lightweight data exchange format (JavaScript Object Notation, JSON), text-based markup language (Extensible Markup Language, XML), etc.). When the dependency requirement component uses the @Inject decorator to inject dependencies, the system will read these full mapping files. By parsing the information in the mapping file, the system can find the implementation class corresponding to the interface required by the dependency requirement component and instantiate or proxy it to meet the requirements of dependency injection. Throughout the process, the Hvigor plug-in and the HAP compiler need to ensure the accuracy and consistency of the mapping relationship. This includes verifying the integrity of the mapping relationship (that is, all interfaces have corresponding implementation classes) and handling possible conflicts (such as the selection strategy when multiple implementation classes implement the same interface). HAP packages are mainly composed of code, resources, configuration files, etc., and are used to implement specific functions and features of applications. An application can contain one or more HAP packages, and each HAP package can be compiled, installed, and run independently.
[0061] At runtime, the system performs the following steps to initialize the dependency injection container and dynamically load the implementation class according to the mapping file. 1. Define the main Container interface, which defines the main methods for obtaining dependent objects, such as get(Class <t>interfaceClass), which is used to return the corresponding implementation class instance according to the interface class. 2. Use @Inject annotation: Where dependency injection is required, use @Inject annotation to mark fields or method parameters. 3. Initialize Container: When the application starts, create and initialize an implementation class of Container. This implementation class is responsible for reading and managing dependency mapping. During the initialization process, the Container implementation class needs to load and parse the mapping file, which should contain the correspondence between the interface class and the implementation class. 4. Find the implementation class corresponding to the interface according to the mapping file: When the get method of Container is called, it searches the mapping file for the corresponding implementation class type according to the provided interface class type. If the corresponding implementation class is found, Container is responsible for creating an instance of the implementation class. 5. Use the Native Application Programming Interface (NAPI) to dynamically load the implementation class: If the implementation class is not loaded when the application starts, Container can use NAPI to dynamically load the implementation class. Once the implementation class is loaded, Container can create its instance and return it to the caller. The specific implementation and usage of NAPI may depend on the runtime environment and programming language.
[0062] Figure 3 A schematic diagram of an application dependency injection framework is shown, such as Figure 3 As shown, in dependency provider components A, B, and C, the implementation class is marked with the @Service decorator. In dependency requirement component D, the runtime class is marked with the @AutoWired decorator, and the property injection, constructor parameter injection, and method injection are marked with the @Inject decorator. At runtime, relying on the dependency injection framework, the instance of dependency provider component A is injected into dependency requirement component D as a property injection instance; the instance of dependency provider component B is injected into dependency requirement component D as a method injection instance; the instance of dependency provider component C is injected into dependency requirement component D as a property injection instance and a constructor parameter injection instance.
[0063] Based on the application dependency injection framework, the present disclosure provides an application dependency injection method. Figure 4 It is a flowchart of an application dependency injection method according to an embodiment of the present disclosure. The application dependency injection method can be applied to an application dependency injection device. The application dependency injection device is located in an electronic device. The electronic device includes but is not limited to fixed devices and / or mobile devices. For example, fixed devices include but are not limited to servers, and the server can be a cloud server or an ordinary server. For example, mobile devices include but are not limited to: mobile phones, tablet computers. In some possible implementations, the application dependency injection method can also be implemented by a processor calling computer-readable instructions stored in a memory. For example Figure 4 As shown, the application dependency injection method includes:
[0064] S401, receiving a dependency call request of a dependency requirement component;
[0065] S402, determining a dependency providing component according to a dependency call request and a known dependency providing mapping relationship;
[0066] S403, generating a dependency injection instance based on the dependency providing component;
[0067] S404: Return the dependency injection instance to the dependency requirement component.
[0068] In the disclosed embodiment, the dependency call request of the dependency requirement component refers to the request initiated by the dependency requirement component to the dependency injection container during operation to obtain the dependency instance it needs. Among them, the dependency call request enables the dependency requirement component to dynamically provide the required dependencies by the dependency injection container in combination with the dependency providing component without having to directly create or manage dependencies, thereby achieving decoupling between components and improving the flexibility and maintainability of the code. Exemplarily, when the dependency requirement component is initialized, a dependency call request is sent to the dependency injection framework.
[0069] In some implementations, the dependency call request may be a container pull (Container.get) instruction. For example, the Container.get instruction may be provided with a runtime class name of a dependency requirement component.
[0070] In the disclosed embodiment, the dependency provider mapping relationship refers to a corresponding relationship between a dependency requirement component and a dependency provider component defined in the system based on a certain rule. Through this mapping relationship, the dependency injection framework can quickly and accurately locate components or resources that meet the dependency requirements.
[0071] In the disclosed embodiments, a dependency injection instance refers to an object instance that is dynamically generated by a dependency injection framework at runtime and delivered to a dependency requirement component. Generally, the instantiation process is usually handled by a dependency injection container, and the developer only needs to declare dependencies. The generation of a dependency injection instance usually includes steps such as finding a dependency providing component, creating an object instance, and initializing required resources. This design pattern effectively decouples the relationship between modules and improves the scalability and maintainability of the code.
[0072] In the disclosed embodiment, a call request for a specific dependency from a dependency requirement component is first received; then, the corresponding dependency provider component is searched in the dependency provider mapping relationship according to the information in the call request; then, the required dependency injection instance is generated based on the dependency provider component; finally, the generated dependency injection instance is returned to the dependency requirement component that initiated the request so that it can be used normally.
[0073] According to the technical solution of the embodiment of the present disclosure, the dependency requirement component can initiate a dependency call request without manually instantiating the dependency component or managing complex dependency relationships, which can reduce the complexity of manual coding and improve development efficiency. By providing a mapping relationship through dependencies, the most appropriate dependency provider component can be dynamically matched according to the dependency call request, and the choice of dependency can be dynamically determined. New dependency implementations can also be added or replaced to improve the scalability of the system. By generating a dependency injection instance based on the dependency provider component, the instantiation process can be standardized to improve the maintainability, readability and testability of the code. By dynamically injecting the generated dependency instance into the dependency requirement component, low-coupling dependency injection can be achieved, improving module reusability, and after the injection is completed, the dependency injection instance can be returned directly to the dependency requirement component, reducing waiting and complex operations during initialization and improving the operating efficiency of the system.
[0074] In some embodiments, before receiving the dependency call request of the dependency requirement component, the method further includes: using a decorator to mark the dependency providing component and the dependency requirement component respectively.
[0075] In the disclosed embodiment, a decorator is a tool for marking a class or its members, which is commonly found in programming languages that support metadata. By using decorators to mark dependency-providing components and dependency-requiring components, the components can be identified, and then the dependency-providing components and dependency-requiring components can be declared to the dependency injection container.
[0076] In the disclosed embodiment, decorators may be added to specific locations of the codes of the dependency provider component and the dependency requirement component, so as to implement a process of marking the dependency provider component and the dependency requirement component respectively by using decorators.
[0077] In this way, by setting the decorator tag, dependent components can be automatically scanned, identified and registered, without the need for developers to manually manage complex dependency configurations, thus improving development efficiency. Through the tagging mechanism, the dependency relationship is separated from the required component and the provided component, reducing the direct coupling between the two. The provided component and the required component can be developed and modified independently, thereby enhancing code flexibility. At the same time, the system can dynamically switch or expand the dependency implementation, enhancing system scalability.
[0078] In some embodiments, the dependency providing component includes an implementation class; the dependency requiring component includes a runtime class and an injection location. The dependency providing component and the dependency requiring component are marked using decorators, respectively, including: marking the implementation class of the dependency providing component, the runtime class of the dependency requiring component, and the injection location using different decorators.
[0079] In the disclosed embodiment, the implementation class is a specific implementation of a certain interface, abstract class or functional requirement, and usually contains business logic or functions that can be called by other components. Specifically, the implementation class is part of the dependency providing component, which is registered in the dependency injection container after being marked by the decorator, and provided to other dependency requiring components as needed.
[0080] In the disclosed embodiment, the runtime class refers to the class of the dependency component itself, which requires certain dependencies to complete its functions at runtime. Specifically, the runtime class is the subject of declaring the dependency relationship, explicitly declaring that it needs a certain dependency through a decorator, and then using the injected dependency to perform its function after the dependency injection is completed.
[0081] In the embodiment of the present disclosure, the injection location is the specific location where the dependency is declared in the dependency requirement component, and is the location where the dependency is actually injected into the dependency requirement component.
[0082] In the disclosed embodiment, the decorator may include: a first decorator, a second decorator and a third decorator. The first decorator can mark the implementation class of the dependency provider component, the second decorator can mark the runtime class of the dependency requirement component, and the third decorator can mark the injection location of the dependency requirement component.
[0083] In some embodiments, the first decorator may be a @Service decorator or a @Providers decorator. The process of marking the implementation class of the dependency provider component with the first decorator may first determine the implementation class to be marked in the code of the dependency provider component, and then add the first decorator to the top of the definition of the class, so that the dependency injection framework can automatically scan the first decorator and register it as the implementation class of the dependency provider component in the dependency injection container.
[0084] In some embodiments, the second decorator may be an @Autowired decorator. The process of marking the runtime class of the dependency component with the second decorator may first determine the runtime class that needs to be marked in the code of the dependency component, and then add the second decorator to the top of the definition of the class, so that the dependency injection framework automatically scans the second decorator and registers it in the container as the runtime class of the dependency component.
[0085] In some embodiments, the third decorator may be an @Inject decorator. The process of marking the injection location of the dependency requirement component with the third decorator may first determine the member variable that needs to be marked in the code of the dependency requirement component, and then use the third decorator on the member variable so that the dependency injection framework can parse and inject it from the dependency injection container according to the type or identifier.
[0086] In some implementations, during runtime, during class loading, the decorator is executed once, and using this mechanism, the mapping relationship between class name and constructor method can be saved in the container of @Autowired decorator. Furthermore, the mapping relationship between class name, attribute name and constructor parameter can also be saved in the container of @Inject decorator. Furthermore, when @Inject decorator decorates a method, the original method body can be dynamically replaced with the new method body in the decorator class at runtime.
[0087] Figure 5 The following is a schematic diagram showing the working principle of the decorator: Figure 5 As shown, the @AutoWired decorator can map the class name to the constructor method in the constructor map (ConstructorMap). The @Inject decorator can map the class name to the property name and return type name in the property parameter map (PropertyParamsMap), and can also map the class name to the parameter name and return type name in the constructor. In addition, the @Inject decorator can also limit the injection method to dynamically replace the member method body and static method body.
[0088] The above is only an example and is not intended to limit all possible situations of decorators, but it is not intended to be exhaustive.
[0089] In this way, by using different decorators to mark the implementation class of the dependency provider component, the runtime class of the dependency requirement component, and the injection location, it is possible to clearly distinguish between the dependency provider component and the dependency requirement component, ensure clear component responsibilities, and enhance the readability and maintainability of the code. By setting decorators, it is possible to achieve decoupling between the dependency provider component and the dependency requirement component, and improve the overall modularity and flexibility. By using decorator marking, automated dependency management can be achieved, and developers do not need to manually initialize dependencies or manage their lifecycles, which reduces duplicate code, simplifies the development process, and improves development efficiency.
[0090] In some embodiments, the dependency providing component also includes an interface class; the interface class corresponds to the runtime class; the dependency providing mapping relationship records the correspondence between the interface class and the implementation class.
[0091] In the disclosed embodiments, an interface class is an abstract type used to define component behavior specifications or functional contracts, which can provide a set of method or property declarations, but does not include specific implementations. Specifically, the interface class is part of the dependency-provided component and corresponds one-to-one with the runtime class. Among them, the interface class provides abstract specifications, and the runtime class relies on the interface class to complete its own business logic. Furthermore, the interface class is a bridge between the runtime class and the implementation class. The runtime class calls the implementation class through the interface class to improve decoupling.
[0092] In the embodiment of the present disclosure, the correspondence between the interface class and the implementation class can be specifically the correspondence between the interface class name and the implementation class name. Specifically, the name of the interface class can correspond to the name of one or more implementation classes. Further, by providing a mapping relationship through dependency, the corresponding one or more implementation class names can be found according to the name of the interface class.
[0093] In this way, by matching the interface class with the runtime class, it can be ensured that the runtime class only depends on the interface class, and not directly on the implementation class, ensuring that changes to the implementation class will not affect the runtime class code, reducing coupling. By setting up dependencies to provide mapping relationships, multiple different implementation classes can be implemented for the same interface class, and then different implementations can be dynamically injected in different scenarios. By recording the correspondence between the interface class and the implementation class, it can be ensured that when a new implementation class is needed, it is only necessary to bind the new implementation class to the interface class without changing the runtime class code, which improves the modularity and extensibility of the system.
[0094] In some embodiments, the application dependency injection method further includes: generating a provider component mapping relationship corresponding to the dependency provider component based on relevant data of the dependency provider component; and generating a dependency provider mapping relationship according to the provider component mapping relationship.
[0095] In the disclosed embodiment, based on the relevant data of the dependent provided component, the process of generating the provided component mapping relationship corresponding to the dependent provided component can first analyze the code file of the dependent provided component to obtain the component name, implementation class name, code file path and other information, and then generate the mapping relationship between the interface and the implementation class based on the above information, and use the mapping relationship as the provided component mapping relationship. Repeat the above operation until the provided component mapping relationship of each dependent provided component is generated.
[0096] In the disclosed embodiment, the process of generating the dependent providing mapping relationship according to the providing component mapping relationship can sort out the providing component mapping relationship of each dependent providing component, and then generate the dependent providing mapping relationship.
[0097] In this way, by analyzing the relevant data of the dependent component and automatically generating the mapping relationship of the provided component, it is possible to avoid manually maintaining complex dependencies, improve the efficiency of dependency injection, and realize the dynamic and intelligent dependency resolution process. By establishing a mapping between the interface class and the implementation class, it is ensured that the runtime class relies on the interface rather than directly on the specific implementation, thereby realizing the decoupling of the runtime class and the implementation class, further organizing the corresponding relationship between the runtime class and the implementation class, and enhancing the modularity of the system. By generating a mapping relationship between the interface and the implementation class, it can support the situation where the same interface has multiple implementation classes. In actual runtime, the appropriate implementation class is dynamically selected according to the context or dependency injection rules and injected into the runtime class, which enhances the adaptability of the system and meets the needs of different scenarios.
[0098] In some embodiments, based on relevant data of the dependency provider component, a provider component mapping relationship corresponding to the dependency provider component is generated, including: parsing the tag information of the dependency provider component to determine the implementation class corresponding to the dependency provider component; analyzing the syntax of the dependency provider component to determine the interface class corresponding to the implementation class; matching the implementation class and the interface class to generate a provider component mapping relationship.
[0099] In the disclosed embodiment, the process of parsing the tag information of the dependency-provided component and determining the implementation class corresponding to the dependency-provided component can first parse the code of the dependency-provided component, traverse all class files under the specified directory or module, and determine whether any class is marked by the decorator as an implementation class corresponding to the dependency-provided component, and then determine the implementation class corresponding to the dependency-provided component. Specifically, there may be multiple implementation classes corresponding to the dependency-provided component in the dependency-provided component. At this time, all implementation classes marked as dependency-provided components can be saved as a list, and each class included in this list can be regarded as an implementation class corresponding to the dependency-provided component.
[0100] In the disclosed embodiment, the process of analyzing the syntax of the dependency-provided component and determining the interface class corresponding to the implementation class can first analyze the code file of the implementation class to determine the basic structure of the implementation class, and then extract the interface class information based on the basic structure of the implementation class to determine the interface class corresponding to the implementation class.
[0101] In the embodiment of the present disclosure, the implementation class and the interface class are matched, and the process of generating the component mapping relationship can create a JSON file after matching the information of the implementation class and the interface class one by one, and use the file as the component mapping relationship.
[0102] In some embodiments, the Hvigor plug-in can be used to generate the mapping relationship of the provided component during the HAR compilation stage. Specifically, during the HAR compilation stage of the dependent provided component, the ets format code file of the current dependent provided component is parsed, and the information of the decorated class is obtained according to the position and type of the @Service decorator or @Providers decorator. Among them, the information of the decorated class may include the component name (moduleName) of the current component, the implementation class name (implName), the ets format code file path, etc. A JSON file of the mapping relationship between the interface and the decorated implementation class is then generated and saved in the original file (rawfile) directory of the component to participate in the subsequent packaging and publishing process.
[0103] In some implementations, the process of generating and providing component mapping relationships can be implemented during the HAR compilation phase by inserting a new task (Task-1) between the two tasks of pre-building (PreBuild) and merging the configuration file (MergeProfile).
[0104] In this way, by automatically parsing the tag information and grammatical structure in the code, the mapping relationship between the interface class and the implementation class can be dynamically generated without the need for manual configuration by the developer, thereby reducing the complexity of manual configuration mapping and the possibility of configuration errors. By generating component mapping relationships, the dependencies between the implementation class and the interface class are decoupled, and the implementation class can be directly replaced without modifying the interface call code, which improves the flexibility of the system and facilitates expansion and maintenance.
[0105] In some embodiments, a dependency providing mapping relationship is generated based on the providing component mapping relationship, including: traversing all dependency providing components to generate a providing component mapping relationship set corresponding to each dependency providing component; merging the providing component mapping relationship set to generate a dependency providing mapping relationship.
[0106] In the disclosed embodiment, the process of traversing all dependent providing components and generating a providing component mapping relationship set corresponding to each dependent providing component can scan the entire code file, determine all dependent components, and then generate a providing component mapping relationship corresponding to each dependent providing component. Finally, the providing component mapping relationship corresponding to each dependent providing component is used as a providing component mapping relationship set.
[0107] In the disclosed embodiment, the process of merging a set of provided component mapping relationships to generate a dependent provided mapping relationship may first traverse each provided component mapping relationship in the provided component mapping relationship set, aggregate and merge them during the traversal process, and then generate a dependent provided mapping relationship.
[0108] In some embodiments, the Hvigor plug-in can be used to automatically merge the JSON files of the rawfiles in all dependent HARs during the HAP compilation phase or the HSP phase. Specifically, in the HAP or HSP phase, the rawfiles will be merged, and based on the merged rawfiles, all the mapping relationship JSON files generated during the HAR compilation phase can be traversed and read, and a mapping relationship ets file can be generated by summarizing, and the JSON files can be deleted at the same time, and the ets file can be saved in the HAP as a dependency to provide mapping relationships and continue to participate in the compilation. Exemplarily, the ets file can be recorded as a service.di.ets file, which is a file used to describe the layout, style, event interaction, and page logic of the service component user interface (UI), where "service" represents the service component, "di" represents dependency injection, and ets represents the file format.
[0109] In some implementations, the process of generating a dependency mapping relationship can be implemented during the HAP compilation phase by inserting a new task (Task-2) between the two tasks of Compile Resource (CompileResource) and Compiler (CompileArkts).
[0110] Figure 6 FIG. 4 shows a flow chart of the second compilation (ie, HAP compilation) stage, as shown in FIG. Figure 6 As shown, the process includes the following steps.
[0111] S601: merge rawfile paths;
[0112] This step is usually performed in the preparation stage to ensure that all required rawfile paths are correctly collected and merged, providing a basis for subsequent reading and processing.
[0113] S602: traverse and read all mapping relationship JSON files;
[0114] This step ensures that all necessary mapping information is collected.
[0115] S603: Generate a summarized mapping relationship ets file and delete the JSON file at the same time;
[0116] After reading all JSON files, generate a summary ets file immediately, which will contain all necessary mapping information. At the same time, in order to save space and facilitate management, the original JSON file can be deleted. This step should be followed by reading the JSON file to ensure the integrity and consistency of the information.
[0117] S604: The summarized mapping relationship ets file is stored in the HAP to continue to participate in the compilation.
[0118] Finally, the generated ets file is stored in the HAP package for use in the subsequent compilation process. This step ensures that the ets file is correctly integrated into the final HAP package.
[0119] In this way, the entire process can avoid the tedious work of manually maintaining dependencies through automated scanning, mapping relationship generation, merging and aggregation, greatly improving the efficiency of building and compiling. By traversing all dependent components and generating corresponding sets of component mapping relationships, it can adapt to the multi-component and multi-level dependency management requirements involved in complex projects. By merging and aggregating resource files during the compilation phase, it can effectively unify resource management, making the final generated dependency mapping relationship file clear and complete, and facilitating subsequent use and maintenance.
[0120] In some embodiments, a dependency provider component is determined based on a dependency call request and a known dependency provider mapping relationship, including: determining a runtime class to be injected, a location to be injected, and an injection method based on the dependency call request; determining a corresponding interface class to be injected based on the runtime class to be injected; and determining a dependency provider component corresponding to the interface class to be injected based on the dependency provider mapping relationship.
[0121] In the embodiment of the present disclosure, the process of determining the runtime class to be injected, the location to be injected, and the injection method according to the dependency call request can first parse the dependency call request to determine the runtime class to be injected of the dependency requirement component, and then determine the location to be injected and the injection method through the decorator. The injection method may include: constructor injection, method injection, direct injection, etc.
[0122] In the disclosed embodiment, the process of determining the corresponding interface class to be injected according to the runtime class to be injected can be based on the dependency requirement component code file and the corresponding interface class to be injected according to the runtime class to be injected.
[0123] In the embodiment of the present disclosure, the process of determining the dependency provider component corresponding to the interface class to be injected based on the dependency provider mapping relationship can first query the dependency provider mapping relationship based on the interface class to be injected, find the implementation class to be injected corresponding to the interface class to be injected, and then determine the dependency provider component based on the implementation class to be injected.
[0124] In some embodiments, the runtime class to be injected can be first determined according to the runtime class name set in the dependency call request Container.get instruction, and then the name of the runtime class is used to locate the location of the dependency requirement component in the code file through the @Autowired decorator. Subsequently, the @Inject decorator is searched in the dependency requirement component, and the location marked by the @Inject decorator is used as the location to be injected. Finally, the injection method is determined according to the member variables, constructors or methods and other parameters configured by the @Inject decorator. Further, the relevant parameter settings in the runtime class to be injected can be found according to the dependency requirement component code file, and the corresponding interface class to be injected can be determined. Finally, according to the interface class to be injected, the service.di.ets generated in the HAP compilation result can be loaded, and the dependency providing mapping relationship ets file can be queried using the pull implementation class instruction (getImpls) to obtain the component name and implementation class name of the implementation class to be injected corresponding to the interface class to be injected, and then the dependency providing component can be determined.
[0125] In this way, through the dependency call request and decorator mechanism, developers do not need to manually manage dependencies, which greatly reduces the complexity of dependency injection. It can automatically parse the process of runtime classes, interface classes and implementation classes, avoiding the tediousness and error-proneness of manual configuration, and improving development efficiency and accuracy. By looking for the corresponding dependency provider component through the dependency call request, the dependency requirement component can be isolated from the specific implementation class, avoiding the dependency requirement component directly relying on the specific implementation class, thereby improving the flexibility and maintainability of the code. By providing mapping relationships through dependencies, the system can organize and manage dependencies in a modular way, allowing different components to be developed independently, and aggregated through mapping relationships, facilitating the collaboration and management of large-scale projects. By providing mapping relationships and dynamic parsing mechanisms through dependencies, the integrity of dependencies can be verified before injection, which can reduce exceptions caused by missing or incorrectly configured dependencies at runtime and improve the robustness of the system.
[0126] In some embodiments, generating a dependency injection instance based on a dependency providing component includes: generating a dependency injection instance matching the dependency providing component using a dynamic loading mechanism according to an injection method and a position to be injected.
[0127] In the disclosed embodiments, the dynamic loading mechanism refers to dynamically loading related classes or modules according to requirements at runtime and generating class instances. The dynamic loading mechanism has good flexibility and delayed loading capabilities, allowing the framework to load appropriate implementation classes according to actual requirements at runtime without determining dependencies at compile time.
[0128] In this way, the dynamic loading mechanism can dynamically load related classes or modules according to the actual needs at runtime, generate instances required for dependencies, eliminate the limitations of hard-coded dependencies, and make the code more adaptable and extensible. The lazy loading capability of the dynamic loading mechanism ensures that the corresponding implementation class is loaded and instantiated only when a dependency is really needed. Unnecessary modules or components will not be loaded immediately, which can reduce resource consumption at system startup and improve startup speed. It can also avoid preloading components that may never be used, thereby reducing runtime memory usage and performance overhead. Through the dynamic loading mechanism, the framework is decoupled from the implementation class through interfaces or abstract classes. The dependency requirement components do not depend on the specific implementation class. They only need to dynamically load the required implementation according to demand, further improving the flexibility of the system.
[0129] In some embodiments, according to the injection method and the position to be injected, a dynamic loading mechanism is used to generate a dependency injection instance that matches the dependency providing component, including: determining the corresponding implementation class to be injected according to the dependency providing component; dynamically loading the implementation class to be injected to generate the instance to be injected; according to the injection method, injecting the instance to be injected into the position to be injected to generate the dependency injection instance.
[0130] In the disclosed embodiment, the process of determining the corresponding implementation class to be injected according to the dependency providing component can first scan the code file of the dependency providing component and determine the corresponding implementation class to be injected based on the decorator.
[0131] In the disclosed embodiment, the process of dynamically loading the implementation class to be injected and generating the instance to be injected can first use reflection or other dynamic loading mechanisms to load the dependent implementation class at runtime, and then generate the instance through the dynamically loaded class. The above is only an exemplary description and is not intended to limit all possible situations of dynamically loading the implementation class to be injected and generating the instance to be injected, but it is not exhaustive here.
[0132] In the disclosed embodiment, according to the injection method, the instance to be injected is injected into the position to be injected, and the process of generating the dependency injection instance can inject the generated instance into the specified position of the dependency requirement component. Specifically, for the field injection method, it can be achieved by setting the private field value through reflection; for the method injection method, the instance to be injected can be passed by calling the method; for the constructor injection method, the instance to be injected can be directly passed through the constructor.
[0133] In some implementations, the code file of the dependency provider component can be scanned first, the @Service or @Providers decorator can be located, and the implementation class marked by the decorator can be used as the implementation class to be injected. Furthermore, the implementation class can be dynamically loaded through the NAPI interface. Furthermore, after the implementation class is dynamically instantiated, it is injected into the class of the dependency requirement component, and an instance of the implementation class is returned. Specifically, the instance of the return type can be injected into a property or constructor parameter or method and returned. Finally, the dependency injection container returns the class instance marked by the @Autowired decorator in the dependency injection request Container.get instruction.
[0134] In some implementations, after determining the dependency requirement component through the dependency injection request Container.get instruction, the dependency injection container is searched to see if there is an instance of the type cached. If so, the instance can be directly injected into the property or constructor parameter or method return. Finally, the dependency injection container returns the class instance marked by the @Autowired decorator in the dependency injection request Container.get instruction.
[0135] In some real-time modes, the open synchronous loading module of Hongmeng can be used to support the loading of multiple module forms.
[0136] In this way, by dynamically loading the implementation class to be injected, the implementation class can be loaded at runtime using reflection or dynamic loading mechanism instead of hard-coding dependencies at compile time, which can ensure that the system dynamically resolves dependencies according to the runtime context, reduces the coupling of the code, and enhances the adaptability of the system. By determining the injection method, the most suitable injection method can be selected according to the needs, providing higher flexibility and scalability. By scanning decorators, the implementation class is decoupled from the interface or abstract class. The dependency requirement component only needs to rely on the interface or abstract class without knowing the specific implementation class, which promotes modular design and improves the maintainability and scalability of the system. By caching instances in the dependency injection container, when the same type of dependency is requested again, the instance can be directly obtained from the cache without regeneration, which improves performance and resource utilization efficiency. Automated dependency parsing and injection are achieved through decorators and dependency injection containers, without the need for developers to manually manage dependencies, simplifying the development process, improving development efficiency, and reducing the possibility of code errors. The dynamic loading mechanism allows the addition or replacement of implementation classes at runtime without modifying the source code or redeploying the system, enhancing the dynamic expansion capability of the system.
[0137] In some embodiments, the application dependency injection method can be applied to Hongmeng mobile applications. According to the decorator syntax definition of Hongmeng ArkTs and the Hvigor plug-in definition of Hongmeng, a mapping relationship JSON file of the interface class and the implementation class is generated for the dependency provider component during HAR / HAP compilation. During HAP compilation, a summary mapping relationship ets file is generated based on the mapping relationship JSON files of each component of the dependency provider component. At the location where the dependency requirement object needs the interface implementation class, the implementation class instance of the interface is dynamically loaded according to the summary mapping relationship ets file and injected into the dependency requirement object.
[0138] In some embodiments, the Hongmeng multi-threaded runtime environment is memory isolated. If the implementation class instance decorated with @Service in the dependent component needs to be used as a singleton in a multi-threaded environment, the implementation class must support multi-threading. According to the Hongmeng official guide, classes that support multi-threaded sharing need to be marked with the @Sendable decorator. However, according to the usage rules and constraints of @Sendable, @Sendable cannot be used with other decorators such as @Service. In response to this problem, since the role of the @Service decorator is to generate a JSON file of the mapping relationship between the interface class name and the implementation class at compile time, the problem can be circumvented by changing the marking method, such as interface identification or abstract class identification, and the syntax tree can be parsed at compile time.
[0139] In some implementations, since in Container.get, the instance of the implementation class loaded using synchronous dynamic modules needs to be saved to the cache map (ImplsMap), for the multi-threaded singleton of the implementation class, it is necessary for ImplsMap to support multi-threaded addition, and the adding method is multi-threaded synchronous, and ImplsMap is a singleton; that is, ImplsMap is a singleton and supports multi-threaded synchronous addition. In view of the above situation, the C++ layer can be encapsulated with a singleton, and the upper layer can be encapsulated with a scripting language (JavaScript, JS) shell, so that the main thread and child thread can obtain without restrictions.
[0140] Figure 7 A schematic diagram of the process of obtaining an instance of a dependent requirement component is shown, such as Figure 7 As shown, the process includes the following steps.
[0141] S701: The dependent requirement component calls the Container.get command and passes in the class name.
[0142] S702: Get the constructor (Constructor) in ConstructorMap.
[0143] S703a: When the injection method is property and / or constructor parameter injection, obtain the property return type and / or constructor return type name from PropertyParamsMap; S703b: When the injection method is method injection, use the return type name in the newly replaced method body.
[0144] S704: According to the return type name, query whether there is an instance of the cached return type in the dependency injection container. If the instance does not exist, execute S705; if the instance exists, execute S708;
[0145] S705: Use synchronous dynamic loading of the instance module to load the service.di.ets file according to the return type name.
[0146] S706: Use the getImpls instruction to obtain the component name, implementation class name and other information of the return type instance.
[0147] S707: Using NAPI to synchronously and dynamically load an instance of the return type, and then output the instance of the return type.
[0148] S708: According to the instance of the return type output by the synchronous dynamic loading instance module or the instance of the return type cached in the dependency injection container, the instance is injected into a property or a constructor parameter or a method for return.
[0149] S709: The dependency injection container returns the class instance decorated with @AutoWired of the Container.get command.
[0150] It should be understood that Figures 1 to 7 The schematic diagram shown is only exemplary and not restrictive, and it is scalable, and those skilled in the art can Figures 1 to 7 Various obvious changes and / or substitutions can be made to the examples, and the resulting technical solutions still fall within the scope of the disclosure of the embodiments of the present disclosure.
[0151] The present disclosure provides an application dependency injection device, such as Figure 8 As shown, the device may include: a request receiving module 801, used to receive a dependency call request of a dependency requirement component; a mapping parsing module 802, used to determine a dependency providing component according to the dependency call request and a known dependency providing mapping relationship; an instance generating module 803, used to generate a dependency injection instance based on the dependency providing component; and an instance returning module 804, used to return the dependency injection instance to the dependency requirement component.
[0152] In some embodiments, the application dependency injection device further includes: a component encoding module ( Figure 8 ), which is used to use decorators to mark the dependency providing components and the dependency requiring components respectively.
[0153] In some embodiments, the dependency providing component includes an implementation class; the dependency requiring component includes a runtime class and an injection location; the component encoding module ( Figure 8 ), used to: use different decorators to mark the implementation class of the dependency-providing component, the runtime class of the dependency-requiring component, and the injection location.
[0154] In some embodiments, the dependency providing component also includes an interface class; the interface class corresponds to the runtime class; the dependency providing mapping relationship records the correspondence between the interface class and the implementation class.
[0155] In some embodiments, the application dependency injection device further includes: a component mapping module ( Figure 8 ), used to generate a mapping relationship of providing components corresponding to the dependent providing components based on the relevant data of the dependent providing components; a dependency mapping module ( Figure 8 ), which is used to generate a dependent provision mapping relationship based on the provided component mapping relationship.
[0156] In some embodiments, the component mapping module ( Figure 8 ), including: a tag parsing submodule, used to parse the tag information of the dependency provider component and determine the implementation class corresponding to the dependency provider component; a syntax analysis submodule, used to analyze the syntax of the dependency provider component and determine the interface class corresponding to the implementation class; a mapping correspondence submodule, used to correspond the implementation class and the interface class to generate a provider component mapping relationship.
[0157] In some embodiments, the dependency mapping module ( Figure 8 ), including: a mapping set submodule, used to traverse all dependency providing components and generate a providing component mapping relationship set corresponding to each dependency providing component; a mapping merging submodule, used to merge the providing component mapping relationship set to generate a dependency providing mapping relationship.
[0158] In some embodiments, the mapping and parsing module 802 includes: a request determination submodule, used to determine the runtime class to be injected, the injection location and the injection method according to the dependency call request; a first corresponding submodule, used to determine the corresponding interface class to be injected according to the runtime class to be injected; and a second corresponding submodule, used to determine the corresponding dependency providing component to be injected according to the interface class to be injected.
[0159] In some embodiments, the instance generation module 803 includes: an instance injection submodule, which is used to generate a dependency injection instance matching the dependency providing component by using a dynamic loading mechanism according to the injection method and the position to be injected.
[0160] In some embodiments, the instance injection submodule is used to: determine the corresponding implementation class to be injected according to the dependency provider component to be injected; dynamically load the implementation class to be injected to generate the instance to be injected; and inject the instance to be injected into the position to be injected according to the injection method to generate a dependency injection instance.
[0161] For the description of specific functions and examples of each module and submodule of the device in the embodiment of the present disclosure, reference can be made to the relevant description of the corresponding steps in the above method embodiment, which will not be repeated here.
[0162] The application dependency injection device in the disclosed embodiment can dynamically match the most appropriate dependency provider component according to the dependency call request through the dependency provider mapping relationship, and can also add or replace new dependency implementations to improve the scalability of the system. By dynamically injecting the generated dependency instance into the dependency requirement component, low-coupling dependency injection can be achieved, improving module reusability, and after the injection is completed, the dependency injection instance can be directly returned to the dependency requirement component, reducing waiting and complex operations during initialization, and improving the operating efficiency of the system.
[0163] In the technical solution disclosed herein, the acquisition, storage and application of user personal information involved are in compliance with the provisions of relevant laws and regulations and do not violate public order and good morals.
[0164] According to an embodiment of the present disclosure, the present disclosure also provides an electronic device, a readable storage medium and a computer program product.
[0165] Fig. 9 A schematic block diagram of an example electronic device 900 that can be used to implement an embodiment of the present disclosure is shown. The electronic device is intended to represent various forms of digital computers, such as laptop computers, desktop computers, workstations, personal digital assistants, servers, blade servers, mainframe computers, and other suitable computers. The electronic device can also represent various forms of mobile devices, such as personal digital assistants, cellular phones, smart phones, wearable devices, and other similar computing devices. The components shown herein, their connections and relationships, and their functions are merely examples and are not intended to limit the implementation of the present disclosure described and / or required herein.
[0166] like Fig. 9 As shown, the device 900 includes a computing unit 901, which can perform various appropriate actions and processes according to a computer program stored in a read-only memory (ROM) 902 or a computer program loaded from a storage unit 908 to a random access memory (RAM) 903. In the RAM 903, various programs and data required for the operation of the device 900 can also be stored. The computing unit 901, the ROM 902, and the RAM 903 are connected to each other via a bus 904. An input / output (I / O) interface 905 is also connected to the bus 904.
[0167] A number of components in the device 900 are connected to the I / O interface 905, including: an input unit 906, such as a keyboard, a mouse, etc.; an output unit 907, such as various types of displays, speakers, etc.; a storage unit 908, such as a disk, an optical disk, etc.; and a communication unit 909, such as a network card, a modem, a wireless communication transceiver, etc. The communication unit 909 allows the device 900 to exchange information / data with other devices through a computer network such as the Internet and / or various telecommunication networks.
[0168] The computing unit 901 may be a variety of general and / or special processing components with processing and computing capabilities. Some examples of the computing unit 901 include, but are not limited to, a central processing unit (CPU), a graphics processing unit (GPU), various dedicated artificial intelligence (AI) computing chips, various computing units running machine learning model algorithms, digital signal processors (DSP), and any appropriate processors, controllers, microcontrollers, etc. The computing unit 901 performs the various methods and processes described above, such as the application dependency injection method. For example, in some embodiments, the application dependency injection method may be implemented as a computer software program, which is tangibly included in a machine-readable medium, such as a storage unit 908. In some embodiments, part or all of the computer program may be loaded and / or installed on the device 900 via the ROM 902 and / or the communication unit 909. When the computer program is loaded into the RAM 903 and executed by the computing unit 901, one or more steps of the application dependency injection method described above may be performed. Alternatively, in other embodiments, the computing unit 901 may be configured to execute the application dependency injection method in any other appropriate manner (for example, by means of firmware).
[0169] Various embodiments of the systems and techniques described above herein can be implemented in digital electronic circuit systems, integrated circuit systems, field programmable gate arrays (FPGAs), application specific integrated circuits (ASICs), application-specific standard products (ASSPs), systems on chips (SOCs), complex programmable logic devices (CPLDs), computer hardware, firmware, software, and / or combinations thereof. These various embodiments can include: being implemented in one or more computer programs that can be executed and / or interpreted on a programmable system including at least one programmable processor, which can be a special purpose or general purpose programmable processor that can receive data and instructions from a storage system, at least one input device, and at least one output device, and transmit data and instructions to the storage system, the at least one input device, and the at least one output device.
[0170] The program code for implementing the method of the present disclosure may be written in any combination of one or more programming languages. These program codes may be provided to a processor or controller of a general-purpose computer, a special-purpose computer, or other programmable data processing device, so that the program code, when executed by the processor or controller, enables the functions / operations specified in the flow chart and / or block diagram to be implemented. The program code may be executed entirely on the machine, partially on the machine, partially on the machine and partially on a remote machine as a stand-alone software package, or entirely on a remote machine or server.
[0171] In the context of the present disclosure, a machine-readable medium may be a tangible medium that may contain or store a program for use by or in conjunction with an instruction execution system, device, or equipment. A machine-readable medium may be a machine-readable signal medium or a machine-readable storage medium. A machine-readable medium may include, but is not limited to, an electronic, magnetic, optical, electromagnetic, infrared, or semiconductor system, device, or device, or any suitable combination of the foregoing. A more specific example of a machine-readable storage medium may include an electrical connection based on one or more lines, a portable computer disk, a hard disk, a random access memory, a read-only memory, an erasable programmable read-only memory (EPROM), a flash memory, an optical fiber, a portable compact disk read-only memory (CD-ROM), an optical storage device, a magnetic storage device, or any suitable combination of the foregoing.
[0172] To provide interaction with a user, the systems and techniques described herein can be implemented on a computer having: a display device (e.g., a cathode ray tube (CRT) or a liquid crystal display (LCD) monitor) for displaying information to the user; and a keyboard and a pointing device (e.g., a mouse or trackball) through which the user can provide input to the computer. Other types of devices can also be used to provide interaction with the user; for example, the feedback provided to the user can be any form of sensory feedback (e.g., visual feedback, auditory feedback, or tactile feedback); and input from the user can be received in any form (including acoustic input, voice input, or tactile input).
[0173] The systems and techniques described herein can be implemented in a computing system that includes back-end components (e.g., as a data server), or a computing system that includes middleware components (e.g., an application server), or a computing system that includes front-end components (e.g., a user computer with a graphical user interface or a web browser through which a user can interact with implementations of the systems and techniques described herein), or a computing system that includes any combination of such back-end components, middleware components, or front-end components. The components of the system can be interconnected by any form or medium of digital data communication (e.g., a communication network). Examples of communication networks include: Local Area Networks (LANs), Wide Area Networks (WANs), and the Internet.
[0174] A computer system may include a client and a server. The client and the server are generally remote from each other and usually interact through a communication network. The relationship of client and server is generated by computer programs running on respective computers and having a client-server relationship with each other. The server may be a cloud server, a server of a distributed system, or a server combined with a blockchain.
[0175] It should be understood that the various forms of processes shown above can be used to reorder, add or delete steps. For example, the steps recorded in this disclosure can be executed in parallel, sequentially or in different orders, as long as the desired results of the technical solutions disclosed in this disclosure can be achieved, and this document does not limit this.
[0176] The above specific implementations do not constitute a limitation on the protection scope of the present disclosure. It should be understood by those skilled in the art that various modifications, combinations, sub-combinations and substitutions can be made according to design requirements and other factors. Any modification, equivalent substitution and improvement made within the principles of the present disclosure shall be included in the protection scope of the present disclosure.< / t>
Claims
1. An application dependency injection method, comprising: Receive dependency call requests from dependency requirement components; Determine the dependency providing component according to the dependency call request and the known dependency providing mapping relationship; Generate a dependency injection instance based on the dependency providing component; Return the dependency injection instance to the dependency requirement component.
2. The method according to claim 1, wherein: Before receiving the dependency call request of the dependency requirement component, the method further includes: The dependency providing component and the dependency requiring component are marked respectively by using decorators.
3. The method according to claim 2, wherein: The dependency providing component includes an implementation class; the dependency requiring component includes a runtime class and an injection location; The step of marking the dependency providing component and the dependency requiring component respectively by using a decorator includes: The implementation class of the dependency providing component, the runtime class of the dependency requiring component and the injection location are marked with different decorators.
4. The method according to claim 3, wherein: The dependency providing component also includes an interface class; the interface class corresponds to the runtime class; The dependency provides a mapping relationship that records the corresponding relationship between the interface class and the implementation class.
5. The method according to claim 2, wherein: The method further comprises: Based on the relevant data of the dependent providing component, generating a providing component mapping relationship corresponding to the dependent providing component; The dependency provision mapping relationship is generated according to the provision component mapping relationship.
6. The method according to claim 5, wherein: The generating, based on the relevant data of the dependent providing component, a providing component mapping relationship corresponding to the dependent providing component comprises: Parsing the tag information of the dependency provider component to determine the implementation class corresponding to the dependency provider component; Analyze the syntax of the dependency provider component and determine the interface class corresponding to the implementation class; The implementation class and the interface class are matched to generate the provided component mapping relationship.
7. The method according to claim 5, wherein: The generating the dependency providing mapping relationship according to the providing component mapping relationship comprises: Traversing all dependent providing components, and generating a providing component mapping relationship set corresponding to each of the dependent providing components; The provided component mapping relationship sets are merged to generate the dependent provided mapping relationship.
8. The method according to claim 1, wherein: The determining of the dependency providing component according to the dependency calling request and the known dependency providing mapping relationship includes: Determine the runtime class to be injected, the location to be injected, and the injection method according to the dependency call request; According to the runtime class to be injected, determine the corresponding interface class to be injected; According to the dependency providing mapping relationship, the dependency providing component corresponding to the interface class to be injected is determined.
9. The method according to claim 8, wherein: The generating a dependency injection instance based on the dependency providing component comprises: According to the injection method and the position to be injected, a dynamic loading mechanism is used to generate the dependency injection instance that matches the dependency providing component.
10. The method according to claim 9, wherein: The step of generating the dependency injection instance matching the dependency providing component by using a dynamic loading mechanism according to the injection mode and the position to be injected includes: Determine the corresponding implementation class to be injected according to the dependency providing component; Dynamically load the implementation class to be injected and generate an instance to be injected; According to the injection method, the instance to be injected is injected into the position to be injected to generate the dependency injection instance.
11. An application dependency injection framework, comprising: A coding construction unit, used for defining a plurality of decorators and marking dependency demand components and dependency providing components by using the plurality of decorators; A first compilation unit is used to construct and provide component mapping relationships; A second compilation unit, configured to generate a dependency provision mapping relationship according to the provision component mapping relationship; Run the loading unit to dynamically generate dependency instances and perform dependency injection.
12. The frame according to claim 11, wherein: The coding construction unit comprises: A framework definition subunit, used to define the multiple decorators; A first marking subunit, configured to mark the dependency providing component using a first type of decorator among the multiple decorators; The second marking subunit is used to mark the dependency requirement component using a second type of decorator among the multiple decorators.
13. The frame according to claim 11, wherein: The first compilation unit includes: A first compiling subunit, configured to construct the providing component mapping relationship according to relevant data of the dependent providing component; The first storage subunit is used to store the provided component mapping relationship.
14. The frame according to claim 11, wherein: The second compilation unit comprises: The second compiling subunit is used to traverse the provided component mapping relationship to obtain a provided component mapping relationship set corresponding to each dependent provided component; merge the provided component mapping relationship sets to generate the dependent provided mapping relationship; The second storage subunit is used to generate the dependency providing mapping relationship.
15. The frame according to claim 11, wherein: The operation loading unit comprises: The interface management subunit is used to define the dependency injection interface; A mapping and parsing subunit, used to provide a mapping relationship according to the dependency and determine an implementation class of the dependency; The dynamic loading subunit is used to dynamically load the corresponding implementation class according to the interface type.
16. An application dependency injection device, comprising: A request receiving module, used to receive a dependency call request of a dependency requirement component; A mapping and parsing module, used for determining a dependency providing component according to the dependency call request and a known dependency providing mapping relationship; An instance generation module, used to generate a dependency injection instance based on the dependency providing component; The instance returning module is used to return the dependency injection instance to the dependency requirement component.
17. The device according to claim 16, wherein: The application dependency injection device further includes: The component encoding module is used to mark the dependency providing component and the dependency requiring component respectively by using decorators.
18. The device according to claim 17, wherein: The dependency providing component includes an implementation class; the dependency requiring component includes a runtime class and an injection location; The component encoding module is used to: The implementation class of the dependency providing component, the runtime class of the dependency requiring component and the injection location are marked with different decorators.
19. The device according to claim 18, wherein: The dependency providing component also includes an interface class; the interface class corresponds to the runtime class; The dependency provides a mapping relationship that records the corresponding relationship between the interface class and the implementation class.
20. The device according to claim 17, wherein: The application dependency injection device also includes: A component mapping module, used to generate a providing component mapping relationship corresponding to the dependent providing component based on the dependent providing component; The dependency mapping module is used to generate the dependency provision mapping relationship according to the provision component mapping relationship.
21. The device according to claim 20, wherein: The component mapping module includes: A tag parsing submodule, used to parse the tag information of the dependency providing component and determine the implementation class corresponding to the dependency providing component; A syntax analysis submodule, used to analyze the syntax of the dependency providing component and determine the interface class corresponding to the implementation class; The mapping correspondence submodule is used to correspond the implementation class and the interface class to generate the provided component mapping relationship.
22. The device according to claim 20, wherein: The dependency mapping module includes: A mapping set submodule, used to traverse all dependent providing components and generate a providing component mapping relationship set corresponding to each of the dependent providing components; The mapping merging submodule is used to merge the provided component mapping relationship set to generate the dependent provided mapping relationship.
23. The device according to claim 16, wherein: The mapping and parsing module comprises: A request determination submodule, used to determine the runtime class to be injected, the location to be injected and the injection method according to the dependency call request; A first corresponding submodule, used to determine a corresponding interface class to be injected according to the runtime class to be injected; The second corresponding submodule is used to determine the corresponding dependency providing component to be injected according to the interface class to be injected.
24. The device according to claim 23, wherein: The instance generation module comprises: The instance injection submodule is used to generate the dependency injection instance matching the dependency providing component by using a dynamic loading mechanism according to the injection method and the position to be injected.
25. The device according to claim 24, wherein: The instance injection submodule is used to: Determine the corresponding implementation class to be injected according to the dependency providing component to be injected; Dynamically load the implementation class to be injected and generate an instance to be injected; According to the injection method, the instance to be injected is injected into the position to be injected to generate the dependency injection instance.
26. An electronic device comprising: at least one processor; as well as a memory communicatively connected to at least one processor; wherein, The memory stores instructions that can be executed by at least one processor, and the instructions are executed by at least one processor to enable the at least one processor to perform the method of any one of claims 1 to 10.
27. A non-transitory computer-readable storage medium storing computer instructions, wherein: The computer instructions are for causing a computer to perform a method according to any one of claims 1-10.
28. A computer program product comprising a computer program stored on a storage medium, the computer program implementing the method according to any one of claims 1 to 10 when executed by a processor.