Skip to content

Commit

Permalink
Simplified factories
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Jul 31, 2024
1 parent 98f41b5 commit b292d2c
Show file tree
Hide file tree
Showing 35 changed files with 1,230 additions and 171 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ dotnet run
- [Resolve methods](readme/resolve-methods.md)
- [Simplified binding](readme/simplified-binding.md)
- [Factory](readme/factory.md)
- [Simplified factory](readme/simplified-factory.md)
- [Class arguments](readme/class-arguments.md)
- [Root arguments](readme/root-arguments.md)
- [Tags](readme/tags.md)
Expand Down
4 changes: 2 additions & 2 deletions readme/async-disposable-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ partial class Composition: IDisposable, IAsyncDisposable
() =>
{
Composition transientComposition2 = this;
Session localValue58 = new Session(transientComposition2);
return localValue58;
Session localValue60 = new Session(transientComposition2);
return localValue60;
});
}
}
Expand Down
10 changes: 5 additions & 5 deletions readme/auto-scoped.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ partial class Composition
Composition transientComposition2 = this;
IService transientIService1;
{
Composition localBaseComposition60 = transientComposition2;
Composition localBaseComposition62 = transientComposition2;
// Creates a session
var localSession61 = new Composition(localBaseComposition60);
transientIService1 = localSession61.SessionRoot;
var localSession63 = new Composition(localBaseComposition62);
transientIService1 = localSession63.SessionRoot;
}

IService localValue59 = transientIService1;
return localValue59;
IService localValue61 = transientIService1;
return localValue61;
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions readme/func-with-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ partial class Composition
}
}

Dependency localDependency26 = new Dependency(_root._singletonClock39!, transientInt323, transientInt324);
return localDependency26;
Dependency localDependency28 = new Dependency(_root._singletonClock39!, transientInt323, transientInt324);
return localDependency28;
};
return new Service(transientFunc1);
}
Expand Down
4 changes: 2 additions & 2 deletions readme/func-with-tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ partial class Composition
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
IDependency localValue27 = new Dependency();
return localValue27;
IDependency localValue29 = new Dependency();
return localValue29;
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions readme/func.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ partial class Composition
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
IDependency localValue25 = new Dependency();
return localValue25;
IDependency localValue27 = new Dependency();
return localValue27;
});
}
}
Expand Down
44 changes: 22 additions & 22 deletions readme/generic-async-composition-roots-with-constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ partial class Composition
TaskCreationOptions transientTaskCreationOptions2 = TaskCreationOptions.None;
TaskFactory<IService<T, bool>> perBlockTaskFactory1;
{
CancellationToken localCancellationToken41 = cancellationToken;
TaskCreationOptions localTaskCreationOptions42 = transientTaskCreationOptions2;
TaskContinuationOptions localTaskContinuationOptions43 = transientTaskContinuationOptions3;
TaskScheduler localTaskScheduler44 = transientTaskScheduler4;
perBlockTaskFactory1 = new TaskFactory<IService<T, bool>>(localCancellationToken41, localTaskCreationOptions42, localTaskContinuationOptions43, localTaskScheduler44);
CancellationToken localCancellationToken43 = cancellationToken;
TaskCreationOptions localTaskCreationOptions44 = transientTaskCreationOptions2;
TaskContinuationOptions localTaskContinuationOptions45 = transientTaskContinuationOptions3;
TaskScheduler localTaskScheduler46 = transientTaskScheduler4;
perBlockTaskFactory1 = new TaskFactory<IService<T, bool>>(localCancellationToken43, localTaskCreationOptions44, localTaskContinuationOptions45, localTaskScheduler46);
}

if (perResolveFunc48 == null)
Expand All @@ -112,22 +112,22 @@ partial class Composition
{
OtherService<T> transientOtherService5;
{
IDependency<T> localDependency46 = new Dependency<T>();
transientOtherService5 = new OtherService<T>(localDependency46);
IDependency<T> localDependency48 = new Dependency<T>();
transientOtherService5 = new OtherService<T>(localDependency48);
}

IService<T, bool> localValue45 = transientOtherService5;
return localValue45;
IService<T, bool> localValue47 = transientOtherService5;
return localValue47;
});
}
}
}

