asp.net C#>NET 7尝试在构建服务提供程序之前解析服务(使用Singleton)

yxyvkwin  于 2023-02-06  发布在  .NET
关注(0)|答案(1)|浏览(129)

我正在一个带有OAuth扩展的WebApplication中使用.NET 7。
(GitHub)AuthenticationBuilder在构建应用程序和创建DI服务提供程序之前添加到代码部分。
然而,在构建容器之前,我需要使用UnitofWork/Repo/etc的DI链。基于一些阅读,我决定在oAuth事件的匿名方法中示例化容器的早期副本。
一旦我这样做了,UI提示我一个警告,第二个容器正在构建,我明白这完全扼杀了单例的概念,可能不是一个真正的好主意。
关于如何在oAuth.OnCreatingTicket事件中处理DB,有什么建议吗?或者我只需要传递配置并自己手动示例化所有类吗?

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddTransient<IUnitOfWork,UnitOfWork>();
builder.Services.AddSingleton<IDocumentStore>(s => 
    DocumentStoreFactory.CreateStore(
        builder.Configuration["Server"], 
        builder.Configuration["Database"]));

builder.Services.AddAuthentication(...)
    .AddCookie(...)
    .AddGitHub(o =>
    {
        o.ClientId = builder.Configuration["GitHub:ClientID"]!;
        o.ClientSecret = builder.Configuration["GitHub:ClientSecret"]!;
        o.Events = new OAuthEvents
        {
            OnCreatingTicket = async context =>
            {
                //Building a temporary service provider so UnitOfWork/Service/DocumentStore DI chain can be fullfilled
                var sp = builder.Services.BuildServiceProvider();
                await OauthPersistUser.HandleGitHubOauthTicket(context, sp.GetService(typeof(ILogger<>)), sp.GetService<IUnitOfWork>());
            }
        };
    });

var app = builder.Build();
//app Service provider Container is built and ready
v64noz0r

v64noz0r1#

几个小时之后,我意识到oAuth提供者传递的上下文可以通过***HttpContext.RequestServices***访问服务提供者。
这样我就可以将参数减少到只有内容,然后通过以下方式获取UnitOfWork对象:

public static async Task HandleGitHubOauthTicket(OAuthCreatingTicketContext context)
{
    var uow = context.HttpContext.RequestServices.GetService<IUnitOfWork>();
    var log = context.HttpContext.RequestServices.GetService<ILogger<OauthPersistUser>>();

        ...
}

相关问题