Demonstrates how to define asynchronous composition roots that return Task or Task, enabling async operations during composition.
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
.Bind<IFileStore>().To<FileStore>()
.Bind<IBackupService>().To<BackupService>()
// Specifies to use CancellationToken from the argument
// when resolving a composition root
.RootArg<CancellationToken>("cancellationToken")
// Composition root
.Root<Task<IBackupService>>("GetBackupServiceAsync");
var composition = new Composition();
// Resolves composition roots asynchronously
var service = await composition.GetBackupServiceAsync(CancellationToken.None);
interface IFileStore;
class FileStore : IFileStore;
interface IBackupService;
class BackupService(IFileStore fileStore) : IBackupService;Running this code sample locally
- Make sure you have the .NET SDK 10.0 or later installed
dotnet --list-sdk- Create a net10.0 (or later) console application
dotnet new console -n Sampledotnet add package Pure.DI
dotnet add package Shouldly- Copy the example code into the Program.cs file
You are ready to run the example 🚀
dotnet runNote
Async roots are useful when you need to perform asynchronous initialization or when your services require async creation.
The following partial class will be generated:
partial class Composition
{
#if NET9_0_OR_GREATER
private readonly Lock _lock = new Lock();
#else
private readonly Object _lock = new Object();
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Task<IBackupService> GetBackupServiceAsync(CancellationToken cancellationToken)
{
Task<IBackupService> transientTask219;
// Injects an instance factory
Func<IBackupService> perBlockFunc220 = new Func<IBackupService>(
[MethodImpl(MethodImplOptions.AggressiveInlining)]
() =>
{
return new BackupService(new FileStore());
});
Func<IBackupService> localFactory = perBlockFunc220;
// Injects a task factory creating and scheduling task objects
TaskFactory<IBackupService> perBlockTaskFactory221;
CancellationToken localCancellationToken = cancellationToken;
TaskCreationOptions transientTaskCreationOptions225 = TaskCreationOptions.None;
TaskCreationOptions localTaskCreationOptions = transientTaskCreationOptions225;
TaskContinuationOptions transientTaskContinuationOptions226 = TaskContinuationOptions.None;
TaskContinuationOptions localTaskContinuationOptions = transientTaskContinuationOptions226;
TaskScheduler transientTaskScheduler227 = TaskScheduler.Default;
TaskScheduler localTaskScheduler = transientTaskScheduler227;
perBlockTaskFactory221 = new TaskFactory<IBackupService>(localCancellationToken, localTaskCreationOptions, localTaskContinuationOptions, localTaskScheduler);
TaskFactory<IBackupService> localTaskFactory = perBlockTaskFactory221;
// Creates and starts a task using the instance factory
transientTask219 = localTaskFactory.StartNew(localFactory);
return transientTask219;
}
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
FileStore --|> IFileStore
BackupService --|> IBackupService
Composition ..> TaskᐸIBackupServiceᐳ : TaskᐸIBackupServiceᐳ GetBackupServiceAsync(System.Threading.CancellationToken cancellationToken)
BackupService *-- FileStore : IFileStore
TaskᐸIBackupServiceᐳ o-- "PerBlock" FuncᐸIBackupServiceᐳ : FuncᐸIBackupServiceᐳ
TaskᐸIBackupServiceᐳ o-- "PerBlock" TaskFactoryᐸIBackupServiceᐳ : TaskFactoryᐸIBackupServiceᐳ
FuncᐸIBackupServiceᐳ *-- BackupService : IBackupService
TaskFactoryᐸIBackupServiceᐳ *-- TaskScheduler : TaskScheduler
TaskFactoryᐸIBackupServiceᐳ *-- TaskCreationOptions : TaskCreationOptions
TaskFactoryᐸIBackupServiceᐳ *-- TaskContinuationOptions : TaskContinuationOptions
TaskFactoryᐸIBackupServiceᐳ o-- CancellationToken : Argument "cancellationToken"
namespace Pure.DI.UsageTests.Basics.AsyncRootScenario {
class BackupService {
<<class>>
+BackupService(IFileStore fileStore)
}
class Composition {
<<partial>>
+TaskᐸIBackupServiceᐳ GetBackupServiceAsync(System.Threading.CancellationToken cancellationToken)
}
class FileStore {
<<class>>
+FileStore()
}
class IBackupService {
<<interface>>
}
class IFileStore {
<<interface>>
}
}
namespace System {
class FuncᐸIBackupServiceᐳ {
<<delegate>>
}
}
namespace System.Threading {
class CancellationToken {
<<struct>>
}
}
namespace System.Threading.Tasks {
class TaskContinuationOptions {
<<enum>>
}
class TaskCreationOptions {
<<enum>>
}
class TaskFactoryᐸIBackupServiceᐳ {
<<class>>
}
class TaskScheduler {
<<abstract>>
}
class TaskᐸIBackupServiceᐳ {
<<class>>
}
}