-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6066fbf
commit b48b5d1
Showing
33 changed files
with
400 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
#### Builders with arguments | ||
|
||
[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](../tests/Pure.DI.UsageTests/Basics/BuilderWithArgumentsScenario.cs) | ||
|
||
Builders can be used with arguments as in the example below: | ||
|
||
|
||
```c# | ||
using Shouldly; | ||
using Pure.DI; | ||
|
||
DI.Setup(nameof(Composition)) | ||
.RootArg<Guid>("serviceId") | ||
.Bind().To<Dependency>() | ||
// Service builder | ||
.Builder<Service>("BuildUp"); | ||
|
||
var composition = new Composition(); | ||
|
||
var id = Guid.NewGuid(); | ||
var service = composition.BuildUp(new Service(), id); | ||
service.Id.ShouldBe(id); | ||
service.Dependency.ShouldBeOfType<Dependency>(); | ||
|
||
interface IDependency; | ||
|
||
class Dependency : IDependency; | ||
|
||
interface IService | ||
{ | ||
Guid Id { get; } | ||
|
||
IDependency? Dependency { get; } | ||
} | ||
|
||
record Service: IService | ||
{ | ||
public Guid Id { get; private set; } = Guid.Empty; | ||
|
||
// The Dependency attribute specifies to perform an injection | ||
[Dependency] | ||
public IDependency? Dependency { get; set; } | ||
|
||
// The Dependency attribute specifies to perform an injection | ||
[Dependency] | ||
public void SetId(Guid id) => Id = id; | ||
} | ||
``` | ||
|
||
<details> | ||
<summary>Running this code sample locally</summary> | ||
|
||
- Make sure you have the [.NET SDK 9.0](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) or later is installed | ||
```bash | ||
dotnet --list-sdk | ||
``` | ||
- Create a net9.0 (or later) console application | ||
```bash | ||
dotnet new console -n Sample | ||
``` | ||
- Add references to NuGet packages | ||
- [Pure.DI](https://www.nuget.org/packages/Pure.DI) | ||
- [Shouldly](https://www.nuget.org/packages/Shouldly) | ||
```bash | ||
dotnet add package Pure.DI | ||
dotnet add package Shouldly | ||
``` | ||
- Copy the example code into the _Program.cs_ file | ||
|
||
You are ready to run the example 🚀 | ||
```bash | ||
dotnet run | ||
``` | ||
|
||
</details> | ||
|
||
The following partial class will be generated: | ||
|
||
```c# | ||
partial class Composition | ||
{ | ||
private readonly Composition _root; | ||
|
||
[OrdinalAttribute(128)] | ||
public Composition() | ||
{ | ||
_root = this; | ||
} | ||
|
||
internal Composition(Composition parentScope) | ||
{ | ||
_root = (parentScope ?? throw new ArgumentNullException(nameof(parentScope)))._root; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public Service BuildUp(Service instance, Guid serviceId) | ||
{ | ||
if (Object.ReferenceEquals(instance, null)) throw new ArgumentNullException(nameof(instance)); | ||
Service transientService0; | ||
Service localInstance48 = instance; | ||
localInstance48.Dependency = new Dependency(); | ||
localInstance48.SetId(serviceId); | ||
transientService0 = localInstance48; | ||
return transientService0; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public T Resolve<T>() | ||
{ | ||
return Resolver<T>.Value.Resolve(this); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public T Resolve<T>(object? tag) | ||
{ | ||
return Resolver<T>.Value.ResolveByTag(this, tag); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public object Resolve(Type type) | ||
{ | ||
throw new InvalidOperationException($"{CannotResolveMessage} {OfTypeMessage} {type}."); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public object Resolve(Type type, object? tag) | ||
{ | ||
throw new InvalidOperationException($"{CannotResolveMessage} \"{tag}\" {OfTypeMessage} {type}."); | ||
} | ||
|
||
private const string CannotResolveMessage = "Cannot resolve composition root "; | ||
private const string OfTypeMessage = "of type "; | ||
|
||
private class Resolver<T>: IResolver<Composition, T> | ||
{ | ||
public static IResolver<Composition, T> Value = new Resolver<T>(); | ||
|
||
public virtual T Resolve(Composition composite) | ||
{ | ||
throw new InvalidOperationException($"{CannotResolveMessage}{OfTypeMessage}{typeof(T)}."); | ||
} | ||
|
||
public virtual T ResolveByTag(Composition composite, object tag) | ||
{ | ||
throw new InvalidOperationException($"{CannotResolveMessage}\"{tag}\" {OfTypeMessage}{typeof(T)}."); | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Class diagram: | ||
|
||
```mermaid | ||
--- | ||
config: | ||
class: | ||
hideEmptyMembersBox: true | ||
--- | ||
classDiagram | ||
Dependency --|> IDependency | ||
Composition ..> Service : Service BuildUp(Pure.DI.UsageTests.Basics.BuilderWithArgumentsScenario.Service instance, System.Guid serviceId) | ||
Service o-- Service : "2M01D25di" Argument "instance" | ||
Service *-- Dependency : IDependency | ||
Service o-- Guid : Argument "serviceId" | ||
namespace Pure.DI.UsageTests.Basics.BuilderWithArgumentsScenario { | ||
class Composition { | ||
<<partial>> | ||
+Service BuildUp(Pure.DI.UsageTests.Basics.BuilderWithArgumentsScenario.Service instance, System.Guid serviceId) | ||
+ T ResolveᐸTᐳ() | ||
+ T ResolveᐸTᐳ(object? tag) | ||
+ object Resolve(Type type) | ||
+ object Resolve(Type type, object? tag) | ||
} | ||
class Dependency { | ||
+Dependency() | ||
} | ||
class IDependency { | ||
<<interface>> | ||
} | ||
class Service { | ||
<<record>> | ||
} | ||
} | ||
namespace System { | ||
class Guid { | ||
<<struct>> | ||
} | ||
} | ||
``` | ||
|
Oops, something went wrong.