Skip to content

Instantly share code, notes, and snippets.

@relyky
Last active January 12, 2022 09:41
Show Gist options
  • Save relyky/3cdd43455cd6c47148da7500d74cba8f to your computer and use it in GitHub Desktop.
Save relyky/3cdd43455cd6c47148da7500d74cba8f to your computer and use it in GitHub Desktop.
.NET6, IServiceProvider, ServiceActivator, 手動注入物件
/// ref→[Consuming a scoped service in a background task](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio#consuming-a-scoped-service-in-a-background-task)
※ 手動注入物件
internal class MyConsumeScopedServiceHostedService : BackgroundService
{
readonly IServiceProvider _provider;
public MyConsumeScopedServiceHostedService(IServiceProvider provider,)
{
_provider = provider;
}
private async Task DoWork(CancellationToken stoppingToken)
{
//※注意:需繞一圈來注入(injection) scope 服務物件。
/// 因為 BackgroundService 是 singleton 服務物件而 scope 與 singleton 這兩者不能一起注入。
using var scope = _provider.CreateScope();
// 注入 scope 服務物件
var scopedService = scope.ServiceProvider.GetRequiredService<IMyScopedService>();
//# 終於開始執行工作
await scopedService.DoWork(stoppingToken);
}
}
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Vista.Biz.AOP
{
/// <summary>
/// Add static service resolver to use when dependencies injection is not available
/// ref → [Resolving instances with ASP.NET Core DI in static classes](https://www.davidezoccarato.cloud/resolving-instances-with-asp-net-core-di-in-static-classes/)
/// 請在 Startup 把 IServiceProvider 註冊進來使用。
/// </summary>
public class ServiceActivator
{
//internal static IServiceProvider _serviceProvider = null;
internal static IServiceProvider _serviceProvider
{
get => AppDomain.CurrentDomain.GetData("Host:ServiceProvider") as IServiceProvider;
set => AppDomain.CurrentDomain.SetData("Host:ServiceProvider", value);
}
/// <summary>
/// Configure ServiceActivator with full serviceProvider
/// 請在 Program/Startup 執行以把 IServiceProvider 註冊進來使用。
/// </summary>
public static void Configure(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <summary>
/// Create a scope where use this ServiceActivator
/// </summary>
public static IServiceScope GetScope(IServiceProvider serviceProvider = null)
{
var provider = serviceProvider ?? _serviceProvider;
return provider?
.GetRequiredService<IServiceScopeFactory>()
.CreateScope();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment