Sparcpoint.Extensions.DependencyInjection
1.6.16
dotnet add package Sparcpoint.Extensions.DependencyInjection --version 1.6.16
NuGet\Install-Package Sparcpoint.Extensions.DependencyInjection -Version 1.6.16
<PackageReference Include="Sparcpoint.Extensions.DependencyInjection" Version="1.6.16" />
paket add Sparcpoint.Extensions.DependencyInjection --version 1.6.16
#r "nuget: Sparcpoint.Extensions.DependencyInjection, 1.6.16"
// Install Sparcpoint.Extensions.DependencyInjection as a Cake Addin #addin nuget:?package=Sparcpoint.Extensions.DependencyInjection&version=1.6.16 // Install Sparcpoint.Extensions.DependencyInjection as a Cake Tool #tool nuget:?package=Sparcpoint.Extensions.DependencyInjection&version=1.6.16
Sparcpoint.Extensions.DependencyInjection
Decoration and child service extensions for Microsoft.Extensions.DependencyInjection
Installation
Package Manager Console
Install-Package Sparcpoint.Extensions.DependencyInjection
.NET Core CLI
dotnet add package Sparcpoint.Extensions.DependencyInjection
Usage
This library adds three extension methods to IServiceCollection
Decorate
- Allows usage of the decorator pattern with Microsoft DI.WithChildServices
- Allows an isolated scope of service injection for a parent service.DecorateWithChildServices
(AliasDecorate
) - Allows usage of the decorator pattern (including child services) with Microsoft DI.
Examples
Decoration
Decoration allows for extending functionality of a class without changing the interface or the original implementation. Instead, you wrap instances of implementations that provide common functionality.
An example might be that you have a service that sends and receives from an endpoint called DefaultEndpointClient : IEndpointClient
. You would like to introduce logging and performance measurements. However, you know if you add it directly to your implementation, you cannot use those again. Instead, you decorate IEndpointClient
with a LoggedEndpointClient : IEndpointClient
and a MeasurePerformanceClient : IEndpointClient
, both of which take a IEndpointClient
into its constructor. Now you have
LoggedEndpointClient
→ MeasurePerformanceClient
→ DefaultEndpointClient
chained together decorating the inner services.
/*
* Basic Usage
* The most common usage of decorators
*/
ServiceCollection services = new();
// Add the root service
services.AddSingleton<IService, ServiceImplementation>();
// Decorate all services currently registered
services.Decorate<IService, LoggingImplementation>();
// Build the provider
IServiceProvider provider = services.BuildServiceProvider();
// When we provide the service, we will receive ServiceDecorator first,
// while the inner service will be the ServiceImplementation
// LoggingImplementation -> ServiceImplementation -> IService
var instance = provider.GetRequiredService<IService>();
/*
* Open Generic Usage
* We can also decorate open generics
*/
ServiceCollection services = new();
// Add the root service
services.AddSingleton<IEventProcessor<ServiceEvent>, DefaultEventProcessor<ServiceEvent>>();
// Decorate all services currently registered
services.Decorate(typeof(IEventProcessor<>), typeof(MeasurePerformanceProcessor<>));
// Build the provider
IServiceProvider provider = services.BuildServiceProvider();
// Like the basic use case, we have decorated the previously registered services
// MeasurePerformanceProcessor<ServiceEvent> -> DefaultEventProcessor<ServiceEvent> -> IEventProcessor<ServiceEvent>
var instance = provider.GetRequiredService<IEventProcessor<ServiceEvent>>();
Child Services
Child Services allow for certain instances of services to be built with an isolated set of registered services separated from the main provider. This allows for sub-services to be different as needed from implementation to implementation
/*
* Basic Usage
*/
ServiceCollection services = new();
// This service is registered with the root provider.
services.AddSingleton<IMessageBus, InMemoryServiceBus>();
services.WithChildServices<DefaultAccountService>(child =>
{
// All services in this container will be used to create the DefaultAccountService
// Extra services are ignored
services.AddSingleton<IMessageBus>(p => new AzureServiceBus("connectionString"));
});
var provider = services.BuildServiceProvider();
// This will return a DefaultAccountService with an AzureServiceBus implementation
// DefaultAccountService -> AzureServiceBus
var accountService = provider.GetRequiredService<DefaultAccountService>();
// This will return the "default" implementation of InMemoryServiceBus
var messageBus = provider.GetRequiredService<IMessageBus>();
/*
* Setting the Parent's Lifetime
* By default, a parent is setup as a Singleton. If you need
* a different lifetime, it is specified as a parameter on
* WithChildServices(...)
*/
// DefaultAccountService will have a Transient lifetime
// and will be created on every provide of this service
services.WithChildServices<DefaultAccountService>(child =>
{
services.AddSingleton<IMessageBus>(p => new AzureServiceBus("connectionString"));
}, lifetime: ServiceLifetime.Transient);
/*
* Decoration Example
* Sometimes you may not want to simply replace the parent service
* Instead, you may want to decorate it
*/
ServiceCollection services = new();
// This service is registered with the root provider.
services.AddSingleton<IMessageBus, InMemoryServiceBus>();
services.WithChildServices<DefaultAccountService>(child =>
{
services.Decorate<IMessageBus, LoggedMessageBus>();
});
var provider = services.BuildServiceProvider();
// This will return a DefaultAccountService with a LoggedMessageBus implementation
// DefaultAccountService -> LoggedMessageBus -> InMemoryServiceBus
var accountService = provider.GetRequiredService<DefaultAccountService>();
// This will return the "default" implementation of InMemoryServiceBus
var messageBus = provider.GetRequiredService<IMessageBus>();
Decorate w/ Child Services
Like above, we can also decorate while injecting child services, as necessary.
Caveat: This can only be used with a closed implementation. Open-generics are NOT supported.
/*
* Basic Usage
*/
ServiceCollection services = new();
// Add the root service
services.AddSingleton<IService, ServiceImplementation>();
// Decorate all services currently registered (w/ Child Services)
services.DecorateWithChildServices<IService, LoggingImplementation>(child =>
{
child.AddSingleton<IOtherService, OtherServiceImplementation>();
});
/*
* Alternate Syntax
*/
ServiceCollection services = new();
// Add the root service
services.AddSingleton<IService, ServiceImplementation>();
// Decorate all services currently registered (w/ Child Services)
services.Decorate<IService, LoggingImplementation>(child =>
{
child.AddSingleton<IOtherService, OtherServiceImplementation>();
});
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.DependencyInjection (>= 6.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Sparcpoint.Extensions.DependencyInjection:
Package | Downloads |
---|---|
Sparcpoint.Extensions.Objects
Modules used to manage objects, their hierarchy and storage |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.6.16 | 1,031 | 6/5/2024 |
1.6.15 | 119 | 5/19/2024 |
1.6.14 | 123 | 5/19/2024 |
1.6.13 | 249 | 5/17/2024 |
1.6.12 | 134 | 5/17/2024 |
1.6.11 | 131 | 5/16/2024 |
1.6.10 | 123 | 5/16/2024 |
1.6.9 | 135 | 5/16/2024 |
1.6.8 | 119 | 5/16/2024 |
1.6.7 | 119 | 5/16/2024 |
1.6.6 | 116 | 5/15/2024 |
1.6.5 | 112 | 5/12/2024 |
1.6.4 | 176 | 4/30/2024 |
1.6.3 | 155 | 4/27/2024 |
1.6.2 | 157 | 4/22/2024 |
1.6.1 | 134 | 4/22/2024 |
1.6.0 | 139 | 4/21/2024 |
1.5.3 | 205 | 4/19/2024 |
1.5.2 | 129 | 4/18/2024 |
1.5.1 | 132 | 4/17/2024 |
1.4.0 | 154 | 4/3/2024 |
1.3.0 | 152 | 3/30/2024 |
1.2.0 | 107 | 3/27/2024 |
1.1.1 | 121 | 3/25/2024 |
1.1.0 | 124 | 3/25/2024 |
1.0.3 | 119 | 3/8/2024 |
1.0.1 | 147 | 2/13/2024 |
1.0.0 | 104 | 2/13/2024 |
Initial Offering