Task<IService<T, bool>> transientTask0;
{
Func<IService<T, bool>> localFactory47 = perResolveFunc48!;
TaskFactory<IService<T, bool>> localTaskFactory48 = perBlockTaskFactory1;
transientTask0 = localTaskFactory48.StartNew(localFactory47);
Func<IService<T, bool>> localFactory49 = perResolveFunc48!;
TaskFactory<IService<T, bool>> localTaskFactory50 = perBlockTaskFactory1;
transientTask0 = localTaskFactory50.StartNew(localFactory49);
}

return transientTask0;
Expand All @@ -144,11 +144,11 @@ partial class Composition
TaskCreationOptions transientTaskCreationOptions2 = TaskCreationOptions.None;
TaskFactory<IService<T, T1>> perBlockTaskFactory1;
{
CancellationToken localCancellationToken49 = cancellationToken;
TaskCreationOptions localTaskCreationOptions50 = transientTaskCreationOptions2;
TaskContinuationOptions localTaskContinuationOptions51 = transientTaskContinuationOptions3;
TaskScheduler localTaskScheduler52 = transientTaskScheduler4;
perBlockTaskFactory1 = new TaskFactory<IService<T, T1>>(localCancellationToken49, localTaskCreationOptions50, localTaskContinuationOptions51, localTaskScheduler52);
CancellationToken localCancellationToken51 = cancellationToken;
TaskCreationOptions localTaskCreationOptions52 = transientTaskCreationOptions2;
TaskContinuationOptions localTaskContinuationOptions53 = transientTaskContinuationOptions3;
TaskScheduler localTaskScheduler54 = transientTaskScheduler4;
perBlockTaskFactory1 = new TaskFactory<IService<T, T1>>(localCancellationToken51, localTaskCreationOptions52, localTaskContinuationOptions53, localTaskScheduler54);
}

if (perResolveFunc50 == null)
Expand All @@ -161,18 +161,18 @@ partial class Composition
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
IService<T, T1> localValue53 = new Service<T, T1>(new Dependency<T>());
return localValue53;
IService<T, T1> localValue55 = new Service<T, T1>(new Dependency<T>());
return localValue55;
});
}
}
}

Task<IService<T, T1>> transientTask0;
{
Func<IService<T, T1>> localFactory54 = perResolveFunc50!;
TaskFactory<IService<T, T1>> localTaskFactory55 = perBlockTaskFactory1;
transientTask0 = localTaskFactory55.StartNew(localFactory54);
Func<IService<T, T1>> localFactory56 = perResolveFunc50!;
TaskFactory<IService<T, T1>> localTaskFactory57 = perBlockTaskFactory1;
transientTask0 = localTaskFactory57.StartNew(localFactory56);
}

return transientTask0;
Expand Down
4 changes: 2 additions & 2 deletions readme/generic-composition-roots-with-constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ partial class Composition
{
OtherService<T> transientOtherService0;
{
IDependency<T> localDependency56 = new Dependency<T>();
transientOtherService0 = new OtherService<T>(localDependency56);
IDependency<T> localDependency58 = new Dependency<T>();
transientOtherService0 = new OtherService<T>(localDependency58);
}

return transientOtherService0;
Expand Down
4 changes: 2 additions & 2 deletions readme/generic-composition-roots.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ partial class Composition
{
OtherService<T2> transientOtherService0;
{
IDependency<T2> localDependency57 = new Dependency<T2>();
transientOtherService0 = new OtherService<T2>(localDependency57);
IDependency<T2> localDependency59 = new Dependency<T2>();
transientOtherService0 = new OtherService<T2>(localDependency59);
}

return transientOtherService0;
Expand Down
8 changes: 4 additions & 4 deletions readme/lazy.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,17 @@ partial class Composition
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
IDependency localValue28 = new Dependency();
return localValue28;
IDependency localValue30 = new Dependency();
return localValue30;
});
}
}
}

