Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More
Dependency Injection Release Notes
4.1 - May 29, 2026
Section titled “4.1 - May 29, 2026” Enhancement
The source generator no longer emits the
AddGeneratedServices extension method (the __GeneratedRegistrations class) when the assembly contains no [Service]-attributed types4.0 - May 27, 2026
Section titled “4.0 - May 27, 2026” Fix
Generated
[Bind] property signatures and On{Name}Changed callbacks are now nullable-aware — the ? reference-type marker is preserved — while typeof/generic usages continue to use the fully-qualified type name Fix
Writing a
[Bind(Default = X)] property’s default value now persists. The setter computes the previous value through the default-aware getter, so assigning the default no longer short-circuits when the key is absent Feature
New
[BindNotify] attribute — opts a partial [Bind] class into a generated INotifyPropertyChanged implementation. Each generated setter raises PropertyChanged after the store write and only when the value actually changes. If the class already implements INPC, the generator raises through your existing OnPropertyChanged (PropertyChangedEventArgs or string overload) or a self-declared PropertyChanged event instead of emitting its own Feature
[Bind(Default = ...)] — supply a compile-time default (primitive, string, enum, or typeof) that the generated getter returns when the store has no value for the key. The generator verifies the default is implicitly convertible to the property type and emits diagnostic DI002 on mismatch Enhancement
New diagnostic
DI003 — warns when [BindNotify] is set but the class inherits INPC from a base that exposes no accessible OnPropertyChanged, so generated setters would otherwise fail to raise notifications silently 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). An Action<TService> overload is provided when the hook does not need the IServiceProvider BREAKING Feature
The source generator now emits factory-form registrations for every attributed class (e.g.
services.AddSingleton<IFoo>(sp => new Foo(sp.GetRequiredService<IDep>()))) instead of type-based registrations. Constructor selection matches ActivatorUtilities rules ([ActivatorUtilitiesConstructor] wins, else most parameters); [FromKeyedServices("k")] is honored; IServiceProvider parameters are passed through. Fully AOT — no reflection at runtime. This makes attributed services chain-friendly with OnResolved/BindOnResolve and removes the need for AddSingletonAsImplementedInterfaces reflection for multi-interface classes (the generator now emits explicit forwarders) Feature
New
[Bind] attribute on partial properties — generator emits property bodies that read/write from a Shiny key/value store via the new static Shiny.Stores accessor (from Shiny.Extensions.Stores). [Bind] for the default store, [Bind("secure")] for the secure store, [Bind("custom-key")] for any keyed store, and Key = "..." to override the storage key (defaults to the property name) 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-end3.0 - April 29, 2026
Section titled “3.0 - April 29, 2026” 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 schemas2.0 - March 9, 2026
Section titled “2.0 - March 9, 2026” 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 instead1.3.1 - September 19, 2025
Section titled “1.3.1 - September 19, 2025” Fix
Type and AsSelf was being ignored if a base class is being used
v1.3.0 - September 16, 2025
Section titled “v1.3.0 - September 16, 2025” Enhancement
DI registration now supports
AsSelf which allows an implementation to be registered directly1.2.2 - July 26, 2025
Section titled “1.2.2 - July 26, 2025” Fix
Booleans with false were not binding properly on stores
1.2.1 - July 15, 2025
Section titled “1.2.1 - July 15, 2025” Enhancement
Logging has been optionally enabled throughout the DI binding
1.2 - July 14, 2025
Section titled “1.2 - July 14, 2025” 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
1.1 - July 13, 2025
Section titled “1.1 - July 13, 2025” 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
1.0 - July 3, 2025
Section titled “1.0 - July 3, 2025” Feature
Initial Public Release