Skip to content

Commit 3eaff83

Browse files
author
Nikolay Pianikov
committed
Update README
1 parent dcd0639 commit 3eaff83

73 files changed

Lines changed: 764 additions & 428 deletions

File tree

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: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4741,6 +4741,82 @@ To run the above code, the following NuGet packages must be added:
47414741
>[!NOTE]
47424742
>Overriding BCL bindings allows you to provide custom implementations for standard types, enabling specialized behavior for your application.
47434743
4744+
## Default BCL bindings
4745+
4746+
Pure.DI provides default bindings for commonly used .NET BCL types, so they can be injected without extra setup code.
4747+
4748+
```c#
4749+
using Shouldly;
4750+
using Pure.DI;
4751+
using System.Globalization;
4752+
using System.Security.Cryptography;
4753+
using System.Text.Json;
4754+
4755+
DI.Setup(nameof(Composition))
4756+
.Root<ReportService>("ReportService");
4757+
4758+
var composition = new Composition();
4759+
var reportService = composition.ReportService;
4760+
4761+
reportService.JsonOptions.ShouldBe(JsonSerializerOptions.Default);
4762+
reportService.Culture.ShouldBe(CultureInfo.CurrentCulture);
4763+
reportService.FormatProvider.ShouldBe(reportService.Culture);
4764+
reportService.CompareInfo.ShouldBe(CultureInfo.CurrentCulture.CompareInfo);
4765+
reportService.StringComparer.ShouldBe(StringComparer.Ordinal);
4766+
reportService.StringComparison.ShouldBe(StringComparison.Ordinal);
4767+
reportService.TimeProvider.ShouldBe(TimeProvider.System);
4768+
reportService.Completion.Task.CreationOptions
4769+
.HasFlag(TaskCreationOptions.RunContinuationsAsynchronously)
4770+
.ShouldBeTrue();
4771+
4772+
var bytes = new byte[4];
4773+
reportService.RandomNumberGenerator.GetBytes(bytes);
4774+
bytes.Length.ShouldBe(4);
4775+
4776+
interface IPlugin;
4777+
4778+
class SearchPlugin : IPlugin;
4779+
4780+
class ExportPlugin : IPlugin;
4781+
4782+
class ReportService(
4783+
JsonSerializerOptions jsonOptions,
4784+
CultureInfo culture,
4785+
IFormatProvider formatProvider,
4786+
CompareInfo compareInfo,
4787+
StringComparer stringComparer,
4788+
StringComparison stringComparison,
4789+
TimeProvider timeProvider,
4790+
TaskCompletionSource<string> completion,
4791+
RandomNumberGenerator randomNumberGenerator)
4792+
{
4793+
public JsonSerializerOptions JsonOptions { get; } = jsonOptions;
4794+
4795+
public CultureInfo Culture { get; } = culture;
4796+
4797+
public IFormatProvider FormatProvider { get; } = formatProvider;
4798+
4799+
public CompareInfo CompareInfo { get; } = compareInfo;
4800+
4801+
public StringComparer StringComparer { get; } = stringComparer;
4802+
4803+
public StringComparison StringComparison { get; } = stringComparison;
4804+
4805+
public TimeProvider TimeProvider { get; } = timeProvider;
4806+
4807+
public TaskCompletionSource<string> Completion { get; } = completion;
4808+
4809+
public RandomNumberGenerator RandomNumberGenerator { get; } = randomNumberGenerator;
4810+
}
4811+
```
4812+
4813+
To run the above code, the following NuGet packages must be added:
4814+
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
4815+
- [Shouldly](https://www.nuget.org/packages/Shouldly)
4816+
4817+
>[!NOTE]
4818+
>Default BCL bindings can still be overridden in the composition when an application needs a different policy.
4819+
47444820
## Generics
47454821

47464822
Generic types are also supported.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ dotnet run
353353
- [Service provider](readme/service-provider.md)
354354
- [Service provider with scope](readme/service-provider-with-scope.md)
355355
- [Overriding the BCL binding](readme/overriding-the-bcl-binding.md)
356+
- [Default BCL bindings](readme/default-bcl-bindings.md)
356357
### Generics
357358
- [Generics](readme/generics.md)
358359
- [Generic composition roots](readme/generic-composition-roots.md)
@@ -2407,7 +2408,7 @@ AI needs to understand the situation it’s in (context). This means knowing det
24072408
| --------------- | ---- | ------ |
24082409
| [AGENTS_SMALL.md](AGENTS_SMALL.md) | 62KB | 16K |
24092410
| [AGENTS_MEDIUM.md](AGENTS_MEDIUM.md) | 112KB | 28K |
2410-
| [AGENTS.md](AGENTS.md) | 411KB | 105K |
2411+
| [AGENTS.md](AGENTS.md) | 413KB | 105K |
24112412

24122413
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._
24132414
## How to contribute to Pure.DI

readme/FuncDetails.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ partial class Func
8888
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8989
() =>
9090
{
91+
// Creates a deferred value
9192
return new Service3(new Service4(), new Service4());
9293
});
9394
return new CompositionRoot(new Service1(new Service2Func(perBlockFuncIService3)), new Service2Func(perBlockFuncIService3), new Service2Func(perBlockFuncIService3), new Service2Func(perBlockFuncIService3), new Service3(new Service4(), new Service4()), new Service4(), new Service4());

