Skip to content

Latest commit

 

History

History
158 lines (137 loc) · 3.51 KB

File metadata and controls

158 lines (137 loc) · 3.51 KB

Generic injections on demand with arguments

Demonstrates how to create generic dependencies on demand with custom arguments using factory delegates.

using Shouldly;
using Pure.DI;
using System.Collections.Generic;

DI.Setup(nameof(Composition))
    .Bind().To<Sensor<TT>>()
    .Bind().To<SensorHub<TT>>()

    // Composition root
    .Root<ISensorHub<string>>("SensorHub");

var composition = new Composition();
var hub = composition.SensorHub;
var sensors = hub.Sensors;
sensors.Count.ShouldBe(2);
sensors[0].Id.ShouldBe(1);
sensors[1].Id.ShouldBe(2);

interface ISensor<out T>
{
    int Id { get; }
}

class Sensor<T>(int id) : ISensor<T>
{
    public int Id { get; } = id;
}

interface ISensorHub<out T>
{
    IReadOnlyList<ISensor<T>> Sensors { get; }
}

class SensorHub<T>(Func<int, ISensor<T>> sensorFactory) : ISensorHub<T>
{
    public IReadOnlyList<ISensor<T>> Sensors { get; } =
    [
        sensorFactory(1),
        sensorFactory(2)
    ];
}
Running this code sample locally
dotnet --list-sdk
  • Create a net10.0 (or later) console application
dotnet new console -n Sample
dotnet 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 run

Note

Generic factories with arguments allow passing runtime parameters while maintaining type safety.

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

  public ISensorHub<string> SensorHub
  {
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    get
    {
      Func<int, ISensor<string>> perBlockFunc520;
      Func<int, ISensor<string>> localFactory8 = new Func<int, ISensor<string>>((int localArg1) =>
      {
        lock (_lock)
        {
          int overriddenInt32 = localArg1;
          return new Sensor<string>(overriddenInt32);
        }
      });
      perBlockFunc520 = localFactory8;
      return new SensorHub<string>(perBlockFunc520);
    }
  }
}

Class diagram:

---
 config:
  maxTextSize: 2147483647
  maxEdges: 2147483647
  class:
   hideEmptyMembersBox: true
---
classDiagram
	SensorHubᐸStringᐳ --|> ISensorHubᐸStringᐳ
	SensorᐸStringᐳ --|> ISensorᐸStringᐳ
	Composition ..> SensorHubᐸStringᐳ : ISensorHubᐸStringᐳ SensorHub
	SensorHubᐸStringᐳ o-- "PerBlock" FuncᐸInt32ˏISensorᐸStringᐳᐳ : FuncᐸInt32ˏISensorᐸStringᐳᐳ
	FuncᐸInt32ˏISensorᐸStringᐳᐳ *--  SensorᐸStringᐳ : ISensorᐸStringᐳ
	SensorᐸStringᐳ *--  Int32 : Int32
	namespace Pure.DI.UsageTests.Generics.GenericInjectionsOnDemandWithArgumentsScenario {
		class Composition {
		<<partial>>
		+ISensorHubᐸStringᐳ SensorHub
		}
		class ISensorHubᐸStringᐳ {
			<<interface>>
		}
		class ISensorᐸStringᐳ {
			<<interface>>
		}
		class SensorHubᐸStringᐳ {
				<<class>>
			+SensorHub(FuncᐸInt32ˏISensorᐸStringᐳᐳ sensorFactory)
		}
		class SensorᐸStringᐳ {
				<<class>>
			+Sensor(Int32 id)
		}
	}
	namespace System {
		class FuncᐸInt32ˏISensorᐸStringᐳᐳ {
				<<delegate>>
		}
		class Int32 {
			<<struct>>
		}
	}
Loading