> For the complete documentation index, see [llms.txt](https://react-epic.gitbook.io/deviation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://react-epic.gitbook.io/deviation/advance/lazy-di-and-cyclic-di.md).

# Lazy DI and Cyclic DI

Sometimes, you may need to make two stores depend on each other. This may sound impossible for some other DI system but in Deviation, this is possible:

```typescript
@Inject({
    todoStore: TodoStore
})
export class CounterStore extends Store {
    get todoStore() {
        return this.props.todoStore
    }
    
    state = {
        count: 0
    }
}

@Inject({
    counterStore: CounterStore
})
export class TodoStore extends Store {
    get counterStore() {
        return this.props.counterStore
    }

    state = {
        todos: []
    }
}
```

As you might see, this won't work. Because both `CounterStore` and `TodoStore` are using decorator, so the classes are not hoisted. Which results in `undefined` when `TodoStore` is called:

```typescript
@Inject({
    todoStore: TodoStore // undefined
})
export class CounterStore extends Store { }
```

So, we will fix this by making Dependency Injection become lazy. Change the code to the following will fix the problem:

```typescript
@Inject({
    todoStore: () => TodoStore
})
export class CounterStore extends Store { }

@Inject({
    counterStore: () => CounterStore
})
export class TodoStore extends Store { }
```

## Caveats

Although Cyclic DI is powerful, there still some caveats that you have to notice. The following example is evil and won't work in Deviation:

```typescript
@Inject({
    todoStore: () => TodoStore
})
export class CounterStore extends Store {
    state = {
        count: this.props.todoStore.state.todos.length
    }
}

@Inject({
    counterStore: () => CounterStore
})
export class TodoStore extends Store {
    state = {
        todos: Array.from({ length: this.props.counterStore.state.count })
    }
}
```

To understand the mechanism of how Cyclic DI works in Deviation. We need to take a look at where we define these stores in our app:

```typescript
ReactDOM.render(
    <Deviation providers={[CounterStore, TodoStore]}>
        <AppRoot />
    </Deviation>,
    document.getElementById('root')
)
```

In this example, `CounterStore` is declared first, then the `CounterStore` will be initialized first.  `TodoStore` will be initialized then. That means `TodoStore` is unavailable to `CounterStore` until `TodoStore`, but `CounterStore` will be available to `TodoStore`. So you may ask, what if we want to access `TodoStore` from `CounterStore` when `TodoStore` have just been initialized. We can do that by using `storeDidMount`:

```typescript
export class CounterStore extends Store {
    get todoStore() {
        this.props.todoStore
    }

    storeDidMount() {
        this.setState({
            count: this.todoStore.state.todos.length
        })
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://react-epic.gitbook.io/deviation/advance/lazy-di-and-cyclic-di.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
