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

跳到安装

来源信息

仓库
shinyorg/templates
最近来源活动
2026年4月2日 01:50
检测到的 SKILL.md 语言
英语
星标
155
分支
15

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
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
在 GitHub 查看