Skip to main content

shiny-di

Generate and configure Shiny DI for .NET - attribute-driven service registration with source generators, keyed services, categories, and multi-interface support

Aller à l'installation

Informations de source

Dépôt
shinyorg/templates
Dernière activité de la source
2 avril 2026 à 01:50
Langue détectée de SKILL.md
anglais
Étoiles
155
Forks
15

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
shiny-di
description
Generate and configure Shiny DI for .NET - attribute-driven service registration with source generators, keyed services, categories, and multi-interface support
auto_invoke
true
triggers
["ServiceAttribute","SingletonAttribute","ScopedAttribute","TransientAttribute","AddShinyServiceRegistry","AddGeneratedServices","AddSingletonAsImplementedInterfaces","AddScopedAsImplementedInterfaces","Shiny.Extensions.DependencyInjection"]
# Shiny Dependency Injection Skill You are an expert in Shiny Extensions Dependency Injection, a .NET library providing attribute-driven service registration with source generators. ## When to Use This Skill Invoke this skill when the user wants to: - Register services using `[Singleton]`, `[Scoped]`, or `[Transient]` attributes with source generation - Configure the Shiny DI service registry in their application - Use keyed services, categories, TryAdd semantics - Register services against multiple interfaces - Use open generics with DI attributes ## Library Overview **Documentation**: https://shinylib.net/extensions/di/ **Repository**: https://github.com/shinyorg/Shiny.Extensions **Package**: `Shiny.Extensions.DependencyInjection` **Namespace**: `Shiny` ## Registration Attributes Mark classes with attributes for automatic DI registration via source generation: ```csharp [Singleton] // Singleton lifetime public class MyService : IMyService { } [Scoped] // Scoped lifetime public class MyRepository : IRepository { } [Transient] // Transient lifetime public class MyFactory : IFactory { } ``` ### Attribute Properties All registration attributes support these properties: | Property | Type | Description | |----------|------|-------------| | `AsSelf` | `bool` | Register as the class itself rather than its interface | | `Type` | `Type` | Register against a specific interface (when class implements multiple) | | `KeyedName` | `string?` | Register as a keyed service | | `Category` | `string?` | Category for conditional registration | | `TryAdd` | `bool` | Use TryAdd semantics (won't replace existing registrations) | ### Examples ```csharp // Register as the class itself [Singleton(AsSelf = true)] public class AppState { } // Register against a specific interface [Singleton(Type = typeof(ISpecificInterface))] public class MultiInterfaceService : ISpecificInterface, IOtherInterface { } // Keyed service [Singleton(KeyedName = "primary")] public class PrimaryCache : ICache { } // Category-based conditional registration [Singleton(Category = "premium")] public class PremiumFeature : IFeature { } // TryAdd semantics [Singleton(TryAdd = true)] public class DefaultLogger : ILogger { } ``` ## Setup ```csharp // Register all source-generated services builder.Services.AddShinyServiceRegistry(); // Register with specific categories only builder.Services.AddShinyServiceRegistry("premium", "analytics"); ``` ## Helper Extensions ```csharp // Register a singleton against all implemented interfaces services.AddSingletonAsImplementedInterfaces<MyService>(); services.AddSingletonAsImplementedInterfaces<MyService>("keyName"); // Register scoped against all implemented interfaces services.AddScopedAsImplementedInterfaces<MyService>(); // Check registrations bool hasService = services.HasService<IMyService>(); bool hasImpl = services.HasImplementation<MyService>(); // Lazy resolution Lazy<IMyService> lazy = services.GetLazyService<IMyService>(required: true); ``` ## Code Generation Instructions - Always use attributes (`[Singleton]`, `[Scoped]`, `[Transient]`) over manual registration - Choose appropriate lifetime: Singleton for stateless services, Scoped for per-request (DbContext), Transient for lightweight factories - Use `Category` for optional features that may not always be registered - Use `KeyedName` when multiple implementations of the same interface exist - Always call `AddShinyServiceRegistry()` to activate source-generated registrations ## Best Practices 1. **Use source generation** - Always prefer `[Singleton]`/`[Scoped]`/`[Transient]` attributes over manual `services.Add*()` calls 2. **Call AddShinyServiceRegistry()** - Required to activate source-generated registrations 3. **Appropriate lifetimes** - Singleton for stateless, Scoped for DbContext/unit-of-work, Transient for factories 4. **Use keyed services** - When multiple implementations exist, use `KeyedName` to disambiguate
Voir sur GitHub