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                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sparcpoint.Extensions.DependencyInjection" Version="1.6.16" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Sparcpoint.Extensions.DependencyInjection --version 1.6.16                
#r "nuget: Sparcpoint.Extensions.DependencyInjection, 1.6.16"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// 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 (Alias Decorate) - 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

LoggedEndpointClientMeasurePerformanceClientDefaultEndpointClient

chained together decorating the inner services.

See Decorator Pattern

/*
 * 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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