メインコンテンツまでスキップ

Instance Sharing Example

This page provides a concrete example of how Singleton, Scoped, and Transient lifetimes behave in a hierarchical scope structure.

Scenario: LifetimeScope Hierarchy

Suppose you have the following LifetimeScope structure:

And a simple service with a unique ID:

public class MyService
{
public Guid Id { get; } = Guid.NewGuid();
}

1. Singleton Registration

If MyService is registered as Singleton in the Root scope:

// RootLifetimeScope.cs
builder.Register<MyService>(Lifetime.Singleton);
ScopeMyService Instance (Id)Note
RootACreated in Root
Scene1AShared from Root
Popup1AShared from Root
Popup2AShared from Root
Scene2AShared from Root

Behavior: All scopes share the same instance (A). Singleton creates one instance per registration, shared across the hierarchy.


2. Scoped Registration (in Root only)

If MyService is registered as Scoped in the Root scope:

// RootLifetimeScope.cs
builder.Register<MyService>(Lifetime.Scoped);
ScopeMyService Instance (Id)Note
RootACreated in Root
Scene1BCreated in Scene1
Popup1CCreated in Popup1
Popup2DCreated in Popup2
Scene2ECreated in Scene2

Behavior:

  • Lifetime.Scoped means "One instance per LifetimeScope".
  • Even if registered in the Root, when a child scope (e.g., Scene1) resolves it, a new instance (B) is created and cached specifically for that child scope.
  • Descendants (Popup1) also create their own instances (C) because they are separate scopes resolving a Scoped registration.
注記

If you want to share an instance across a specific subtree (e.g., Scene1 and its children), you should use Singleton registration within Scene1, or use RegisterInstance to pass a specific instance.


3. Scoped Registration (in Popup1 as well)

If MyService is registered as Scoped in Root, AND also in Popup1:

// RootLifetimeScope.cs
builder.Register<MyService>(Lifetime.Scoped);

// Popup1LifetimeScope.cs
builder.Register<MyService>(Lifetime.Scoped);
ScopeMyService Instance (Id)Note
RootACreated in Root
Scene1BCreated in Scene1
Popup1FCreated in Popup1 (overridden)
Popup2DCreated in Popup2 (uses Root registration)
Scene2ECreated in Scene2

Behavior:

  • Popup1 registers its own MyService, so it uses that registration. Since it is Scoped, it creates instance F.
  • Popup2 does not have its own registration, so it uses the Root registration. Since it is Scoped, it creates instance D (separate from Scene1's instance).

4. Transient Registration (in Root)

If MyService is registered as Transient in the Root scope:

// RootLifetimeScope.cs
builder.Register<MyService>(Lifetime.Transient);
ScopeMyService Instance (Id)
RootG (new every resolve)
Scene1H (new every resolve)
Popup1I (new every resolve)
Popup2J (new every resolve)
Scene2K (new every resolve)

Behavior: Every time the service is resolved, a new instance is created, regardless of the scope.


Summary Table

LifetimeInstance Sharing Behavior
SingletonOne instance per registration. Shared across the hierarchy (Root and all descendants).
ScopedOne instance per LifetimeScope. Each scope (Parent, Child, etc.) gets its own unique instance when resolving.
TransientNew instance every time the service is resolved.