Skip to content

Commit a2db8fb

Browse files
#91 Simplified parametric Func-based injection
1 parent 028bc6e commit a2db8fb

40 files changed

Lines changed: 434 additions & 307 deletions

AI_CONTEXT_LARGE.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ To run the above code, the following NuGet packages must be added:
470470

471471
## Injections as required
472472

473+
This example demonstrates using dependency injection with Pure.DI to dynamically create dependencies as needed via a factory function. The code defines a service (`Service`) that requires multiple instances of a dependency (`Dependency`). Instead of injecting pre-created instances, the service receives a `Func<IDependency>` factory delegate, allowing it to generate dependencies on demand.
474+
473475
```c#
474476
using Shouldly;
475477
using Pure.DI;
@@ -509,9 +511,17 @@ To run the above code, the following NuGet packages must be added:
509511
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
510512
- [Shouldly](https://www.nuget.org/packages/Shouldly)
511513

514+
Key elements:
515+
- `Dependency` is bound to the `IDependency` interface, and `Service` is bound to `IService`.
516+
- The `Service` constructor accepts `Func<IDependency>`, enabling deferred creation of dependencies.
517+
- The `Service` calls the factory twice, resulting in two distinct `Dependency` instances stored in its `Dependencies` collection.
518+
519+
This approach showcases how factories can control dependency lifetime and instance creation timing in a DI container. The Pure.DI configuration ensures the factory resolves new `IDependency` instances each time it's invoked, achieving "injections as required" functionality.
512520

513521
## Injections as required with arguments
514522

523+
This example illustrates dependency injection with parameterized factory functions using Pure.DI, where dependencies are created with runtime-provided arguments. The scenario features a service that generates dependencies with specific IDs passed during instantiation.
524+
515525
```c#
516526
using Shouldly;
517527
using Pure.DI;
@@ -560,6 +570,15 @@ To run the above code, the following NuGet packages must be added:
560570
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
561571
- [Shouldly](https://www.nuget.org/packages/Shouldly)
562572

573+
Key components:
574+
- `Dependency` class accepts an int id constructor argument, stored in its `Id` property.
575+
- `Service` receives `Func<int, IDependency>` delegate, enabling creation of dependencies with dynamic values.
576+
- `Service` creates two dependencies using the factory – one with ID `33`, another with ID `99`.
577+
578+
Delayed dependency instantiation:
579+
- Injection of dependencies requiring runtime parameters
580+
- Creation of distinct instances with different configurations
581+
- Type-safe resolution of dependencies with constructor arguments
563582

564583
## Class arguments
565584

@@ -1377,6 +1396,8 @@ To run the above code, the following NuGet packages must be added:
13771396

13781397
## Overrides
13791398

1399+
This example demonstrates advanced dependency injection techniques using Pure.DI's override mechanism to customize dependency instantiation with runtime arguments and tagged parameters. The implementation creates multiple `IDependency` instances with values manipulated through explicit overrides.
1400+
13801401
```c#
13811402
using Shouldly;
13821403
using Pure.DI;
@@ -12150,6 +12171,15 @@ DI.Setup("Composition")
1215012171
</blockquote></details>
1215112172

1215212173

12174+
<details><summary>Field UniqueTag</summary><blockquote>
12175+
12176+
Atomically generated smart tag with value "UniqueTag".
12177+
It's used for:
12178+
12179+
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
12180+
</blockquote></details>
12181+
12182+
1215312183
<details><summary>Field Overrider</summary><blockquote>
1215412184

1215512185
Atomically generated smart tag with value "Overrider".
@@ -12168,39 +12198,39 @@ Atomically generated smart tag with value "Cleaner".
1216812198
</blockquote></details>
1216912199

1217012200

12171-
<details><summary>Field CompositionClass</summary><blockquote>
12201+
<details><summary>Field Override</summary><blockquote>
1217212202

12173-
Atomically generated smart tag with value "CompositionClass".
12203+
Atomically generated smart tag with value "Override".
1217412204
It's used for:
1217512205

12176-
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
12206+
class _Generator__OverrideIdProvider_ <-- _IIdGenerator_(Override) -- _IdGenerator_ as _PerResolve_
1217712207
</blockquote></details>
1217812208

1217912209

12180-
<details><summary>Field UniqueTag</summary><blockquote>
12210+
<details><summary>Field UsingDeclarations</summary><blockquote>
1218112211

12182-
Atomically generated smart tag with value "UniqueTag".
12212+
Atomically generated smart tag with value "UsingDeclarations".
1218312213
It's used for:
1218412214

12185-
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
12215+
class _Generator__CompositionClassBuilder_ <-- _IBuilder`2_(UsingDeclarations) -- _UsingDeclarationsBuilder_ as _PerBlock_
1218612216
</blockquote></details>
1218712217

1218812218

12189-
<details><summary>Field GenericType</summary><blockquote>
12219+
<details><summary>Field CompositionClass</summary><blockquote>
1219012220

12191-
Atomically generated smart tag with value "GenericType".
12221+
Atomically generated smart tag with value "CompositionClass".
1219212222
It's used for:
1219312223

12194-
class _Generator__TypeResolver_ <-- _IIdGenerator_(GenericType) -- _IdGenerator_ as _PerResolve_
12224+
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
1219512225
</blockquote></details>
1219612226

1219712227

12198-
<details><summary>Field UsingDeclarations</summary><blockquote>
12228+
<details><summary>Field GenericType</summary><blockquote>
1219912229

12200-
Atomically generated smart tag with value "UsingDeclarations".
12230+
Atomically generated smart tag with value "GenericType".
1220112231
It's used for:
1220212232

12203-
class _Generator__CompositionClassBuilder_ <-- _IBuilder`2_(UsingDeclarations) -- _UsingDeclarationsBuilder_ as _PerBlock_
12233+
class _Generator__TypeResolver_ <-- _IIdGenerator_(GenericType) -- _IdGenerator_ as _PerResolve_
1220412234
</blockquote></details>
1220512235

1220612236

@@ -12211,15 +12241,6 @@ Atomically generated smart tag with value "Injection".
1221112241
</blockquote></details>
1221212242

1221312243

12214-
<details><summary>Field Override</summary><blockquote>
12215-
12216-
Atomically generated smart tag with value "Override".
12217-
It's used for:
12218-
12219-
class _Generator__OverrideIdProvider_ <-- _IIdGenerator_(Override) -- _IdGenerator_ as _PerResolve_
12220-
</blockquote></details>
12221-
12222-
1222312244
</blockquote></details>
1222412245

1222512246

AI_CONTEXT_MEDIUM.md

Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ To run the above code, the following NuGet packages must be added:
470470

471471
## Injections as required
472472

473+
This example demonstrates using dependency injection with Pure.DI to dynamically create dependencies as needed via a factory function. The code defines a service (`Service`) that requires multiple instances of a dependency (`Dependency`). Instead of injecting pre-created instances, the service receives a `Func<IDependency>` factory delegate, allowing it to generate dependencies on demand.
474+
473475
```c#
474476
using Shouldly;
475477
using Pure.DI;
@@ -509,9 +511,17 @@ To run the above code, the following NuGet packages must be added:
509511
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
510512
- [Shouldly](https://www.nuget.org/packages/Shouldly)
511513

514+
Key elements:
515+
- `Dependency` is bound to the `IDependency` interface, and `Service` is bound to `IService`.
516+
- The `Service` constructor accepts `Func<IDependency>`, enabling deferred creation of dependencies.
517+
- The `Service` calls the factory twice, resulting in two distinct `Dependency` instances stored in its `Dependencies` collection.
518+
519+
This approach showcases how factories can control dependency lifetime and instance creation timing in a DI container. The Pure.DI configuration ensures the factory resolves new `IDependency` instances each time it's invoked, achieving "injections as required" functionality.
512520

513521
## Injections as required with arguments
514522

523+
This example illustrates dependency injection with parameterized factory functions using Pure.DI, where dependencies are created with runtime-provided arguments. The scenario features a service that generates dependencies with specific IDs passed during instantiation.
524+
515525
```c#
516526
using Shouldly;
517527
using Pure.DI;
@@ -560,6 +570,15 @@ To run the above code, the following NuGet packages must be added:
560570
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
561571
- [Shouldly](https://www.nuget.org/packages/Shouldly)
562572

573+
Key components:
574+
- `Dependency` class accepts an int id constructor argument, stored in its `Id` property.
575+
- `Service` receives `Func<int, IDependency>` delegate, enabling creation of dependencies with dynamic values.
576+
- `Service` creates two dependencies using the factory – one with ID `33`, another with ID `99`.
577+
578+
Delayed dependency instantiation:
579+
- Injection of dependencies requiring runtime parameters
580+
- Creation of distinct instances with different configurations
581+
- Type-safe resolution of dependencies with constructor arguments
563582

564583
## Class arguments
565584

@@ -3805,59 +3824,6 @@ To run the above code, the following NuGet packages must be added:
38053824
- [Shouldly](https://www.nuget.org/packages/Shouldly)
38063825

38073826

3808-
## Custom generic argument attribute
3809-
3810-
```c#
3811-
using Shouldly;
3812-
using Pure.DI;
3813-
3814-
DI.Setup(nameof(Composition))
3815-
// Registers custom generic argument
3816-
.GenericTypeArgumentAttribute<MyGenericTypeArgumentAttribute>()
3817-
.Bind<IDependency<TTMy>>().To<Dependency<TTMy>>()
3818-
.Bind<IService>().To<Service>()
3819-
3820-
// Composition root
3821-
.Root<IService>("Root");
3822-
3823-
var composition = new Composition();
3824-
var service = composition.Root;
3825-
service.IntDependency.ShouldBeOfType<Dependency<int>>();
3826-
service.StringDependency.ShouldBeOfType<Dependency<string>>();
3827-
3828-
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)]
3829-
class MyGenericTypeArgumentAttribute : Attribute;
3830-
3831-
[MyGenericTypeArgument]
3832-
interface TTMy;
3833-
3834-
interface IDependency<T>;
3835-
3836-
class Dependency<T> : IDependency<T>;
3837-
3838-
interface IService
3839-
{
3840-
IDependency<int> IntDependency { get; }
3841-
3842-
IDependency<string> StringDependency { get; }
3843-
}
3844-
3845-
class Service(
3846-
IDependency<int> intDependency,
3847-
IDependency<string> stringDependency)
3848-
: IService
3849-
{
3850-
public IDependency<int> IntDependency { get; } = intDependency;
3851-
3852-
public IDependency<string> StringDependency { get; } = stringDependency;
3853-
}
3854-
```
3855-
3856-
To run the above code, the following NuGet packages must be added:
3857-
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
3858-
- [Shouldly](https://www.nuget.org/packages/Shouldly)
3859-
3860-
38613827
## Decorator
38623828

38633829
Interception is the ability to intercept calls between objects in order to enrich or change their behavior, but without having to change their code. A prerequisite for interception is weak binding. That is, if programming is abstraction-based, the underlying implementation can be transformed or improved by "packaging" it into other implementations of the same abstraction. At its core, intercept is an application of the Decorator design pattern. This pattern provides a flexible alternative to inheritance by dynamically "attaching" additional responsibility to an object. Decorator "packs" one implementation of an abstraction into another implementation of the same abstraction like a "matryoshka doll".

AI_CONTEXT_SMALL.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ To run the above code, the following NuGet packages must be added:
470470

471471
## Injections as required
472472

473+
This example demonstrates using dependency injection with Pure.DI to dynamically create dependencies as needed via a factory function. The code defines a service (`Service`) that requires multiple instances of a dependency (`Dependency`). Instead of injecting pre-created instances, the service receives a `Func<IDependency>` factory delegate, allowing it to generate dependencies on demand.
474+
473475
```c#
474476
using Shouldly;
475477
using Pure.DI;
@@ -509,9 +511,17 @@ To run the above code, the following NuGet packages must be added:
509511
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
510512
- [Shouldly](https://www.nuget.org/packages/Shouldly)
511513

514+
Key elements:
515+
- `Dependency` is bound to the `IDependency` interface, and `Service` is bound to `IService`.
516+
- The `Service` constructor accepts `Func<IDependency>`, enabling deferred creation of dependencies.
517+
- The `Service` calls the factory twice, resulting in two distinct `Dependency` instances stored in its `Dependencies` collection.
518+
519+
This approach showcases how factories can control dependency lifetime and instance creation timing in a DI container. The Pure.DI configuration ensures the factory resolves new `IDependency` instances each time it's invoked, achieving "injections as required" functionality.
512520

513521
## Injections as required with arguments
514522

523+
This example illustrates dependency injection with parameterized factory functions using Pure.DI, where dependencies are created with runtime-provided arguments. The scenario features a service that generates dependencies with specific IDs passed during instantiation.
524+
515525
```c#
516526
using Shouldly;
517527
using Pure.DI;
@@ -560,6 +570,15 @@ To run the above code, the following NuGet packages must be added:
560570
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
561571
- [Shouldly](https://www.nuget.org/packages/Shouldly)
562572

573+
Key components:
574+
- `Dependency` class accepts an int id constructor argument, stored in its `Id` property.
575+
- `Service` receives `Func<int, IDependency>` delegate, enabling creation of dependencies with dynamic values.
576+
- `Service` creates two dependencies using the factory – one with ID `33`, another with ID `99`.
577+
578+
Delayed dependency instantiation:
579+
- Injection of dependencies requiring runtime parameters
580+
- Creation of distinct instances with different configurations
581+
- Type-safe resolution of dependencies with constructor arguments
563582

564583
## Transient
565584

README.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,6 +3450,15 @@ DI.Setup("Composition")
34503450
</blockquote></details>
34513451

34523452

3453+
<details><summary>Field UniqueTag</summary><blockquote>
3454+
3455+
Atomically generated smart tag with value "UniqueTag".
3456+
It's used for:
3457+
3458+
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
3459+
</blockquote></details>
3460+
3461+
34533462
<details><summary>Field Overrider</summary><blockquote>
34543463

34553464
Atomically generated smart tag with value "Overrider".
@@ -3468,39 +3477,39 @@ Atomically generated smart tag with value "Cleaner".
34683477
</blockquote></details>
34693478

34703479

3471-
<details><summary>Field CompositionClass</summary><blockquote>
3480+
<details><summary>Field Override</summary><blockquote>
34723481

3473-
Atomically generated smart tag with value "CompositionClass".
3482+
Atomically generated smart tag with value "Override".
34743483
It's used for:
34753484

3476-
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
3485+
class _Generator__OverrideIdProvider_ <-- _IIdGenerator_(Override) -- _IdGenerator_ as _PerResolve_
34773486
</blockquote></details>
34783487

34793488

3480-
<details><summary>Field UniqueTag</summary><blockquote>
3489+
<details><summary>Field UsingDeclarations</summary><blockquote>
34813490

3482-
Atomically generated smart tag with value "UniqueTag".
3491+
Atomically generated smart tag with value "UsingDeclarations".
34833492
It's used for:
34843493

3485-
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
3494+
class _Generator__CompositionClassBuilder_ <-- _IBuilder`2_(UsingDeclarations) -- _UsingDeclarationsBuilder_ as _PerBlock_
34863495
</blockquote></details>
34873496

34883497

3489-
<details><summary>Field GenericType</summary><blockquote>
3498+
<details><summary>Field CompositionClass</summary><blockquote>
34903499

3491-
Atomically generated smart tag with value "GenericType".
3500+
Atomically generated smart tag with value "CompositionClass".
34923501
It's used for:
34933502

3494-
class _Generator__TypeResolver_ <-- _IIdGenerator_(GenericType) -- _IdGenerator_ as _PerResolve_
3503+
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
34953504
</blockquote></details>
34963505

34973506

3498-
<details><summary>Field UsingDeclarations</summary><blockquote>
3507+
<details><summary>Field GenericType</summary><blockquote>
34993508

3500-
Atomically generated smart tag with value "UsingDeclarations".
3509+
Atomically generated smart tag with value "GenericType".
35013510
It's used for:
35023511

3503-
class _Generator__CompositionClassBuilder_ <-- _IBuilder`2_(UsingDeclarations) -- _UsingDeclarationsBuilder_ as _PerBlock_
3512+
class _Generator__TypeResolver_ <-- _IIdGenerator_(GenericType) -- _IdGenerator_ as _PerResolve_
35043513
</blockquote></details>
35053514

35063515

@@ -3511,15 +3520,6 @@ Atomically generated smart tag with value "Injection".
35113520
</blockquote></details>
35123521

35133522

3514-
<details><summary>Field Override</summary><blockquote>
3515-
3516-
Atomically generated smart tag with value "Override".
3517-
It's used for:
3518-
3519-
class _Generator__OverrideIdProvider_ <-- _IIdGenerator_(Override) -- _IdGenerator_ as _PerResolve_
3520-
</blockquote></details>
3521-
3522-
35233523
</blockquote></details>
35243524

35253525

@@ -5260,9 +5260,9 @@ Contextual AI needs to understand the situation it’s in. This means knowing de
52605260

52615261
| AI Context file | Size | Tokens |
52625262
| --------------- | ---- | ------ |
5263-
| [AI_CONTEXT_SMALL.md](AI_CONTEXT_SMALL.md) | 27KB | 7K |
5264-
| [AI_CONTEXT_MEDIUM.md](AI_CONTEXT_MEDIUM.md) | 123KB | 31K |
5265-
| [AI_CONTEXT_LARGE.md](AI_CONTEXT_LARGE.md) | 377KB | 96K |
5263+
| [AI_CONTEXT_SMALL.md](AI_CONTEXT_SMALL.md) | 29KB | 7K |
5264+
| [AI_CONTEXT_MEDIUM.md](AI_CONTEXT_MEDIUM.md) | 124KB | 31K |
5265+
| [AI_CONTEXT_LARGE.md](AI_CONTEXT_LARGE.md) | 379KB | 97K |
52665266
## How to contribute to Pure.DI
52675267

52685268
Thank you for your interest in contributing to the Pure.DI project! First of all, if you are going to make a big change or feature, please open a problem first. That way, we can coordinate and understand if the change you're going to work on fits with current priorities and if we can commit to reviewing and merging it within a reasonable timeframe. We don't want you to waste a lot of your valuable time on something that may not align with what we want for Pure.DI.

build/Core/FilterTools.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public bool AddExample(AIContextSize size, int priority, string groupName)
1313
case AIContextSize.Small
1414
when priority <= 4 && groupName is "Basics" or "Lifetimes":
1515
case AIContextSize.Medium
16-
when priority <= 12 && groupName is not "Advanced" and not "Hints":
16+
when priority <= 11 && groupName is not "Advanced" and not "Hints":
1717
case AIContextSize.Large:
1818
return true;
1919

readme/async-disposable-scope.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ partial class Composition: IDisposable, IAsyncDisposable
170170
() =>
171171
{
172172
Composition transientComposition3 = this;
173-
Session localValue143 = new Session(transientComposition3);
174-
return localValue143;
173+
Session localValue149 = new Session(transientComposition3);
174+
return localValue149;
175175
});
176176
return new Program(perBlockFunc1);
177177
}

0 commit comments

Comments
 (0)