การใช้ ConfigurationDbContext ใน IndetityServer4 จาก API ที่แตกต่างกัน

หลังจากแก้ไขปัญหาเริ่มต้นของฉันด้วยการเพิ่ม UserManager ให้กับ API (การสร้างผู้ใช้ด้วย IdentityServer4 จากหลาย API) ที่ไม่ได้เริ่มต้น IdentityServer4 (ซึ่งจะเริ่มต้นภายในเว็บแอปที่รับผิดชอบเฉพาะการลงทะเบียนและการเข้าสู่ระบบของผู้ใช้เท่านั้น) ฉันพบปัญหาอื่น จาก API เดียวกัน ฉันต้องการรับลูกค้าและทรัพยากรจาก IConfigurationDbContext ของ IdentityServer4 ด้วย

สิ่งที่ฉันกำลังลองอยู่ตอนนี้มีดังต่อไปนี้: ฉันกำลังเพิ่ม ConfigurationDbContext ในการเริ่มต้นของ API จากนั้นผ่าน ClientsController และ ClientsRepository ฉันกำลังพยายามเข้าถึงไคลเอนต์ดังที่แสดงด้านล่าง

Startup.cs

 services.AddDbContext<ApplicationDbContext>(options =>
        options.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXX"))
    );

 services.AddDbContext<ConfigurationDbContext>(options =>
        options.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXXX"))
    );

  services.AddIdentityCore<ApplicationUser>(options => {
        options.Password.RequireNonAlphanumeric = false;
    });
    new IdentityBuilder(typeof(ApplicationUser), typeof(IdentityRole), services)
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddSignInManager<SignInManager<ApplicationUser>>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

ClientsRepository.cs (ใน .DataAccess):

private readonly IConfigurationDbContext _context;
public bool AutoSaveChanges { get; set; } = true;

public ClientRepository(IConfigurationDbContext context)
{
    _context = context;
}

public Task<Client> GetClientAsync(int id)
{
    return _context.Clients
        .Include(x => x.AllowedGrantTypes)
        .Include(x => x.RedirectUris)
        .Include(x => x.PostLogoutRedirectUris)
        .Include(x => x.AllowedScopes)
        .Include(x => x.ClientSecrets)
        .Include(x => x.Claims)
        .Include(x => x.IdentityProviderRestrictions)
        .Include(x => x.AllowedCorsOrigins)
        .Include(x => x.Properties)
        .Where(x => x.Id == id)
            .SingleOrDefaultAsync();
 }

อย่างไรก็ตาม ฉันได้รับข้อผิดพลาดดังต่อไปนี้:

System.InvalidOperationException: Unable to resolve service for type 'IdentityServer4.EntityFramework.Interfaces.IConfigurationDbContext' while attempting to activate 'XXXXXX.Data.Repositories.ClientRepository'. 

ฉันเดาว่ามันจะต้องทำอะไรบางอย่างกับบริการเริ่มต้นอีกครั้ง แต่ดูเหมือนจะหามันไม่เจอ

มีใครแก้ไขสิ่งที่คล้ายกันบ้างไหม?

ดีที่สุด มาริออส


person mkanakis    schedule 08.02.2019    source แหล่งที่มา


คำตอบ (1)


เพียงใช้ส่วนขยาย ServicesCollection ที่มีอยู่แล้วในแพ็คเกจ IDS4.EFCore หากคุณต้องการใช้สิ่งเหล่านี้:

        services.AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = builder => builder.UseNpgsql(defaultConnection, db => db.MigrationsAssembly("XXXXXXXX"));
        });

สิ่งนี้จะเพิ่ม IConfigurationDbContext ให้คุณเพื่อให้สามารถใช้ในบริการอื่น ๆ ผ่าน DI ได้ในภายหลัง

