Skip to content
Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More

Dependency Injection Release Notes

Feature
New services.OnResolved<TService>(hook) chain method — wraps the last service descriptor’s factory with a callback that fires after the container constructs the instance but before it’s returned. Fires once per construction (singleton: once; scoped: per-scope; transient: per-resolve)
Enhancement
OnResolved is fully AOT-clean — no reflection. It wraps factory-based descriptors only; type-based registrations like AddSingleton<TService, TImpl>() and pre-built instance registrations throw a clear error directing users to a factory registration (AddSingleton<TService>(sp => new TImpl(...)))
Enhancement
AddSingletonAsImplementedInterfaces<TImpl> and AddScopedAsImplementedInterfaces<TImpl> now propagate [DynamicallyAccessedMembers(PublicConstructors | Interfaces)] on TImpl, so trimmer/AOT analyzers preserve constructors and interface metadata without warnings
Enhancement
GetLazyService<T> now constrains where T : notnull and suppresses the IL2091 warning from Lazy<T>’s default-constructor requirement (we always pass a Func<T>, so the requirement isn’t exercised)
Fix
Keyed forwarders in AddSingletonAsImplementedInterfaces / AddScopedAsImplementedInterfaces now resolve via GetRequiredKeyedService<TImpl>(key) — the previous non-keyed GetRequiredService<TImpl> lookup meant keyed registrations could not actually resolve their interfaces end-to-end
Feature
New [Tool] attribute for interfaces — mark methods with [Description] to automatically generate AIFunction classes compatible with Microsoft.Extensions.AI
Feature
Generated AddGeneratedAITools() extension method registers all AI tools as transient services in the DI container
Enhancement
AI tool generation is conditional — only emits code when Microsoft.Extensions.AI is referenced in the project
Enhancement
AOT-safe argument extraction for all standard types (string, int, Guid, DateTime, DateOnly, TimeOnly, TimeSpan, decimal, enums, and more) using direct JsonElement accessors instead of reflection
Enhancement
CancellationToken parameters are automatically passed through to the service method and excluded from AI tool metadata
Enhancement
Parameter [Description] attributes are propagated to AIFunctionParameterMetadata for rich tool schemas
BREAKING Feature
We now use module initializers and a global service registry along with a new defined method services.AddShinyServiceRegistry() that pulls in all registered values
BREAKING Enhancement
Namespace changed from Shiny.Extensions.DependencyInjection to Shiny — no more verbose usings needed
BREAKING Enhancement
Removed IShinyStartupTask and RunStartupTasks() — use hosted services or module-based initialization instead
Fix
Type and AsSelf was being ignored if a base class is being used
Enhancement
DI registration now supports AsSelf which allows an implementation to be registered directly
Fix
Booleans with false were not binding properly on stores
Enhancement
Logging has been optionally enabled throughout the DI binding
Enhancement
ServiceAttribute now has a TryAdd property that will call the appropriate service lifetime method
Enhancement
Additional SingletonAttribute, ScopedAttribute, and TransientAttribute to remove the need for multiple namespaces
Enhancement
Type property on service attribute allows you to override which interface is used in multiple interface scenarios
Feature
ServiceAttribute now accepts a Category. Categories allow you to pass an argument to the AddGeneratedServices that only get instantiate if you pass that category name. Great for unit testing or dev vs production
Enhancement
Now works with records
BREAKING Fix
ServiceAttribute KeyedName name parameter was moved from the constructor to a property
Feature
Initial Public Release