Demonstrates how to create and use custom attributes for generic type arguments, enabling advanced generic binding scenarios.
using Shouldly;
using Pure.DI;
DI.Setup(nameof(Composition))
// Registers custom generic argument
.GenericTypeArgumentAttribute<GenericArgAttribute>()
.Bind<IRepository<TMy>>().To<Repository<TMy>>()
.Bind<IContentService>().To<ContentService>()
// Composition root
.Root<IContentService>("ContentService");
var composition = new Composition();
var service = composition.ContentService;
service.Posts.ShouldBeOfType<Repository<Post>>();
service.Comments.ShouldBeOfType<Repository<Comment>>();
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)]
class GenericArgAttribute : Attribute;
[GenericArg]
interface TMy;
interface IRepository<T>;
class Repository<T> : IRepository<T>;
class Post;
class Comment;
interface IContentService
{
IRepository<Post> Posts { get; }
IRepository<Comment> Comments { get; }
}
class ContentService(
IRepository<Post> posts,
IRepository<Comment> comments)
: IContentService
{
public IRepository<Post> Posts { get; } = posts;
public IRepository<Comment> Comments { get; } = comments;
}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 runNote
Custom generic argument attributes are useful when you need to pass metadata specific to generic type parameters during binding resolution.
The following partial class will be generated:
partial class Composition
{
public IContentService ContentService
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new ContentService(new Repository<Post>(), new Repository<Comment>());
}
}
}Class diagram:
---
config:
maxTextSize: 2147483647
maxEdges: 2147483647
class:
hideEmptyMembersBox: true
---
classDiagram
ContentService --|> IContentService
RepositoryᐸPostᐳ --|> IRepositoryᐸPostᐳ
RepositoryᐸCommentᐳ --|> IRepositoryᐸCommentᐳ
Composition ..> ContentService : IContentService ContentService
ContentService *-- RepositoryᐸPostᐳ : IRepositoryᐸPostᐳ
ContentService *-- RepositoryᐸCommentᐳ : IRepositoryᐸCommentᐳ
namespace Pure.DI.UsageTests.Attributes.CustomGenericArgumentAttributeScenario {
class Composition {
<<partial>>
+IContentService ContentService
}
class ContentService {
<<class>>
+ContentService(IRepositoryᐸPostᐳ posts, IRepositoryᐸCommentᐳ comments)
}
class IContentService {
<<interface>>
}
class IRepositoryᐸCommentᐳ {
<<interface>>
}
class IRepositoryᐸPostᐳ {
<<interface>>
}
class RepositoryᐸCommentᐳ {
<<class>>
+Repository()
}
class RepositoryᐸPostᐳ {
<<class>>
+Repository()
}
}