readme/SingletonDetails.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ partial class Singleton
7777
{
7878
private Singleton _root;
7979

80-
private Service1? _scopedService160;
81-
private Service4? _scopedService463;
80+
private Service1? _scopedService170;
81+
private Service4? _scopedService473;
8282

8383
[OrdinalAttribute(256)]
8484
public Singleton()
@@ -95,22 +95,22 @@ partial class Singleton
9595
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9696
public partial CompositionRoot TestPureDIByCR()
9797
{
98-
if (_scopedService160 is null)
98+
if (_scopedService170 is null)
9999
{
100-
if (_scopedService463 is null)
100+
if (_scopedService473 is null)
101101
{
102-
_scopedService463 = new Service4();
102+
_scopedService473 = new Service4();
103103
}
104104

105-
_scopedService160 = new Service1(new Service2(new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463)));
105+
_scopedService170 = new Service1(new Service2(new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473)));
106106
}
107107

108-
if (_scopedService463 is null)
108+
if (_scopedService473 is null)
109109
{
110-
_scopedService463 = new Service4();
110+
_scopedService473 = new Service4();
111111
}
112112

113-
return new CompositionRoot(_scopedService160, new Service2(new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463)), new Service2(new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463)), new Service2(new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463), new Service3(_scopedService463, _scopedService463)), new Service3(_scopedService463, _scopedService463), _scopedService463, _scopedService463);
113+
return new CompositionRoot(_scopedService170, new Service2(new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473)), new Service2(new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473)), new Service2(new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473), new Service3(_scopedService473, _scopedService473)), new Service3(_scopedService473, _scopedService473), _scopedService473, _scopedService473);
114114
}
115115

116116
[MethodImpl(MethodImplOptions.AggressiveInlining)]

readme/accumulators.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ partial class Composition
101101
private readonly Object _lock = new Object();
102102
#endif
103103

104-
private NetworkDataSource? _singletonNetworkDataSource64;
104+
private NetworkDataSource? _singletonNetworkDataSource74;
105105

