Skip to content

Latest commit

 

History

History
139 lines (115 loc) · 3.73 KB

File metadata and controls

139 lines (115 loc) · 3.73 KB

Generic roots

Demonstrates how to create roots for all generic types that inherit from a given base type at compile time.

using Shouldly;
using Pure.DI;

DI.Setup(nameof(Composition))
    // Disable Resolve methods to keep the public API minimal
    .Hint(Hint.Resolve, "Off")
    .Bind().To<JsonFormatter<TT>>()
    .Bind().To<FileExporter<TT>>()
    // Creates NetworkExporter manually,
    // just for the sake of example
    .Bind<NetworkExporter<TT>>().To(ctx => {
        ctx.Inject(out IFormatter<TT> formatter);
        return new NetworkExporter<TT>(formatter);
    })

    // Specifies to define composition roots for all types inherited from IExporter<TT>
    // available at compile time at the point where the method is called
    .Roots<IExporter<TT>>("GetMy{type}");

var composition = new Composition();

// fileExporter = new FileExporter<int>(new JsonFormatter<int>());
var fileExporter = composition.GetMyFileExporter_T<int>();

// networkExporter = new NetworkExporter<string>(new JsonFormatter<string>());
var networkExporter = composition.GetMyNetworkExporter_T<string>();

interface IFormatter<T>;

class JsonFormatter<T> : IFormatter<T>;

interface IExporter<T>;

class FileExporter<T>(IFormatter<T> formatter) : IExporter<T>;

class NetworkExporter<T>(IFormatter<T> formatter) : IExporter<T>;
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 roots enable exposing multiple generic implementations without explicitly registering each one.

The following partial class will be generated:

partial class Composition
{
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public NetworkExporter<T1> GetMyNetworkExporter_T<T1>()
  {
    NetworkExporter<T1> transientNetworkExporter529;
    IFormatter<T1> localFormatter = new JsonFormatter<T1>();
    transientNetworkExporter529 = new NetworkExporter<T1>(localFormatter);
    return transientNetworkExporter529;
  }

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public FileExporter<T1> GetMyFileExporter_T<T1>()
  {
    return new FileExporter<T1>(new JsonFormatter<T1>());
  }
}

Class diagram:

---
 config:
  maxTextSize: 2147483647
  maxEdges: 2147483647
  class:
   hideEmptyMembersBox: true
---
classDiagram
	FileExporterᐸT1ᐳ --|> IExporterᐸT1ᐳ
	JsonFormatterᐸT1ᐳ --|> IFormatterᐸT1ᐳ
	Composition ..> NetworkExporterᐸT1ᐳ : NetworkExporterᐸT1ᐳ GetMyNetworkExporter_TᐸT1ᐳ()
	Composition ..> FileExporterᐸT1ᐳ : FileExporterᐸT1ᐳ GetMyFileExporter_TᐸT1ᐳ()
	NetworkExporterᐸT1ᐳ *--  JsonFormatterᐸT1ᐳ : IFormatterᐸT1ᐳ
	FileExporterᐸT1ᐳ *--  JsonFormatterᐸT1ᐳ : IFormatterᐸT1ᐳ
	namespace Pure.DI.UsageTests.Generics.GenericsRootsScenario {
		class Composition {
		<<partial>>
		+FileExporterᐸT1ᐳ GetMyFileExporter_TᐸT1ᐳ()
		+NetworkExporterᐸT1ᐳ GetMyNetworkExporter_TᐸT1ᐳ()
		}
		class FileExporterᐸT1ᐳ {
				<<class>>
			+FileExporter(IFormatterᐸT1ᐳ formatter)
		}
		class IExporterᐸT1ᐳ {
			<<interface>>
		}
		class IFormatterᐸT1ᐳ {
			<<interface>>
		}
		class JsonFormatterᐸT1ᐳ {
				<<class>>
			+JsonFormatter()
		}
		class NetworkExporterᐸT1ᐳ {
				<<class>>
		}
	}
Loading