Specifying Span<T> and ReadOnlySpan<T> work the same as with the array T[].
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
.Bind<Point>('a').To(() => new Point(1, 1))
.Bind<Point>('b').To(() => new Point(2, 2))
.Bind<Point>('c').To(() => new Point(3, 3))
.Bind<IPath>().To<Path>()
// Composition root
.Root<IPath>("Path");
var composition = new Composition();
var path = composition.Path;
path.PointCount.ShouldBe(3);
readonly struct Point(int x, int y)
{
public int X { get; } = x;
public int Y { get; } = y;
}
interface IPath
{
int PointCount { get; }
}
class Path(ReadOnlySpan<Point> points) : IPath
{
// The 'points' span is allocated on the stack, so it's very efficient.
// However, we cannot store it in a field because it's a ref struct.
// We can process it here in the constructor.
public int PointCount { get; } = points.Length;
}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 runThis scenario is even more efficient in the case of Span<T> or ReadOnlySpan<T> when T is a value type. In this case, there is no heap allocation, and the composition root IPath looks like this:
public IPath Path
{
get
{
ReadOnlySpan<Point> points = stackalloc Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) };
return new Path(points);
}
}The following partial class will be generated:
partial class Composition
{
public IPath Path
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
Point transientPoint445 = new Point(1, 1);
Point transientPoint446 = new Point(2, 2);
Point transientPoint447 = new Point(3, 3);
return new Path(stackalloc Point[3] { transientPoint445, transientPoint446, transientPoint447 });
}
}
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
Path --|> IPath
Composition ..> Path : IPath Path
Path *-- ReadOnlySpanᐸPointᐳ : ReadOnlySpanᐸPointᐳ
ReadOnlySpanᐸPointᐳ *-- Point : 'a' Point
ReadOnlySpanᐸPointᐳ *-- Point : 'b' Point
ReadOnlySpanᐸPointᐳ *-- Point : 'c' Point
namespace Pure.DI.UsageTests.BCL.SpanScenario {
class Composition {
<<partial>>
+IPath Path
}
class IPath {
<<interface>>
}
class Path {
<<class>>
+Path(ReadOnlySpanᐸPointᐳ points)
}
class Point {
<<struct>>
}
}
namespace System {
class ReadOnlySpanᐸPointᐳ {
<<struct>>
}
}