Skip to content

Commit

Permalink
Adds examples
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Mar 22, 2024
1 parent 06ab1b1 commit 8ed4085
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ dotnet run
- [Async Enumerable](readme/async-enumerable.md)
- [Service collection](readme/service-collection.md)
- [Func with arguments](readme/func-with-arguments.md)
- [Func with tag](readme/func-with-tag.md)
- [Keyed service provider](readme/keyed-service-provider.md)
- [Service provider](readme/service-provider.md)
- [Service provider with scope](readme/service-provider-with-scope.md)
Expand Down
229 changes: 229 additions & 0 deletions readme/func-with-tag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
#### Func with tag

[![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](../tests/Pure.DI.UsageTests/BaseClassLibrary/FuncWithTagScenario.cs)

```c#
interface IDependency;

class Dependency : IDependency;

interface IService
{
ImmutableArray<IDependency> Dependencies { get; }
}

class Service([Tag("my tag")] Func<IDependency> dependencyFactory)
: IService
{
public ImmutableArray<IDependency> Dependencies { get; } =
Enumerable
.Range(0, 10)
.Select(_ => dependencyFactory())
.ToImmutableArray();
}

DI.Setup(nameof(Composition))
.Bind<IDependency>("my tag").To<Dependency>()
.Bind<IService>().To<Service>()
.Root<IService>("Root");

var composition = new Composition();
var service = composition.Root;
service.Dependencies.Length.ShouldBe(10);
```

<details open>
<summary>Class Diagram</summary>

```mermaid
classDiagram
class Composition {
+IService Root
+ T ResolveᐸTᐳ()
+ T ResolveᐸTᐳ(object? tag)
+ object Resolve(Type type)
+ object Resolve(Type type, object? tag)
}
Dependency --|> IDependency : "my tag"
class Dependency {
+Dependency()
}
Service --|> IService :
class Service {
+Service(FuncᐸIDependencyᐳ dependencyFactory)
}
class FuncᐸIDependencyᐳ
class IDependency {
<<abstract>>
}
class IService {
<<abstract>>
}
Service o-- "PerResolve" FuncᐸIDependencyᐳ : "my tag" FuncᐸIDependencyᐳ
Composition ..> Service : IService Root
FuncᐸIDependencyᐳ *-- Dependency : "my tag" IDependency
```

</details>

<details>
<summary>Pure.DI-generated partial class Composition</summary><blockquote>

```c#
partial class Composition
{
private readonly Composition _rootM03D22di;
private readonly object _lockM03D22di;

public Composition()
{
_rootM03D22di = this;
_lockM03D22di = new object();
}

internal Composition(Composition baseComposition)
{
_rootM03D22di = baseComposition._rootM03D22di;
_lockM03D22di = _rootM03D22di._lockM03D22di;
}

public Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService Root
{
get
{
var perResolveM03D22di38_Func = default(System.Func<Pure.DI.UsageTests.BCL.FuncWithTagScenario.IDependency>);
perResolveM03D22di38_Func = new global::System.Func<Pure.DI.UsageTests.BCL.FuncWithTagScenario.IDependency>(
[global::System.Runtime.CompilerServices.MethodImpl((global::System.Runtime.CompilerServices.MethodImplOptions)768)]
() =>
{
var factory_M03D22di1 = new Pure.DI.UsageTests.BCL.FuncWithTagScenario.Dependency();
return factory_M03D22di1;
});
return new Pure.DI.UsageTests.BCL.FuncWithTagScenario.Service(perResolveM03D22di38_Func);
}
}

public T Resolve<T>()
{
return ResolverM03D22di<T>.Value.Resolve(this);
}

public T Resolve<T>(object? tag)
{
return ResolverM03D22di<T>.Value.ResolveByTag(this, tag);
}

public object Resolve(global::System.Type type)
{
var index = (int)(_bucketSizeM03D22di * ((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(type) % 1));
var finish = index + _bucketSizeM03D22di;
do {
ref var pair = ref _bucketsM03D22di[index];
if (ReferenceEquals(pair.Key, type))
{
return pair.Value.Resolve(this);
}
} while (++index < finish);

throw new global::System.InvalidOperationException($"Cannot resolve composition root of type {type}.");
}

public object Resolve(global::System.Type type, object? tag)
{
var index = (int)(_bucketSizeM03D22di * ((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(type) % 1));
var finish = index + _bucketSizeM03D22di;
do {
ref var pair = ref _bucketsM03D22di[index];
if (ReferenceEquals(pair.Key, type))
{
return pair.Value.ResolveByTag(this, tag);
}
} while (++index < finish);

throw new global::System.InvalidOperationException($"Cannot resolve composition root \"{tag}\" of type {type}.");
}

public override string ToString()
{
return
"classDiagram\n" +
" class Composition {\n" +
" +IService Root\n" +
" + T ResolveᐸTᐳ()\n" +
" + T ResolveᐸTᐳ(object? tag)\n" +
" + object Resolve(Type type)\n" +
" + object Resolve(Type type, object? tag)\n" +
" }\n" +
" Dependency --|> IDependency : \"my tag\" \n" +
" class Dependency {\n" +
" +Dependency()\n" +
" }\n" +
" Service --|> IService : \n" +
" class Service {\n" +
" +Service(FuncᐸIDependencyᐳ dependencyFactory)\n" +
" }\n" +
" class FuncᐸIDependencyᐳ\n" +
" class IDependency {\n" +
" <<abstract>>\n" +
" }\n" +
" class IService {\n" +
" <<abstract>>\n" +
" }\n" +
" Service o-- \"PerResolve\" FuncᐸIDependencyᐳ : \"my tag\" FuncᐸIDependencyᐳ\n" +
" Composition ..> Service : IService Root\n" +
" FuncᐸIDependencyᐳ *-- Dependency : \"my tag\" IDependency";
}

private readonly static int _bucketSizeM03D22di;
private readonly static global::Pure.DI.Pair<global::System.Type, global::Pure.DI.IResolver<Composition, object>>[] _bucketsM03D22di;

static Composition()
{
var valResolverM03D22di_0000 = new ResolverM03D22di_0000();
ResolverM03D22di<Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService>.Value = valResolverM03D22di_0000;
_bucketsM03D22di = global::Pure.DI.Buckets<global::System.Type, global::Pure.DI.IResolver<Composition, object>>.Create(
1,
out _bucketSizeM03D22di,
new global::Pure.DI.Pair<global::System.Type, global::Pure.DI.IResolver<Composition, object>>[1]
{
new global::Pure.DI.Pair<global::System.Type, global::Pure.DI.IResolver<Composition, object>>(typeof(Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService), valResolverM03D22di_0000)
});
}

private sealed class ResolverM03D22di<T>: global::Pure.DI.IResolver<Composition, T>
{
public static global::Pure.DI.IResolver<Composition, T> Value = new ResolverM03D22di<T>();

public T Resolve(Composition composite)
{
throw new global::System.InvalidOperationException($"Cannot resolve composition root of type {typeof(T)}.");
}

public T ResolveByTag(Composition composite, object tag)
{
throw new global::System.InvalidOperationException($"Cannot resolve composition root \"{tag}\" of type {typeof(T)}.");
}
}

private sealed class ResolverM03D22di_0000: global::Pure.DI.IResolver<Composition, Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService>
{
public Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService Resolve(Composition composition)
{
return composition.Root;
}

public Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService ResolveByTag(Composition composition, object tag)
{
switch (tag)
{
case null:
return composition.Root;
}
throw new global::System.InvalidOperationException($"Cannot resolve composition root \"{tag}\" of type Pure.DI.UsageTests.BCL.FuncWithTagScenario.IService.");
}
}
}
```

</blockquote></details>

5 changes: 3 additions & 2 deletions readme/func.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface IService
ImmutableArray<IDependency> Dependencies { get; }
}

