Skip to content

Commit 90813c9

Browse files
author
Nikolay Pianikov
committed
Update README
1 parent 118d8ee commit 90813c9

41 files changed

Lines changed: 906 additions & 180 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 283 additions & 33 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ dotnet run
451451
### Unity
452452
- [Unity Basics](readme/unity-basics.md)
453453
- [Unity with prefabs](readme/unity-with-prefabs.md)
454+
- [Unity scene scopes](readme/unity-scene-scopes.md)
454455
### Applications
455456
- Console
456457
- [Schrodinger's cat](readme/Console.md)
@@ -1863,42 +1864,6 @@ DI.Setup("Composition")
18631864

18641865
</details>
18651866

1866-
<details>
1867-
<summary>Code generation workflow</summary>
1868-
1869-
```mermaid
1870-
flowchart TD
1871-
start@{ shape: circle, label: Start }
1872-
setups[fa:fa-search DI setups analysis]
1873-
types["`fa:fa-search Types analysis
1874-
constructors/methods/properties/fields`"]
1875-
subgraph dep[Dependency graph]
1876-
option[fa:fa-search Selecting a next dependency set]
1877-
creating[fa:fa-cog Creating a dependency graph variant]
1878-
verification{fa:fa-check-circle Verification}
1879-
end
1880-
codeGeneration[fa:fa-code Code generation]
1881-
compilation[fa:fa-cog Compilation]
1882-
failed@{ shape: dbl-circ, label: Compilation failed }
1883-
success@{ shape: dbl-circ, label: Success }
1884-
1885-
start ==> setups
1886-
setups -.->|Has problems| failed
1887-
setups ==> types
1888-
types -.-> |Has problems| failed
1889-
types ==> option
1890-
option ==> creating
1891-
option -.-> |There are no other options| failed
1892-
creating ==> verification
1893-
verification -->|Has problems| option
1894-
verification ==>|Correct| codeGeneration
1895-
codeGeneration ==> compilation
1896-
compilation -.-> |Has problems| failed
1897-
compilation ==> success
1898-
```
1899-
1900-
</details>
1901-
19021867
<details>
19031868
<summary>Interface generation</summary>
19041869

@@ -1956,6 +1921,86 @@ See also:
19561921

19571922
</details>
19581923

1924+
<details>
1925+
<summary>Comments</summary>
1926+
1927+
Pure.DI can copy comments from setup calls into generated documentation comments for the composition class, composition arguments, and composition roots.
1928+
1929+
Use regular `//` comments before API calls when you want Pure.DI to include the text in the generated documentation:
1930+
1931+
```c#
1932+
DI.Setup("Composition")
1933+
.Bind<IService>().To<Service>()
1934+
// Provides the main service.
1935+
.Root<IService>("Service");
1936+
```
1937+
1938+
For `Setup(...)` and composition roots, XML documentation comments written with `///` replace the automatically generated documentation:
1939+
1940+
```c#
1941+
/// <summary>
1942+
/// Application composition.
1943+
/// </summary>
1944+
DI.Setup("Composition")
1945+
.Bind<IService>().To<Service>()
1946+
/// <summary>
1947+
/// Provides the main service.
1948+
/// </summary>
1949+
.Root<IService>("Service");
1950+
```
1951+
1952+
The generated root member keeps the user-defined XML documentation:
1953+
1954+
```c#
1955+
/// <summary>
1956+
/// Provides the main service.
1957+
/// </summary>
1958+
public IService Service
1959+
{
1960+
get { ... }
1961+
}
1962+
```
1963+
1964+
For other setup calls, such as `Arg<T>(...)`, comments are used as documentation text in the generated constructor documentation. Use regular `//` comments there unless you want XML markup to be shown as text.
1965+
1966+
</details>
1967+
1968+
<details>
1969+
<summary>Code generation workflow</summary>
1970+
1971+
```mermaid
1972+
flowchart TD
1973+
start@{ shape: circle, label: Start }
1974+
setups[fa:fa-search DI setups analysis]
1975+
types["`fa:fa-search Types analysis
1976+
constructors/methods/properties/fields`"]
1977+
subgraph dep[Dependency graph]
1978+
option[fa:fa-search Selecting a next dependency set]
1979+
creating[fa:fa-cog Creating a dependency graph variant]
1980+
verification{fa:fa-check-circle Verification}
1981+
end
1982+
codeGeneration[fa:fa-code Code generation]
1983+
compilation[fa:fa-cog Compilation]
1984+
failed@{ shape: dbl-circ, label: Compilation failed }
1985+
success@{ shape: dbl-circ, label: Success }
1986+
1987+
start ==> setups
1988+
setups -.->|Has problems| failed
1989+
setups ==> types
1990+
types -.-> |Has problems| failed
1991+
types ==> option
1992+
option ==> creating
1993+
option -.-> |There are no other options| failed
1994+
creating ==> verification
1995+
verification -->|Has problems| option
1996+
verification ==>|Correct| codeGeneration
1997+
codeGeneration ==> compilation
1998+
compilation -.-> |Has problems| failed
1999+
compilation ==> success
2000+
```
2001+
2002+
</details>
2003+
19592004
## Project template
19602005

19612006
Install the DI template [Pure.DI.Templates](https://www.nuget.org/packages/Pure.DI.Templates)
@@ -2102,7 +2147,7 @@ AI needs to understand the situation it’s in (context). This means knowing det
21022147
| --------------- | ---- | ------ |
21032148
| [AGENTS_SMALL.md](AGENTS_SMALL.md) | 62KB | 16K |
21042149
| [AGENTS_MEDIUM.md](AGENTS_MEDIUM.md) | 108KB | 27K |
2105-
| [AGENTS.md](AGENTS.md) | 394KB | 101K |
2150+
| [AGENTS.md](AGENTS.md) | 406KB | 104K |
21062151

21072152
For different IDEs, you can use the _AGENTS.md_ file as is by simply copying it to the root directory. For use with _JetBrains Rider_ and _Junie_, please refer to [these instructions](https://www.jetbrains.com/help/junie/customize-guidelines.html). For example, you can copy any _AGENTS.md_ file into your project (using _Pure.DI_) as _.junie/guidelines.md._
21082153
## How to contribute to Pure.DI

readme/Avalonia.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/AvaloniaApp)
44

5-
This example demonstrates the creation of an [Avalonia](https://avaloniaui.net/) application in the pure DI paradigm using the Pure.DI code generator.
5+
This example shows how to build an [Avalonia](https://avaloniaui.net/) application with Pure.DI, using generated composition roots for view models and infrastructure services instead of a runtime container.
6+
7+
> [!TIP]
8+
> XAML binds to virtual composition roots such as `App` and `Clock`. `Hint.Resolve` is disabled because the sample uses explicit roots instead of generated service-locator methods.
69
710
> [!NOTE]
8-
> [Another example](samples/SingleRootAvaloniaApp) with Avalonia shows how to create an application with a single composition root.
11+
> [Another example](/samples/SingleRootAvaloniaApp) with Avalonia shows how to create an application with a single composition root.
912
1013
The definition of the composition is in [Composition.cs](/samples/AvaloniaApp/Composition.cs). This class sets up how the object graphs will be created for the application. Do not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_:
1114

@@ -18,7 +21,10 @@ namespace AvaloniaApp;
1821

1922
partial class Composition
2023
{
24+
[System.Diagnostics.Conditional("DI")]
2125
private void Setup() => DI.Setup()
26+
.Hint(Hint.Resolve, "Off")
27+
2228
.Root<IAppViewModel>(nameof(App), kind: Virtual)
2329
.Root<IClockViewModel>(nameof(Clock), kind: Virtual)
2430

@@ -74,6 +80,8 @@ This markup fragment
7480

7581
creates a shared resource of type `Composition` with key _"Composition"_, which will be further used as a data context in the views.
7682

83+
Dispose the composition when the Avalonia lifetime exits. This releases singleton and scoped disposable instances created by Pure.DI.
84+
7785
The associated application [App.axaml.cs](/samples/AvaloniaApp/App.axaml.cs) class looks like:
7886

7987
```c#

readme/BlazorServerApp.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/BlazorServerApp)
44

5-
This example demonstrates the creation of a [Blazor Server](https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models#blazor-server) application in the pure DI paradigm using the Pure.DI code generator.
5+
This example shows how to build a [Blazor Server](https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models#blazor-server) application with Pure.DI while still integrating with the ASP.NET Core hosting and service-provider pipeline.
6+
7+
> [!NOTE]
8+
> The composition is installed as the host service-provider factory. Components can still use the standard Blazor/ASP.NET Core service infrastructure, while application view models come from generated Pure.DI roots.
69
710
The composition setup file is [Composition.cs](/samples/BlazorServerApp/Composition.cs):
811

@@ -15,7 +18,8 @@ namespace BlazorServerApp;
1518

1619
partial class Composition : ServiceProviderFactory<Composition>
1720
{
18-
private void Setup() => DI.Setup()
21+
[System.Diagnostics.Conditional("DI")]
22+
private static void Setup() => DI.Setup()
1923
.Root<IAppViewModel>()
2024
.Root<IClockViewModel>()
2125

@@ -29,7 +33,7 @@ partial class Composition : ServiceProviderFactory<Composition>
2933
}
3034
```
3135

32-
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself.
36+
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself. Only registered roots can be resolved through the Microsoft `IServiceProvider`, so each view model consumed by the host must be listed with `Root`.
3337

3438
The web application entry point is in the [Program.cs](/samples/BlazorServerApp/Program.cs) file:
3539

readme/BlazorWebAssemblyApp.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
[Here's an example](https://devteam.github.io/Pure.DI/) on GitHub Pages.
66

7-
This example demonstrates the creation of a [Blazor WebAssembly](https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models#blazor-webassembly) application in the pure DI paradigm using the Pure.DI code generator.
7+
This example shows how to build a [Blazor WebAssembly](https://learn.microsoft.com/en-us/aspnet/core/blazor/hosting-models#blazor-webassembly) application with Pure.DI, exposing generated roots through the WebAssembly host container.
8+
9+
> [!NOTE]
10+
> WebAssembly uses `builder.ConfigureContainer(composition)` instead of `UseServiceProviderFactory`. Keep browser-specific services, such as `HttpClient`, registered in the normal Blazor service collection.
811
912
The composition setup file is [Composition.cs](/samples/BlazorWebAssemblyApp/Composition.cs):
1013

@@ -17,7 +20,8 @@ namespace BlazorWebAssemblyApp;
1720

1821
partial class Composition : ServiceProviderFactory<Composition>
1922
{
20-
private void Setup() => DI.Setup()
23+
[System.Diagnostics.Conditional("DI")]
24+
private static void Setup() => DI.Setup()
2125
.Root<IAppViewModel>()
2226
.Root<IClockViewModel>()
2327

@@ -31,7 +35,7 @@ partial class Composition : ServiceProviderFactory<Composition>
3135
}
3236
```
3337

34-
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself.
38+
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself. Only registered roots can be resolved through the Microsoft `IServiceProvider`, so each view model consumed by the host must be listed with `Root`.
3539

3640
The web application entry point is in the [Program.cs](/samples/BlazorWebAssemblyApp/Program.cs) file:
3741

readme/Console.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/ShroedingersCat)
44

5-
This example demonstrates the creation of a simple console application in the pure DI paradigm using the Pure.DI code generator. All code is in [one file](/samples/ShroedingersCat/Program.cs) for easy reading:
5+
This example shows the smallest Pure.DI console application: abstractions, implementations, bindings, and the composition root are kept in one place so the generated object graph is easy to inspect. All code is in [one file](/samples/ShroedingersCat/Program.cs) for easy reading:
6+
7+
> [!TIP]
8+
> The `Setup` method is a compile-time hint for the generator. It is not called at runtime, so it can stay private and contain only composition configuration.
69
710
```c#
811
using Pure.DI;

readme/ConsoleNativeAOT.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/ShroedingersCatNativeAOT)
44

5-
This example is very similar to the [simple console application](ConsoleTemplate.md), except that this is a [native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) application.
5+
This example shows how the simple console composition can be published as a [native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) application. Pure.DI generates plain C# object creation code, so the dependency graph remains friendly to trimming and ahead-of-time compilation.
6+
7+
> [!TIP]
8+
> Native AOT works best when construction is explicit and reflection-light. Prefer generated roots and bindings over runtime service-location patterns in AOT samples.
69
710
The [project file](/samples/ShroedingersCatNativeAOT/ShroedingersCatNativeAOT.csproj) looks like this:
811

readme/ConsoleTopLevelStatements.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/ShroedingersCatTopLevelStatements)
44

5-
This example is very similar to the [simple console application](ConsoleTemplate.md), except that the composition is [defined](/samples/ShroedingersCatTopLevelStatements/Program.cs) as top-level statements and looks a little less verbose:
5+
This example shows the same object graph as the [simple console application](ConsolePageTemplate.md), but defines the composition directly in [Program.cs](/samples/ShroedingersCatTopLevelStatements/Program.cs) with top-level statements. It keeps the setup compact while still producing the same compile-time validated composition:
6+
7+
> [!TIP]
8+
> Top-level statements are convenient for small samples. For larger applications, move setup into a partial composition class so roots, lifetimes, and infrastructure bindings are easier to navigate.
69
710
```c#
811
using Pure.DI;

readme/EntityFramework.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/EF)
44

5-
This example demonstrates the creation of an Entity Framework application in the pure DI paradigm using the Pure.DI code generator.
5+
This example shows how to combine Pure.DI with Entity Framework services supplied by Microsoft dependency injection. Pure.DI builds the application graph, while the external service provider supplies the `DbContext` and EF infrastructure.
6+
7+
> [!TIP]
8+
> `PersonsDbContext` is intentionally not bound in Pure.DI. It is requested from the external `ServiceProvider`, while Pure.DI owns the application root and factories such as `Func<Person>`.
69
710
The composition setup file is [Composition.cs](/samples/EF/Composition.cs):
811

@@ -15,6 +18,7 @@ namespace EF;
1518

1619
partial class Composition : ServiceProviderFactory<Composition>
1720
{
21+
[System.Diagnostics.Conditional("DI")]
1822
private void Setup() => DI.Setup()
1923
.Root<Program>(nameof(Root))
2024

@@ -23,7 +27,7 @@ partial class Composition : ServiceProviderFactory<Composition>
2327
}
2428
```
2529

26-
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself.
30+
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself. When Pure.DI cannot resolve framework services such as `DbContext`, `ServiceProviderFactory<T>` delegates those requests to the configured Microsoft dependency injection provider.
2731

2832
The console application entry point is in the [Program.cs](/samples/EF/Program.cs) file:
2933

@@ -79,6 +83,8 @@ partial class Program(
7983
}
8084
```
8185

86+
The external service provider should be configured before resolving `composition.Root`. If a required EF service is missing, Pure.DI will fail when the root is created instead of hiding the missing registration.
87+
8288
The [project file](/samples/EF/EF.csproj) looks like this:
8389

8490
```xml

readme/GrpcService.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](/samples/GrpcService)
44

5-
This example demonstrates the creation of a gRPC service in the pure DI paradigm using the Pure.DI code generator.
5+
This example shows how to build a gRPC service with Pure.DI and ASP.NET Core hosting. The generated composition exposes the service and application dependencies through the Microsoft service-provider pipeline.
6+
7+
> [!TIP]
8+
> The gRPC service type itself is a composition root. Keep the ASP.NET Core gRPC registration (`AddGrpc`) in `Program.cs`, and let Pure.DI create the service graph.
69
710
The composition setup file is [Composition.cs](/samples/GrpcService/Composition.cs):
811

@@ -15,7 +18,7 @@ namespace GrpcService;
1518

1619
partial class Composition : ServiceProviderFactory<Composition>
1720
{
18-
private void Setup() => DI.Setup()
21+
private static void Setup() => DI.Setup()
1922
.Root<ClockService>()
2023

2124
.Bind().As(Singleton).To<ClockViewModel>()
@@ -28,7 +31,7 @@ partial class Composition : ServiceProviderFactory<Composition>
2831
}
2932
```
3033

31-
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself.
34+
The composition class inherits from `ServiceProviderFactory<T>`, where `T` is the composition class itself. Only registered roots can be resolved through the Microsoft `IServiceProvider`, so the gRPC service type is declared as a root.
3235

3336
The web application entry point is in the [Program.cs](/samples/GrpcService/Program.cs) file:
3437

0 commit comments

Comments
 (0)