Skip to content

Commit 0209cff

Browse files
Update README.md
1 parent 732890d commit 0209cff

42 files changed

Lines changed: 424 additions & 440 deletions

Some content is hidden

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

AI_CONTEXT_LARGE.md

Lines changed: 79 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -317,73 +317,41 @@ For class `Dependency`, the `Bind().To<Dependency>()` binding will be equivalent
317317

318318
## Factory
319319

320-
This example demonstrates how to create and initialize an instance manually.
321-
At the compilation stage, the set of dependencies that an object needs in order to be created is determined. In most cases, this happens automatically according to the set of constructors and their arguments and does not require any additional customization efforts. But sometimes it is necessary to manually create an object, as in lines of code:
320+
This example demonstrates how to create and initialize an instance manually. At the compilation stage, the set of dependencies that the object to be created needs is determined. In most cases, this happens automatically, according to the set of constructors and their arguments, and does not require additional customization efforts. But sometimes it is necessary to manually create and/or initialize an object, as in lines of code:
322321

323322
```c#
324323
using Shouldly;
325324
using Pure.DI;
326325

327326
DI.Setup(nameof(Composition))
328-
.Bind().To(_ => DateTimeOffset.Now)
329-
.RootArg<bool>("isFake", "FakeArgTag")
330327
.Bind<IDependency>().To<IDependency>(ctx =>
331328
{
332-
// When building a composition of objects,
333-
// all of this code will be outside the lambda function.
334-
335-
// Some custom logic for creating an instance.
336-
// For example, here's how you can inject and initialize
337-
// an instance of a particular type:
338-
339-
ctx.Inject<bool>("FakeArgTag", out var isFake);
340-
if (isFake)
341-
{
342-
return new FakeDependency();
343-
}
344-
329+
// Some logic for creating an instance:
345330
ctx.Inject(out Dependency dependency);
346331
dependency.Initialize();
347332
return dependency;
348-
349333
})
350334
.Bind<IService>().To<Service>()
351335

352336
// Composition root
353-
.Root<IService>("GetMyService");
337+
.Root<IService>("MyService");
354338

355339
var composition = new Composition();
356-
357-
var service = composition.GetMyService(isFake: false);
358-
service.Dependency.ShouldBeOfType<Dependency>();
340+
var service = composition.MyService;
359341
service.Dependency.IsInitialized.ShouldBeTrue();
360-
361-
var serviceWithFakeDependency = composition.GetMyService(isFake: true);
362-
serviceWithFakeDependency.Dependency.ShouldBeOfType<FakeDependency>();
363342

364343
interface IDependency
365344
{
366-
DateTimeOffset Time { get; }
367-
368345
bool IsInitialized { get; }
369346
}
370347

371-
class Dependency(DateTimeOffset time) : IDependency
348+
class Dependency : IDependency
372349
{
373-
public DateTimeOffset Time { get; } = time;
374-
375350
public bool IsInitialized { get; private set; }
376351

377352
public void Initialize() => IsInitialized = true;
378353
}
379354

380-
class FakeDependency : IDependency
381-
{
382-
public DateTimeOffset Time => DateTimeOffset.MinValue;
383-
384-
public bool IsInitialized => true;
385-
}
386-
387355
interface IService
388356
{
389357
IDependency Dependency { get; }
@@ -399,7 +367,11 @@ To run the above code, the following NuGet packages must be added:
399367
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
400368
- [Shouldly](https://www.nuget.org/packages/Shouldly)
401369

402-
This approach is more expensive to maintain, but allows you to create objects more flexibly by passing them some state and introducing dependencies. As in the case of automatic dependency injecting, objects give up control on embedding, and the whole process takes place when the object graph is created.
370+
There are scenarios where manual control over the creation process is required, such as:
371+
- When additional initialization logic is needed
372+
- When complex construction steps are required
373+
- When specific object states need to be set during creation
374+
403375
> [!IMPORTANT]
404376
> The method `Inject()`cannot be used outside of the binding setup.
405377
@@ -412,13 +384,13 @@ using Shouldly;
412384
using Pure.DI;
413385

414386
DI.Setup(nameof(Composition))
415-
.Bind("now datetime").To(_ => DateTimeOffset.Now)
387+
.Bind("now").To(_ => DateTimeOffset.Now)
416388
// Injects Dependency and DateTimeOffset instances
417389
// and performs further initialization logic
418390
// defined in the lambda function
419391
.Bind<IDependency>().To((
420392
Dependency dependency,
421-
[Tag("now datetime")] DateTimeOffset time) =>
393+
[Tag("now")] DateTimeOffset time) =>
422394
{
423395
dependency.Initialize(time);
424396
return dependency;
@@ -467,6 +439,7 @@ To run the above code, the following NuGet packages must be added:
467439
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
468440
- [Shouldly](https://www.nuget.org/packages/Shouldly)
469441

442+
The example creates a `service` that depends on a `dependency` initialized with a specific timestamp. The `Tag` attribute allows specifying named dependencies for more complex scenarios.
470443

471444
## Injection on demand
472445

@@ -731,7 +704,7 @@ When using composition root arguments, compilation warnings are shown if `Resolv
731704