class Service(Func<IDependency> dependencyFactory) : IService
class Service(Func<IDependency> dependencyFactory): IService
{
public ImmutableArray<IDependency> Dependencies { get; } =
Enumerable
Expand All @@ -25,7 +25,8 @@ class Service(Func<IDependency> dependencyFactory) : IService

DI.Setup(nameof(Composition))
.Bind<IDependency>().To<Dependency>()
.Bind<IService>().To<Service>().Root<IService>("Root");
.Bind<IService>().To<Service>()
.Root<IService>("Root");

var composition = new Composition();
var service = composition.Root;
Expand Down
5 changes: 3 additions & 2 deletions tests/Pure.DI.UsageTests/BaseClassLibrary/FuncScenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface IService
ImmutableArray<IDependency> Dependencies { get; }
}

class Service(Func<IDependency> dependencyFactory) : IService
class Service(Func<IDependency> dependencyFactory): IService
{
public ImmutableArray<IDependency> Dependencies { get; } =
Enumerable
Expand All @@ -43,7 +43,8 @@ public void Run()
// {
DI.Setup(nameof(Composition))
.Bind<IDependency>().To<Dependency>()
.Bind<IService>().To<Service>().Root<IService>("Root");
.Bind<IService>().To<Service>()
.Root<IService>("Root");

var composition = new Composition();
var service = composition.Root;
Expand Down
54 changes: 54 additions & 0 deletions tests/Pure.DI.UsageTests/BaseClassLibrary/FuncWithTagScenario.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
$v=true
$p=99
$d=Func with tag
*/

// ReSharper disable ClassNeverInstantiated.Local
// ReSharper disable CheckNamespace
// ReSharper disable ArrangeTypeModifiers
namespace Pure.DI.UsageTests.BCL.FuncWithTagScenario;

using System.Collections.Immutable;
using Shouldly;
using Xunit;

// {
interface IDependency;

class Dependency : IDependency;

interface IService
{
ImmutableArray<IDependency> Dependencies { get; }
}

class Service([Tag("my tag")] Func<IDependency> dependencyFactory)
: IService
{
public ImmutableArray<IDependency> Dependencies { get; } =
Enumerable
.Range(0, 10)
.Select(_ => dependencyFactory())
.ToImmutableArray();
}
// }

public class Scenario
{
[Fact]
public void Run()
{
// {
DI.Setup(nameof(Composition))
.Bind<IDependency>("my tag").To<Dependency>()
.Bind<IService>().To<Service>()
.Root<IService>("Root");

var composition = new Composition();
var service = composition.Root;
service.Dependencies.Length.ShouldBe(10);
// }
composition.SaveClassDiagram();
}
}

0 comments on commit 8ed4085

Please sign in to comment.