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

Ir a la instalación

Datos de origen

Repositorio
shinyorg/templates
Última actividad en el origen
2 de abril de 2026 a las 01:50
Idioma detectado de SKILL.md
inglés
Estrellas
155
Forks
15

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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
Ver en GitHub