106106
public (IDashboard dashboard, TelemetryRegistry registry) Root
107107
{
@@ -110,15 +110,15 @@ partial class Composition
110110
{
111111
var perBlockTelemetryRegistry = new TelemetryRegistry();
112112
var perBlockSqlDataSource = new SqlDataSource();
113-
if (_singletonNetworkDataSource64 is null)
113+
if (_singletonNetworkDataSource74 is null)
114114
lock (_lock)
115-
if (_singletonNetworkDataSource64 is null)
115+
if (_singletonNetworkDataSource74 is null)
116116
{
117-
NetworkDataSource _singletonNetworkDataSource64Temp;
118-
_singletonNetworkDataSource64Temp = new NetworkDataSource();
119-
perBlockTelemetryRegistry.Add(_singletonNetworkDataSource64Temp);
117+
NetworkDataSource _singletonNetworkDataSource74Temp;
118+
_singletonNetworkDataSource74Temp = new NetworkDataSource();
119+
perBlockTelemetryRegistry.Add(_singletonNetworkDataSource74Temp);
120120
Thread.MemoryBarrier();
121-
_singletonNetworkDataSource64 = _singletonNetworkDataSource64Temp;
121+
_singletonNetworkDataSource74 = _singletonNetworkDataSource74Temp;
122122
}
123123

124124
var transientSqlDataSource = new SqlDataSource();
@@ -127,7 +127,7 @@ partial class Composition
127127
perBlockTelemetryRegistry.Add(transientSqlDataSource);
128128
}
129129

130-
var transientDashboard = new Dashboard(transientSqlDataSource, _singletonNetworkDataSource64, perBlockSqlDataSource);
130+
var transientDashboard = new Dashboard(transientSqlDataSource, _singletonNetworkDataSource74, perBlockSqlDataSource);
131131
lock (_lock)
132132
{
133133
perBlockTelemetryRegistry.Add(transientDashboard);

readme/async-disposable-scope.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ partial class Composition: IDisposable, IAsyncDisposable
130130
private object[] _disposables;
131131
private int _disposeIndex;
132132

133-
private Dependency? _scopedDependency62;
133+
private Dependency? _scopedDependency72;
134134

135135
[OrdinalAttribute(256)]
136136
public Composition()
@@ -157,15 +157,15 @@ partial class Composition: IDisposable, IAsyncDisposable
157157
[MethodImpl(MethodImplOptions.AggressiveInlining)]
158158
get
159159
{
160-
if (_scopedDependency62 is null)
160+
if (_scopedDependency72 is null)
161161
lock (_lock)
162-
if (_scopedDependency62 is null)
162+
if (_scopedDependency72 is null)
163163
{
164-
_scopedDependency62 = new Dependency();
165-
_disposables[_disposeIndex++] = _scopedDependency62;
164+
_scopedDependency72 = new Dependency();
165+
_disposables[_disposeIndex++] = _scopedDependency72;
166166
}
167167

168-
return new Service(_scopedDependency62);
168+
return new Service(_scopedDependency72);
169169
}
170170
}
171171

@@ -178,6 +178,7 @@ partial class Composition: IDisposable, IAsyncDisposable
178178
[MethodImpl(MethodImplOptions.AggressiveInlining)]
179179
() =>
180180
{
181+
// Creates a deferred value
181182
return new Session(this);
182183
});
183184
return new Program(perBlockFuncSession);
@@ -194,7 +195,7 @@ partial class Composition: IDisposable, IAsyncDisposable
194195
_disposeIndex = 0;
195196
disposables = _disposables;
196197
_disposables = new object[1];
197-
_scopedDependency62 = null;
198+
_scopedDependency72 = null;
198199
}
199200

200201
while (disposeIndex-- > 0)
@@ -230,7 +231,7 @@ partial class Composition: IDisposable, IAsyncDisposable
230231
_disposeIndex = 0;
231232
disposables = _disposables;
232233
_disposables = new object[1];
233-
_scopedDependency62 = null;
234+
_scopedDependency72 = null;
234235
}
235236

236237
while (disposeIndex-- > 0)

readme/async-disposable-singleton.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,22 @@ partial class Composition: IDisposable, IAsyncDisposable
118118
private object[] _disposables = new object[1];
119119
private int _disposeIndex;
120120

121-
private AuditLogWriter? _singletonAuditLogWriter62;
121+
private AuditLogWriter? _singletonAuditLogWriter72;
122122

123123
public ICheckoutService CheckoutService
124124
{
125125
[MethodImpl(MethodImplOptions.AggressiveInlining)]
126126
get
127127
{
128-
if (_singletonAuditLogWriter62 is null)
128+
if (_singletonAuditLogWriter72 is null)
129129
lock (_lock)
130-
if (_singletonAuditLogWriter62 is null)
130+
if (_singletonAuditLogWriter72 is null)
131131
{
132-
_singletonAuditLogWriter62 = new AuditLogWriter();
133-
_disposables[_disposeIndex++] = _singletonAuditLogWriter62;
132+
_singletonAuditLogWriter72 = new AuditLogWriter();
133+
_disposables[_disposeIndex++] = _singletonAuditLogWriter72;
134134
}
135135

136-
return new CheckoutService(_singletonAuditLogWriter62);
136+
return new CheckoutService(_singletonAuditLogWriter72);
137137
}
138138
}
139139