732705
## Tags
733706

734-
Sometimes it's important to take control of building a dependency graph. For example, when there are multiple implementations of the same contract. In this case, _tags_ will help:
707+
Sometimes it's important to take control of building a dependency graph. For example, when there are different implementations of the same interface. In this case, _tags_ will help:
735708

736709
```c#
737710
using Shouldly;
@@ -741,9 +714,7 @@ DI.Setup(nameof(Composition))
741714
// The `default` tag is used to resolve dependencies
742715
// when the tag was not specified by the consumer
743716
.Bind<IDependency>("AbcTag", default).To<AbcDependency>()
744-
.Bind<IDependency>("XyzTag")
745-
.As(Lifetime.Singleton)
746-
.To<XyzDependency>()
717+
.Bind<IDependency>("XyzTag").As(Lifetime.Singleton).To<XyzDependency>()
747718
.Bind<IService>().To<Service>()
748719

749720
// "XyzRoot" is root name, "XyzTag" is tag
@@ -794,6 +765,12 @@ To run the above code, the following NuGet packages must be added:
794765
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
795766
- [Shouldly](https://www.nuget.org/packages/Shouldly)
796767

768+
The example shows how to:
769+
- Define multiple bindings for the same interface
770+
- Use tags to differentiate between implementations
771+
- Control lifetime management
772+
- Inject tagged dependencies into constructors
773+
797774
The tag can be a constant, a type, a [smart tag](smart-tags.md), or a value of an `Enum` type. The _default_ and _null_ tags are also supported.
798775

799776
## Smart tags
@@ -883,7 +860,7 @@ To run the above code, the following NuGet packages must be added:
883860

884861
## Build up of an existing object
885862

886-
In other words, injecting the necessary dependencies via methods, properties, or fields into an existing object.
863+
This example demonstrates the Build-Up pattern in dependency injection, where an existing object is injected with necessary dependencies through its properties, methods, or fields.
887864

888865
```c#
889866
using Shouldly;
@@ -918,14 +895,12 @@ interface IDependency
918895
class Dependency : IDependency
919896
{
920897
// The Dependency attribute specifies to perform an injection and its order
921-
[Dependency]
922-
public string Name { get; set; } = "";
898+
[Dependency] public string Name { get; set; } = "";
923899

924900
public Guid Id { get; private set; } = Guid.Empty;
925901

926902
// The Dependency attribute specifies to perform an injection and its order
927-
[Dependency]
928-
public void SetId(Guid id) => Id = id;
903+
[Dependency] public void SetId(Guid id) => Id = id;
929904
}
930905

