The Setup method has an additional argument kind, which defines the type of composition:
CompositionKind.Public- will create a normal composition class, this is the default setting and can be omitted, it can also use theDependsOnmethod to use it as a dependency in other compositionsCompositionKind.Internal- the composition class will not be created, but that composition can be used to create other compositions by calling theDependsOnmethod with its nameCompositionKind.Global- the composition class will also not be created, but that composition will automatically be used to create other compositions Use dependent compositions to split large object graphs into reusable setup layers.
using Pure.DI;
using static Pure.DI.CompositionKind;
// This setup does not generate code, but can be used as a dependency
// and requires the use of the "DependsOn" call to add it as a dependency
DI.Setup("Infrastructure", Internal)
.Bind<IDatabase>().To<SqlDatabase>();
// This setup generates code and can also be used as a dependency
DI.Setup(nameof(Composition))
// Uses "Infrastructure" setup
.DependsOn("Infrastructure")
.Bind<IUserService>().To<UserService>()
.Root<IUserService>("UserService");
// As in the previous case, this setup generates code and can also be used as a dependency
DI.Setup(nameof(OtherComposition))
// Uses "Composition" setup
.DependsOn(nameof(Composition))
.Root<Ui>("Ui");
var composition = new Composition();
var userService = composition.UserService;
var otherComposition = new OtherComposition();
userService = otherComposition.Ui.UserService;
interface IDatabase;
class SqlDatabase : IDatabase;
interface IUserService;
class UserService(IDatabase database) : IUserService;
partial class Ui(IUserService userService)
{
public IUserService UserService { get; } = userService;
}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 Sample- Add a reference to the NuGet package
dotnet add package Pure.DI- Copy the example code into the Program.cs file
You are ready to run the example 🚀
dotnet runLimitations: too many setup layers can make graph ownership unclear; keep boundaries explicit and naming consistent. See also: Composition roots, Global compositions.
The following partial class will be generated:
partial class Composition
{
public IUserService UserService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new UserService(new SqlDatabase());
}
}
}The following partial class will be generated:
partial class OtherComposition
{
public IUserService UserService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new UserService(new SqlDatabase());
}
}
public Ui Ui
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new Ui(new UserService(new SqlDatabase()));
}
}
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
UserService --|> IUserService
SqlDatabase --|> IDatabase
OtherComposition ..> Ui : Ui Ui
OtherComposition ..> UserService : IUserService UserService
UserService *-- SqlDatabase : IDatabase
Ui *-- UserService : IUserService
namespace Pure.DI.UsageTests.Advanced.DependentCompositionsScenario {
class IDatabase {
<<interface>>
}
class IUserService {
<<interface>>
}
class OtherComposition {
<<partial>>
+Ui Ui
+IUserService UserService
}
class SqlDatabase {
<<class>>
+SqlDatabase()
}
class Ui {
<<class>>
+Ui(IUserService userService)
}
class UserService {
<<class>>
+UserService(IDatabase database)
}
}