@@ -147,7 +147,7 @@ partial class Composition: IDisposable, IAsyncDisposable
147147
_disposeIndex = 0;
148148
disposables = _disposables;
149149
_disposables = new object[1];
150-
_singletonAuditLogWriter62 = null;
150+
_singletonAuditLogWriter72 = null;
151151
}
152152

153153
while (disposeIndex-- > 0)
@@ -183,7 +183,7 @@ partial class Composition: IDisposable, IAsyncDisposable
183183
_disposeIndex = 0;
184184
disposables = _disposables;
185185
_disposables = new object[1];
186-
_singletonAuditLogWriter62 = null;
186+
_singletonAuditLogWriter72 = null;
187187
}
188188

189189
while (disposeIndex-- > 0)

readme/async-root.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,16 @@ partial class Composition
7171
public Task<IBackupService> GetBackupServiceAsync(CancellationToken cancellationToken)
7272
{
7373
Task<IBackupService> transientTaskIBackupService;
74-
// Injects an instance factory
74+
// Creates the task value factory
7575
Func<IBackupService> perBlockFuncIBackupService = new Func<IBackupService>(
7676
[MethodImpl(MethodImplOptions.AggressiveInlining)]
7777
() =>
7878
{
79+
// Creates a deferred value
7980
return new BackupService(new FileStore());
8081
});
8182
Func<IBackupService> localFactory = perBlockFuncIBackupService;
82-
// Injects a task factory creating and scheduling task objects
83+
// Creates the task factory
8384
TaskFactory<IBackupService> perBlockTaskFactoryIBackupService;
8485
CancellationToken localCancellationToken = cancellationToken;
8586
TaskCreationOptions transientTaskCreationOptions = TaskCreationOptions.None;
@@ -90,7 +91,7 @@ partial class Composition
9091
TaskScheduler localTaskScheduler = transientTaskScheduler;
9192
perBlockTaskFactoryIBackupService = new TaskFactory<IBackupService>(localCancellationToken, localTaskCreationOptions, localTaskContinuationOptions, localTaskScheduler);
9293
TaskFactory<IBackupService> localTaskFactory = perBlockTaskFactoryIBackupService;
93-
// Creates and starts a task using the instance factory
94+
// Starts the task
9495
transientTaskIBackupService = localTaskFactory.StartNew(localFactory);
9596
return transientTaskIBackupService;
9697
}

readme/auto-scoped.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ partial class Composition
130130
private readonly Object _lock;
131131
#endif
132132

133-
private PlaybackQueue? _scopedPlaybackQueue62;
133+
private PlaybackQueue? _scopedPlaybackQueue72;
134134

135135
[OrdinalAttribute(256)]
136136
public Composition()
@@ -159,6 +159,7 @@ partial class Composition
159159
[MethodImpl(MethodImplOptions.AggressiveInlining)]
160160
() =>
161161
{
162+
// Creates a deferred value
162163
IListeningSession transientIListeningSession;
163164
Composition localParentScope = this;
164165
// Create a child scope so scoped services (PlaybackQueue) are unique per session.
@@ -175,14 +176,14 @@ partial class Composition
175176
[MethodImpl(MethodImplOptions.AggressiveInlining)]
176177
get
177178
{
178-
if (_scopedPlaybackQueue62 is null)
179+
if (_scopedPlaybackQueue72 is null)
179180
lock (_lock)
180-
if (_scopedPlaybackQueue62 is null)
181+
if (_scopedPlaybackQueue72 is null)
181182
{
182-
_scopedPlaybackQueue62 = new PlaybackQueue();
183+
_scopedPlaybackQueue72 = new PlaybackQueue();
183184
}
184185

185-
return new ListeningSession(_scopedPlaybackQueue62);
186+
return new ListeningSession(_scopedPlaybackQueue72);
186187
}
187188
}
188189
}

0 commit comments

Comments
 (0)