DependencyInjection.StaticAccessor 9.0.0-preview-1733580617

This is a prerelease version of DependencyInjection.StaticAccessor.
There is a newer version of this package available.
See the version list below for details.
dotnet add package DependencyInjection.StaticAccessor --version 9.0.0-preview-1733580617                
NuGet\Install-Package DependencyInjection.StaticAccessor -Version 9.0.0-preview-1733580617                
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="DependencyInjection.StaticAccessor" Version="9.0.0-preview-1733580617" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add DependencyInjection.StaticAccessor --version 9.0.0-preview-1733580617                
#r "nuget: DependencyInjection.StaticAccessor, 9.0.0-preview-1733580617"                
#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 DependencyInjection.StaticAccessor as a Cake Addin
#addin nuget:?package=DependencyInjection.StaticAccessor&version=9.0.0-preview-1733580617&prerelease

// Install DependencyInjection.StaticAccessor as a Cake Tool
#tool nuget:?package=DependencyInjection.StaticAccessor&version=9.0.0-preview-1733580617&prerelease                

DependencyInjection.StaticAccessor

δΈ­ζ–‡ | English

DependencyInjection.StaticAccessor is dedicated to providing static access to the IServiceProvider object corresponding to the current DI Scope for various types of .NET projects. This allows you to easily use IServiceProvider in static methods and in types where direct interaction with DI services is not possible.

NuGet Packages Overview

Package Name Purpose
DependencyInjection.StaticAccessor.Hosting For AspNetCore projects (WebApi, Mvc, etc.) and Generic Host
DependencyInjection.StaticAccessor.Blazor For Blazor projects, including Blazor Server and Blazor WebAssembly Server
DependencyInjection.StaticAccessor.Blazor.WebAssembly For Blazor WebAssembly Client projects, also supports Auto mode for Client projects
DependencyInjection.StaticAccessor Base library, A non-startup project using PinnedScope references the package

Version Number Explanation

All version numbers follow the Semantic Versioning format. The major version matches the version of Microsoft.Extensions.* ( please make sure the major version matches the Microsoft.Extensions.* version you are using when referencing the NuGet package). The minor version indicates feature updates, while the patch version is for bug fixes.

Quick Start

Install the corresponding NuGet package based on your project type, as listed in the NuGet Packages Overview.

// 1. Initialization (Generic Host)
var builder = Host.CreateDefaultBuilder();

builder.UsePinnedScopeServiceProvider(); // Only this step to complete initialization

var host = builder.Build();

host.Run();

// 2. Access anywhere
class Test
{
    public static void M()
    {
        var yourService = PinnedScope.ScopedServices.GetService<IYourService>();
    }
}

The initialization method is similar for different project types, and all require calling the UsePinnedScopeServiceProvider extension method. Example initialization code for different project types will be provided later.

AspNetCore Project Initialization Example

Install the NuGet package

dotnet add package DependencyInjection.StaticAccessor.Hosting

// 1. Initialization
var builder = WebApplication.CreateBuilder();

builder.Host.UsePinnedScopeServiceProvider(); // Just this step to complete the initialization

var app = builder.Build();

app.Run();

Blazor Server-Side Project Initialization

Note: The Blazor Server-side here includes Server, WebAssembly, and Auto modes of the Server-side project, not just the Server mode specifically.

Install the NuGet package

dotnet add package DependencyInjection.StaticAccessor.Blazor

The initialization process for Blazor Server-side is the same as AspNetCore. Please refer to the AspNetCore Project Initialization Example. However, since Blazor's DI scope is different from the conventional one, additional steps are required.

Inherit PinnedScopeComponentBase for Pages

Due to Blazor's unique DI scope, all pages need to inherit from PinnedScopeComponentBase. It is recommended to define this once in _Imports.razor so that it applies to all pages.

// _Imports.razor

@inherits DependencyInjection.StaticAccessor.Blazor.PinnedScopeComponentBase

In addition to PinnedScopeComponentBase, PinnedScopeOwningComponentBase and PinnedScopeLayoutComponentBase are also provided, and more types may be added as needed.

Solution for Existing Custom ComponentBase Base Classes

You might be using a ComponentBase base class defined by another package, and since C# does not support multiple inheritance, here is a solution that does not require inheriting from PinnedScopeComponentBase.

// Assuming your current ComponentBase base class is ThirdPartyComponentBase

// Define a new base class that inherits from ThirdPartyComponentBase
public class YourComponentBase : ThirdPartyComponentBase, IHandleEvent, IServiceProviderHolder
{
    private IServiceProvider _serviceProvider;