Lazy<IDependency> transientLazy1;
{
Func<IDependency> localFactory29 = perResolveFunc43!;
transientLazy1 = new Lazy<IDependency>(localFactory29, true);
Func<IDependency> localFactory31 = perResolveFunc43!;
transientLazy1 = new Lazy<IDependency>(localFactory31, true);
}

return new Service(transientLazy1);
Expand Down
10 changes: 5 additions & 5 deletions readme/manually-started-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,18 @@ partial class Composition
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
IDependency localValue30 = new Dependency();
return localValue30;
IDependency localValue32 = new Dependency();
return localValue32;
});
}
}
}

Task<IDependency> transientTask1;
{
Func<IDependency> localFactory31 = perResolveFunc45!;
CancellationToken localCancellationToken32 = cancellationToken;
transientTask1 = new Task<IDependency>(localFactory31, localCancellationToken32);
Func<IDependency> localFactory33 = perResolveFunc45!;
CancellationToken localCancellationToken34 = cancellationToken;
transientTask1 = new Task<IDependency>(localFactory33, localCancellationToken34);
}

return new Service(transientTask1);
Expand Down
4 changes: 2 additions & 2 deletions readme/scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ partial class Composition: IDisposable
() =>
{
Composition transientComposition2 = this;
Session localValue62 = new Session(transientComposition2);
return localValue62;
Session localValue64 = new Session(transientComposition2);
return localValue64;
});
}
}
Expand Down
122 changes: 122 additions & 0 deletions readme/simplified-factory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#### Simplified factory

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

This example shows how to create and initialize an instance manually in a simplified form. When you use a lambda function to specify custom instance initialization logic, each parameter of that function represents an injection of a dependency. Since C# 10, you can also specify the `Tag(...)` attribute before the lambda function parameter to specify the tag of the injected dependency.


```c#
interface IDependency
{
DateTimeOffset Time { get; }

bool IsInitialized { get; }
}

class Dependency : IDependency
{
public DateTimeOffset Time { get; private set; }

public bool IsInitialized { get; private set; }

public void Initialize(DateTimeOffset time)
{
Time = time;
IsInitialized = true;
}
}

interface IService
{
IDependency Dependency { get; }
}

class Service(IDependency dependency) : IService
{
public IDependency Dependency { get; } = dependency;
}

DI.Setup(nameof(Composition))
.Bind("now datetime").To(_ => DateTimeOffset.Now)
// Injects Dependency and DateTimeOffset instances
// and performs further initialization logic
// defined in the lambda function
.Bind<IDependency>().To((
Dependency dependency,
[Tag("now datetime")] DateTimeOffset time) =>
{
dependency.Initialize(time);
return dependency;
})
.Bind().To<Service>()

// Composition root
.Root<IService>("MyService");

var composition = new Composition();
var service = composition.MyService;
service.Dependency.IsInitialized.ShouldBeTrue();
```

The following partial class will be generated:

```c#
partial class Composition
{
private readonly Composition _root;

[OrdinalAttribute(20)]
public Composition()
{
_root = this;
}

internal Composition(Composition parentScope)
{
_root = (parentScope ?? throw new ArgumentNullException(nameof(parentScope)))._root;
}

public IService MyService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
DateTimeOffset transientDateTimeOffset3 = DateTimeOffset.Now;
Dependency transientDependency1;
{
Dependency localDependency25 = new Dependency();
DateTimeOffset localTime26 = transientDateTimeOffset3;
localDependency25.Initialize(localTime26);
transientDependency1 = localDependency25;
}

return new Service(transientDependency1);
}
}
}
```

Class diagram:

```mermaid
classDiagram
class Composition {
<<partial>>
+IService MyService
}
class Dependency {
+Dependency()
}
class DateTimeOffset
Service --|> IService
class Service {
+Service(IDependency dependency)
}
class IService {
<<interface>>
}
Composition ..> Service : IService MyService
Dependency *-- DateTimeOffset : "now datetime" DateTimeOffset
Service *-- Dependency : IDependency
```

Loading

0 comments on commit b292d2c

Please sign in to comment.