第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

禁用 Program 類中的依賴項注入范圍驗證功能?

禁用 Program 類中的依賴項注入范圍驗證功能?

C#
隔江千里 2023-09-24 10:43:45
我的教科書展示了一個構建身份服務的示例,下面是代碼://startup.cs    public void Configure(IApplicationBuilder app) {   app.UseStatusCodePages();   app.UseDeveloperExceptionPage();   app.UseStaticFiles();   app.UseAuthentication();   app.UseMvcWithDefaultRoute();   //try to seed an admin account for the first time the app runs   AppIdentityDbContext.CreateAdminAccount(app.ApplicationServices, Configuration).Wait();}//AppIdentityDbContext.cspublic class AppIdentityDbContext : IdentityDbContext<AppUser>{    public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options) : base(options) { }    public static async Task CreateAdminAccount(IServiceProvider serviceProvider, IConfiguration configuration)    {        UserManager<AppUser> userManager = serviceProvider.GetRequiredService<UserManager<AppUser>>();        RoleManager<IdentityRole> roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();        string username = configuration["Data:AdminUser:Name"];        string email = configuration["Data:AdminUser:Email"];        string password = configuration["Data:AdminUser:Password"];        string role = configuration["Data:AdminUser:Role"];            }        }    }}然后教科書上說:因為我通過 IApplicationBuilder.ApplicationServices 提供程序訪問作用域服務,所以我還必須禁用 Program 類中的依賴項注入作用域驗證功能,如下所示://Program.cspublic static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseDefaultServiceProvider(options => options.ValidateScopes = false) .Build();我對 DI 有基本的了解,但我對這個例子很困惑,以下是我的問題:Q1-通過 IApplicationBuilder.ApplicationServices 提供程序訪問范圍服務 是什么意思?它嘗試訪問哪些服務?為什么它的作用域不是瞬態(tài)的或單例的?Q2-為什么我們必須禁用依賴注入范圍驗證,范圍驗證試圖實現什么目的?
查看完整描述

1 回答

?
手掌心

TA貢獻1942條經驗 獲得超3個贊

為了了解發(fā)生了什么,您首先必須了解依賴注入生命周期之間的差異:

  • 瞬態(tài):為每個解決的依賴關系創(chuàng)建一個新實例。

  • Singleton:每當服務得到解決時,就會使用單個共享實例。

  • 范圍:每當服務在單個范圍(或請求)內得到解析時,就會共享單個實例。后續(xù)請求將意味著將再次創(chuàng)建一個新實例。

數據庫上下文保存與數據庫的連接。這就是為什么您通常不希望它成為單例,這樣您就不會在應用程序的整個生命周期中保持單個連接打開。所以你想讓它成為暫時的。但是,如果您需要在處理單個請求時多次訪問數據庫,則需要在短時間內多次打開數據庫連接。因此,折衷方案是默認使其成為范圍依賴項:這樣您就不會長時間保持連接打開,但您仍然可以在短時間內重用連接。

現在,讓我們考慮一下當單例服務依賴于非單例服務時會發(fā)生什么:單例服務只創(chuàng)建一次,因此它的依賴關系也只解決一次。這意味著它所具有的任何依賴項現在都在該服務的整個生命周期(即應用程序的生命周期)中有效共享。因此,通過依賴非單例服務,您可以有效地使這些服務成為準單例。

這就是為什么(在開發(fā)期間)存在保護措施,可以防止您犯此錯誤:作用域驗證將檢查您是否不依賴于作用域之外的作用域服務,例如在單例服務內。這樣,您就不會逃避該范圍服務的預期生命周期。

當您現在AppIdentityDbContext.CreateAdminAccount在該方法內運行時Configure,您是在范圍之外運行它。所以你基本上處于“單身土地”內。您現在創(chuàng)建的任何依賴項都將保留。由于您解析了UserManager<AppUser>RoleManager<IdentityRole>兩者都依賴于作用域數據庫上下文,因此您現在正在轉義數據庫上下文的配置作用域生命周期。

為了解決這個問題,您應該創(chuàng)建一個短暫的作用域,然后您可以在其中訪問作用域服務(因為您位于作用域內),當作用域終止時,這些服務將被正確清理:

public static async Task CreateAdminAccount(IServiceProvider serviceProvider, IConfiguration configuration)

{

    // get service scope factory (you could also pass this instead of the service provider)

    var serviceScopeFactory = serviceProvider.GetService<IServiceScopeFactory>();


    // create a scope

    using (var scope = serviceScopeFactory.CreateScope())

    {

        // resolve the services *within that scope*

        var userManager = scope.ServiceProvider.GetRequiredService<UserManager<AppUser>>();

        var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();


        // do stuff

    }

    // scope is terminated after the using ends, and all scoped dependencies will be cleaned up

}


查看完整回答
反對 回復 2023-09-24
  • 1 回答
  • 0 關注
  • 121 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號