Skip to content

Latest commit

 

History

History
149 lines (123 loc) · 3.53 KB

File metadata and controls

149 lines (123 loc) · 3.53 KB

Required properties or fields

This example shows how the required modifier can be used to automatically inject dependencies into properties and fields. When a property or field is marked with required, the DI will automatically inject the dependency without additional effort.

using Shouldly;
using Pure.DI;

DI.Setup(nameof(Composition))
    .Arg<string>("connectionString")
    .Bind<IDatabase>().To<SqlDatabase>()
    .Bind<IUserRepository>().To<UserRepository>()

    // Composition root
    .Root<IUserRepository>("Repository");

var composition = new Composition(connectionString: "Server=.;Database=MyDb;");
var repository = composition.Repository;

repository.Database.ShouldBeOfType<SqlDatabase>();
repository.ConnectionString.ShouldBe("Server=.;Database=MyDb;");

interface IDatabase;

class SqlDatabase : IDatabase;

interface IUserRepository
{
    string ConnectionString { get; }

    IDatabase Database { get; }
}

class UserRepository : IUserRepository
{
    // The required field will be injected automatically.
    // In this case, it gets the value from the composition argument
    // of type 'string'.
    public required string ConnectionStringField;

    public string ConnectionString => ConnectionStringField;

    // The required property will be injected automatically
    // without additional effort.
    public required IDatabase Database { get; init; }
}
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

This approach simplifies dependency injection by eliminating the need to manually configure bindings for required dependencies, making the code more concise and easier to maintain.

The following partial class will be generated:

partial class Composition
{
  private readonly string _argConnectionString;

  [OrdinalAttribute(128)]
  public Composition(string connectionString)
  {
    _argConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
  }

  public IUserRepository Repository
  {
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    get
    {
      return new UserRepository()
      {
        ConnectionStringField = _argConnectionString,
        Database = new SqlDatabase()
      };
    }
  }
}

Class diagram:

---
 config:
  class:
   hideEmptyMembersBox: true
---
classDiagram
	SqlDatabase --|> IDatabase
	UserRepository --|> IUserRepository
	Composition ..> UserRepository : IUserRepository Repository
	UserRepository o-- String : Argument "connectionString"
	UserRepository *-- SqlDatabase : IDatabase
	namespace Pure.DI.UsageTests.Basics.RequiredPropertiesOrFieldsScenario {
		class Composition {
		<<partial>>
		+IUserRepository Repository
		}
		class IDatabase {
			<<interface>>
		}
		class IUserRepository {
			<<interface>>
		}
		class SqlDatabase {
				<<class>>
			+SqlDatabase()
		}
		class UserRepository {
				<<class>>
			+UserRepository()
			+String ConnectionStringField
			+IDatabase Database
		}
	}
	namespace System {
		class String {
				<<class>>
		}
	}
Loading