ใช้วิธีการคงที่ด้านล่างหากคุณต้องการเพิ่มลงใน ServicesCollection โดยตรง:

    public static IServiceCollection AddConfigurationStore(this IServiceCollection services,
        Action<ConfigurationStoreOptions> storeOptionsAction = null)
    {
        return services.AddConfigurationStore<ConfigurationDbContext>(storeOptionsAction);
    }

    public static IServiceCollection AddConfigurationStore<TContext>(this IServiceCollection services,
    Action<ConfigurationStoreOptions> storeOptionsAction = null)
    where TContext : DbContext, IConfigurationDbContext
    {
        var options = new ConfigurationStoreOptions();
        services.AddSingleton(options);
        storeOptionsAction?.Invoke(options);

        if (options.ResolveDbContextOptions != null)
        {
            services.AddDbContext<TContext>(options.ResolveDbContextOptions);
        }
        else
        {
            services.AddDbContext<TContext>(dbCtxBuilder =>
            {
                options.ConfigureDbContext?.Invoke(dbCtxBuilder);
            });
        }
        services.AddScoped<IConfigurationDbContext, TContext>();

        return services;
    }
person Vidmantas Blazevicius    schedule 08.02.2019
comment
ฉันไม่มีวิธี AddConfigurationDbContext ใด ๆ คุณแน่ใจหรือว่าเป็นเช่นนี้ อย่างที่คุณเห็นในการเริ่มต้นของฉัน ฉันใช้ AddDbContext กับ ConfigurationDbContext แต่ดูเหมือนว่าจะไม่ได้ผล - person mkanakis; 08.02.2019
comment
@ Davelis4 ConfiguratonDbContext ประกาศที่ไหน? ฉันหมายถึงชุดประกอบใด นอกจากนี้ฉันได้แก้ไขคำตอบแล้ว ฉันผิดเล็กน้อยในชื่อวิธี หลังจากนั้นก็เป็น AddConfigurationStore - person Vidmantas Blazevicius; 08.02.2019
comment
ConfigurationDbContext ได้รับการประกาศเหมือนในคำถามก่อนหน้าของฉันใน WebApp และไม่ได้อยู่ใน API ที่ฉันพยายามเข้าถึง นอกจากนี้ AddConfigurationStore ยังแสดงสิ่งต่อไปนี้: IServiceCollection ไม่มีคำจำกัดความสำหรับ ... และวิธีการขยายที่ดีที่สุดโอเวอร์โหลด IdentityServerEntityFrameworkBuilderExtensions.AddConfigurationStore(...) ต้องใช้ตัวรับประเภท 'IIdentityServerBuilder;' - person mkanakis; 08.02.2019
comment
@ Davelis4 โอเค พอใช้ได้ ฉันให้โค้ดเพิ่มเติมแก่คุณเพื่อให้งานนี้ทำงานกับ ServicesCollection ได้โดยตรง สร้างคลาสส่วนขยายเพื่อเก็บวิธีการคงที่เหล่านี้ - person Vidmantas Blazevicius; 08.02.2019
comment
มันได้ผล ขอบคุณมาก ต้องถามว่าอะไรคือความแตกต่างที่สำคัญ? เพราะในการเริ่มต้นของฉัน ฉันได้ทำสิ่งที่คล้ายกันโดยเพิ่ม ConfigureDbContext เป็น AddDbContext แต่ดูเหมือนจะไม่ทำงาน - person mkanakis; 08.02.2019
comment
สิ่งที่ฉันลืมถาม สิ่งนี้ใช้ได้กับทรัพยากรยกเว้นไคลเอนต์หรือไม่ คุณเคยลองมาก่อนหรือไม่? ขอบคุณอีกครั้ง. - person mkanakis; 09.02.2019
comment
@ Davelis4 ใช่แล้ว สิ่งนี้จะใช้ได้กับการค้นหาทรัพยากร api เช่นกันผ่านบริบท และเพื่อตอบคำถามอื่นๆ ของคุณ เวอร์ชันนี้ใช้งานไม่ได้เนื่องจากคุณได้เพิ่ม ConfigurationDbContext ประเภทที่เป็นรูปธรรม แต่แล้วคุณพยายามใช้เวอร์ชันอินเทอร์เฟซในคอนโทรลเลอร์ของคุณ - person Vidmantas Blazevicius; 09.02.2019
comment
ฉันใช้แอปพลิเคชันผู้เช่าหลายราย ดังนั้นจะกำหนดค่าที่เก็บการกำหนดค่าตามข้อมูลรับรองฐานข้อมูลผู้เช่าได้อย่างไร - person vijay; 22.02.2021