    [Inject]
    public IServiceProvider ServiceProvider
    {
        get => _serviceProvider;
        set
        {
            PinnedScope.Scope = new FoolScope(value);
            _serviceProvider = value;
        }
    }

    Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, object? arg)
    {
        return this.PinnedScopeHandleEventAsync(callback, arg);
    }
}

// _Imports.razor
@inherits YourComponentBase

Blazor WebAssembly Client Initialization

Note: This is for Blazor WebAssembly Client-side initialization. For Server-side initialization, please refer to Blazor Server-Side Project Initialization

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.UsePinnedScopeServiceProvider(); // Just this step to complete the initialization

await builder.Build().RunAsync();

Similar to the Server-side, Client-side pages also need to inherit from PinnedScopeComponentBase. Please refer to Inherit PinnedScopeComponentBase for Pages.

Notes

Do Not Operate IServiceScope Through PinnedScope

Although you can access the current DI Scope via PinnedScope.Scope, please do not directly manipulate PinnedScope.Scope, such as calling the Dispose method. Instead, you should operate through the variable created when you initially created the scope.

Does Not Support Non-Standard Scopes

In typical development scenarios, this issue usually does not need to be addressed, and it generally does not occur in standard AspNetCore projects. However, Blazor is an example of a non-standard DI Scope in official project types.

Before explaining what a non-standard Scope is, let's first talk about the standard Scope mode. We know that DI Scopes can be nested, and under normal circumstances, the nested Scopes form a stack structure, where the most recently created Scope is released first, in an orderly manner.

using (var scope11 = serviceProvider.CreateScope())                    // push scope11. [scope11]
{
    using (var scope21 = scope11.ServiceProvider.CreateScope())        // push scope21. [scope11, scope21]
    {
        using (var scope31 = scope21.ServiceProvider.CreateScope())    // push scope31. [scope11, scope21, scope31]
        {

        }                                                              // pop scope31.  [scope11, scope21]

        using (var scope32 = scope21.ServiceProvider.CreateScope())    // push scope32. [scope11, scope21, scope32]
        {

        }                                                              // pop scope32.  [scope11, scope21]
    }                                                                  // pop scope21.  [scope11]

    using (var scope22 = scope11.ServiceProvider.CreateScope())        // push scope22. [scope11, scope22]
    {

    }                                                                  // pop scope22.  [scope11]
}                                                                      // pop scope11.  []

With this understanding of standard Scopes, non-standard Scopes can be easily understood. Any Scope that does not follow this orderly stack structure is considered a non-standard Scope. A common example is the scenario with Blazor:

As we know, Blazor SSR implements SPA through SignalR, where each SignalR connection corresponds to a DI Scope. Various events on the interface (clicks, focus acquisition, etc.) notify the server to callback event functions via SignalR. These callbacks are inserted externally to interact with SignalR. Without special handling, the Scope belonging to the callback event is a newly created Scope for that event. However, the Component we interact with in the callback event is created within the Scope belonging to SignalR, resulting in cross-Scope interaction. PinnedScopeComponentBase addresses this by resetting PinnedScope.Scope to the SignalR corresponding Scope before executing the callback function.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on DependencyInjection.StaticAccessor:

Package Downloads
DependencyInjection.StaticAccessor.Hosting

This is for the hosting startup project to ensure that you can use the static property PinnedScope.ScopedServices.

Rougamo.Extensions.DependencyInjection.Microsoft

Provide extension methods to access Microsoft DepenencyInjection in Rougamo aspect classes.

DependencyInjection.StaticAccessor.Blazor.WebAssembly

This is for the Blazor client-side project and provides a setup method to ensure that you can use the static property PinnedScope.ScopedServices.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
9.0.0 596 12/14/2024
9.0.0-preview-1733580617 994 12/7/2024
8.1.0 123 12/13/2024
8.1.0-preview-1734072808 97 12/13/2024
8.0.0 527 9/18/2024
8.0.0-preview-1726647274 205 9/18/2024
8.0.0-preview-1726214654 116 9/13/2024
8.0.0-preview-1726080008 110 9/11/2024
7.0.0 186 9/18/2024
7.0.0-preview-1726646818 155 9/18/2024
7.0.0-preview-1726214086 105 9/13/2024
7.0.0-preview-1726079148 113 9/11/2024
6.0.0 176 9/18/2024
6.0.0-preview-1726646692 174 9/18/2024
6.0.0-preview-1726212998 103 9/13/2024
6.0.0-preview-1726078946 112 9/11/2024
3.0.0 189 9/18/2024
3.0.0-preview-1726646466 191 9/18/2024
3.0.0-preview-1726212320 109 9/13/2024
3.0.0-preview-1726078421 122 9/11/2024