931906
interface IService
@@ -940,6 +915,9 @@ To run the above code, the following NuGet packages must be added:
940915
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
941916
- [Shouldly](https://www.nuget.org/packages/Shouldly)
942917

918+
Key Concepts:
919+
**Build-Up** - injecting dependencies into an already created object
920+
**Dependency Attribute** - marker for identifying injectable members
943921

944922
## Builder
945923

@@ -988,11 +966,25 @@ To run the above code, the following NuGet packages must be added:
988966
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
989967
- [Shouldly](https://www.nuget.org/packages/Shouldly)
990968

991-
The default builder method name is `BuildUp`. The first argument to this method will always be the instance to be built.
969+
Important Notes:
970+
- The default builder method name is `BuildUp`
971+
- The first argument to the builder method is always the instance to be built
972+
973+
Advantages:
974+
- Allows working with pre-existing objects
975+
- Provides flexibility in dependency injection
976+
- Supports partial injection of dependencies
977+
- Can be used with legacy code
978+
979+
Use Cases:
980+
- When objects are created outside the DI container
981+
- For working with third-party libraries
982+
- When migrating existing code to DI
983+
- For complex object graphs where full construction is not feasible
992984

993985
## Builder with arguments
994986

995-
Builders can be used with arguments as in the example below:
987+
This example demonstrates how to use builders with custom arguments in dependency injection. It shows how to pass additional parameters during the build-up process.
996988

997989
```c#
998990
using Shouldly;
@@ -1038,7 +1030,21 @@ To run the above code, the following NuGet packages must be added:
10381030
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
10391031
- [Shouldly](https://www.nuget.org/packages/Shouldly)
10401032

1041-
The default builder method name is `BuildUp`. The first argument to this method will always be the instance to be built. The remaining arguments of this method will be listed in the order in which they are defined in the setup.
1033+
Important Notes:
1034+
- The default builder method name is `BuildUp`
1035+
- The first argument to the builder method is always the instance to be built
1036+
- Additional arguments are passed in the order they are defined in the setup
1037+
- Root arguments can be used to provide custom values during build-up
1038+
1039+
Use Cases:
1040+
- When additional parameters are required during object construction
1041+
- For scenarios where dependencies depend on runtime values
1042+
- When specific initialization data is needed
1043+
- For conditional injection based on provided arguments
1044+
1045+
Best Practices
1046+
- Keep the number of builder arguments minimal
1047+
- Use meaningful names for root arguments
10421048

10431049
## Builders
10441050

@@ -1101,7 +1107,9 @@ To run the above code, the following NuGet packages must be added:
11011107
- [Pure.DI](https://www.nuget.org/packages/Pure.DI)
11021108
- [Shouldly](https://www.nuget.org/packages/Shouldly)
11031109

1104-
The default builder method name is `BuildUp`. The first argument to this method will always be the instance to be built.
1110+
Important Notes:
1111+
- The default builder method name is `BuildUp`
1112+
- The first argument to the builder method is always the instance to be built
11051113

11061114
## Builders with a name template
11071115

@@ -12164,30 +12172,21 @@ DI.Setup("Composition")
1216412172
</blockquote></details>
1216512173

1216612174

12167-
<details><summary>Field Overrider</summary><blockquote>
12168-
12169-
Atomically generated smart tag with value "Overrider".
12170-
It's used for:
12171-
12172-
class _Generator__DependencyGraphBuilder_ <-- _IGraphRewriter_(Overrider) -- _GraphOverrider_ as _PerBlock_
12173-
</blockquote></details>
12174-
12175-
12176-
<details><summary>Field Cleaner</summary><blockquote>
12175+
<details><summary>Field UniqueTag</summary><blockquote>
1217712176

12178-
Atomically generated smart tag with value "Cleaner".
12177+
Atomically generated smart tag with value "UniqueTag".
1217912178
It's used for:
1218012179

12181-
class _Generator__DependencyGraphBuilder_ <-- _IGraphRewriter_(Cleaner) -- _GraphCleaner_ as _PerBlock_
12180+
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
1218212181
</blockquote></details>
1218312182

1218412183

12185-
<details><summary>Field CompositionClass</summary><blockquote>
12184+
<details><summary>Field Overrider</summary><blockquote>
1218612185

12187-
Atomically generated smart tag with value "CompositionClass".
12186+
Atomically generated smart tag with value "Overrider".
1218812187
It's used for:
1218912188

12190-
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
12189+
class _Generator__DependencyGraphBuilder_ <-- _IGraphRewriter_(Overrider) -- _GraphOverrider_ as _PerBlock_
1219112190
</blockquote></details>
1219212191

1219312192

@@ -12207,6 +12206,15 @@ Atomically generated smart tag with value "Injection".
1220712206
</blockquote></details>
1220812207

1220912208

12209+
<details><summary>Field CompositionClass</summary><blockquote>
12210+
12211+
Atomically generated smart tag with value "CompositionClass".
12212+
It's used for:
12213+
12214+
class _Generator__CodeBuilder_ <-- _IBuilder`2_(CompositionClass) -- _CompositionClassBuilder_ as _PerBlock_
12215+
</blockquote></details>
12216+
12217+
1221012218
<details><summary>Field UsingDeclarations</summary><blockquote>
1221112219

1221212220
Atomically generated smart tag with value "UsingDeclarations".
@@ -12225,12 +12233,12 @@ Atomically generated smart tag with value "Override".
1222512233
</blockquote></details>
1222612234

1222712235

12228-
<details><summary>Field UniqueTag</summary><blockquote>
12236+
<details><summary>Field Cleaner</summary><blockquote>
1222912237

12230-
Atomically generated smart tag with value "UniqueTag".
12238+
Atomically generated smart tag with value "Cleaner".
1223112239
It's used for:
1223212240

12233-
class _Generator__ApiInvocationProcessor_ <-- (UniqueTag) -- _IdGenerator_ as _PerResolve_
12241+
class _Generator__DependencyGraphBuilder_ <-- _IGraphRewriter_(Cleaner) -- _GraphCleaner_ as _PerBlock_
1223412242
</blockquote></details>
1223512243

1223612244

0 commit comments

Comments
 (0)