---
title: Inject objects into a node instance
description: A node instance is constructed every time that node is reached in a tree and is discarded as soon as it has been used to process the state once.
component: pingam
version: 7.3
page_id: pingam:auth-nodes:core-inject
canonical_url: https://docs.pingidentity.com/pingam/8.1/auth-nodes/core-inject.html
llms_txt: https://docs.pingidentity.com/pingam/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
keywords: ["Extensibility", "Nodes &amp; Trees", "Scripts"]
superseded_by: https://docs.pingidentity.com/pingam/8.1/auth-nodes/core-inject.html
section_ids:
  using-a-cache: Use a cache
  custon-guice-bindings: Custom Guice bindings
---

# Inject objects into a node instance

A node instance is constructed every time that node is reached in a tree and is discarded as soon as it has been used to process the state once.

This model is different to authentication *modules* which are instantiated once for each end-user authentication process. All authentication interactions for the life of the authentication process address the same instance in the same JVM.

Modules can store state in the module instance; however, state stored in a node is lost when the node's process method completes. To make state available for other nodes in the tree, nodes must return the state to the user or store it in the *shared state*.

AM uses Google's *Guice* dependency injection framework for authentication nodes and uses Guice to manage most of its object lifecycles. Use *just-in-time* bindings from the constructor to inject an object from Guice.

The following node-specific instances are available from Guice:

* @Assisted Realm

  The realm that the node is in.

* @Assisted UUID

  The unique ID of the node instance.

* @Assisted TreeMetadata

  The metadata for the tree that the node belongs to.

* \<T> @Assisted T

  The configuration object that is an instance of the interface specified in the `configClass` metadata parameter.

|   |                                                                                                     |
| - | --------------------------------------------------------------------------------------------------- |
|   | Any other objects in AM that are managed by Guice can also be obtained from within the constructor. |

|   |                                                                                                                                                                                                                                                                                                                                                                                        |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | The node interface supports sending one-time password (OTP) scripts in plain text notification only. You can't include HTML-rich notifications that use information from shared or transient state. If you need to support HTML notifications, you can use a Groovy script with a private HTTP client that makes the REST API calls and places the output in a scripted decision node. |

The following example is the configuration injection used by the [Debug node](https://docs.pingidentity.com/auth-node-ref/7.3/am-only/auth-node-debug.html):

```java
@Inject
public DebugNode(@Assisted DebugNode.Config config) {
  this.config = config;
  ...
}
```

For more information, refer to the [Inject](https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Inject.html) and [Assisted](https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/assistedinject/Assisted.html) annotation types in the *Google Guice Javadoc*.

## Use a cache

You can use Guice injection to cache information in a node by annotating the object that contains the cache with the `@Singleton` annotation, for example:

```java
@Node.Metadata(
  outcomeProvider = SingleOutcomeNode.OutcomeProvider.class,
  configClass = MyCustomNode.Config.class)
  public class MyCustomNode extends SingleOutcomeNode {

    public interface Config {
      String url();
    }

    private final Config config;
    private final MyCustomNodeCache cache;

    @Inject
    public MyCustomNode(@Assisted Config config, MyCustomNodeCache cache) {
      this.config = config;
      this.cache = cache;
    }

    @Override
    public Action process(TreeContext context) {
      CachedThing thing = cache.getThing(config.url());
      // implement node logic here
    }
}

@Singleton
class MyCustomNodeCache {
   private final LoadingCache<String, CachedThing> cache =
      CacheBuilder.newBuilder()
         .build(CacheLoader.from(url -> read(url)));

   public CachedThing get(String url) {
      return cache.get(url);
   }

   private CachedThing read(String url) {
      // Access resource and construct
   }
}
```

## Custom Guice bindings

If just-in-time bindings are not sufficient for your use case, you can add your own Guice module into the injector configuration by implementing your own `com.google.inject.Module` and registering it using the service loader mechanism. For example:

```java
// com/example/MyCustomModule.java
public class MyCustomModule extends AbstractModule {
   @Override
   protected void configure() {
      bind(Thing.class).to(MyThing.class);
      // and so on
   }
}
```

```java
// META-INF/services/com.google.inject.Module
// Refer to https://docs.oracle.com/javase/tutorial/ext/basics/spi.html
com.example.MyCustomModule
```

The `MyCustomModule` object will then be automatically configured as part of the injector creation.
