You can call Bind() without type parameters to infer contracts from the implementation type.
This reduces boilerplate while preserving compile-time graph validation.
using System.Collections;
using Pure.DI;
// Specifies to create a partial class "Composition"
DI.Setup(nameof(Composition))
// Begins the binding definition for the implementation type itself,
// and if the implementation is not an abstract class or structure,
// for all abstract but NOT special types that are directly implemented.
// Equivalent to:
// .Bind<IOrderRepository, IOrderNotification, OrderManager>()
// .As(Lifetime.PerBlock)
// .To<OrderManager>()
.Bind().As(Lifetime.PerBlock).To<OrderManager>()
.Bind().To<Shop>()
// Specifies to create a property "MyShop"
.Root<IShop>("MyShop");
var composition = new Composition();
var shop = composition.MyShop;
interface IManager;
class ManagerBase : IManager;
interface IOrderRepository;
interface IOrderNotification;
class OrderManager :
ManagerBase,
IOrderRepository,
IOrderNotification,
IDisposable,
IEnumerable<string>
{
public void Dispose() {}
public IEnumerator<string> GetEnumerator() =>
new List<string> { "Order #1", "Order #2" }.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
interface IShop;
class Shop(
OrderManager manager,
IOrderRepository repository,
IOrderNotification notification)
: IShop;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 runIn practice, most abstraction types can be inferred. The parameterless Bind() binds:
- the implementation type itself
- and, if it is NOT abstract,
- all abstract types it directly implements
- except special types
Special types will not be added to bindings:
System.ObjectSystem.EnumSystem.MulticastDelegateSystem.DelegateSystem.Collections.IEnumerableSystem.Collections.Generic.IEnumerable<T>System.Collections.Generic.IList<T>System.Collections.Generic.ICollection<T>System.Collections.IEnumeratorSystem.Collections.Generic.IEnumerator<T>System.Collections.Generic.IReadOnlyList<T>System.Collections.Generic.IReadOnlyCollection<T>System.IDisposableSystem.IAsyncResultSystem.AsyncCallback
If you want to add your own special type, use the SpecialType<T>() call.
For class OrderManager, Bind().To<OrderManager>() is equivalent to Bind<IOrderRepository, IOrderNotification, OrderManager>().To<OrderManager>(). The types IDisposable and IEnumerable<string> are excluded because they are special. ManagerBase is excluded because it is not abstract. IManager is excluded because it is not implemented directly by OrderManager.
| ✅ | OrderManager |
implementation type itself |
| ✅ | IOrderRepository |
directly implements |
| ✅ | IOrderNotification |
directly implements |
| ❌ | IDisposable |
special type |
| ❌ | IEnumerable<string> |
special type |
| ❌ | ManagerBase |
non-abstract |
| ❌ | IManager |
is not directly implemented by class OrderManager |
| Limitations: inferred bindings include only directly implemented abstractions and exclude special types. | ||
| Common pitfalls: |
- Expecting inherited interfaces to be included automatically.
- Forgetting that special framework types are intentionally excluded. See also: Simplified lifetime-specific bindings, Special types.
The following partial class will be generated:
partial class Composition
{
public IShop MyShop
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
var perBlockOrderManager342 = new OrderManager();
return new Shop(perBlockOrderManager342, perBlockOrderManager342, perBlockOrderManager342);
}
}
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
OrderManager --|> IOrderRepository
OrderManager --|> IOrderNotification
OrderManager --|> IEnumerableᐸStringᐳ
Shop --|> IShop
Composition ..> Shop : IShop MyShop
Shop o-- "PerBlock" OrderManager : OrderManager
Shop o-- "PerBlock" OrderManager : IOrderRepository
Shop o-- "PerBlock" OrderManager : IOrderNotification
namespace Pure.DI.UsageTests.Basics.SimplifiedBindingScenario {
class Composition {
<<partial>>
+IShop MyShop
}
class IOrderNotification {
<<interface>>
}
class IOrderRepository {
<<interface>>
}
class IShop {
<<interface>>
}
class OrderManager {
<<class>>
+OrderManager()
}
class Shop {
<<class>>
+Shop(OrderManager manager, IOrderRepository repository, IOrderNotification notification)
}
}
namespace System.Collections.Generic {
class IEnumerableᐸStringᐳ {
<<interface>>
}
}