Penggunaan ConfigurationDbContext di IndetityServer4 dari API yang berbeda

Setelah menyelesaikan masalah awal saya dengan menambahkan UserManager ke API (Pembuatan pengguna dengan IdentityServer4 dari beberapa API) yang tidak menginisialisasi IdentityServer4 (yang pada gilirannya diinisialisasi di dalam aplikasi web hanya bertanggung jawab untuk registrasi dan login pengguna) Saya mengalami masalah lain. Dari API yang sama saya juga ingin mendapatkan Klien dan Sumber Daya dari IConfigurationDbContext dari IdentityServer4.

Apa yang saya coba sejauh ini adalah sebagai berikut: Saya menambahkan ConfigurationDbContext di startup API dan kemudian melalui ClientsController dan ClientsRepository saya mencoba mengakses klien seperti yang ditunjukkan di bawah ini.

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 (di .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();
 }

Namun, saya mendapatkan kesalahan berikut:

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

Saya kira lagi-lagi ada hubungannya dengan layanan Startup, tetapi sepertinya saya tidak dapat menemukannya.

Adakah yang memecahkan hal serupa?

Yang terbaik, Marios.


person mkanakis    schedule 08.02.2019    source sumber


Jawaban (1)


Gunakan saja ekstensi ServicesCollection yang sudah ada dalam paket IDS4.EFCore jika Anda ingin menggunakan ini:

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

Ini akan menambahkan IConfigurationDbContext kepada Anda sehingga nantinya dapat digunakan di layanan lain melalui DI.

Gunakan metode statis di bawah ini jika Anda ingin menambahkannya langsung ke 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
Saya tidak punya metode AddConfigurationDbContext, apakah Anda yakin seperti ini? Seperti yang Anda lihat di startup saya, saya menggunakan AddDbContext dengan ConfigurationDbContext tetapi sepertinya tidak berhasil. - person mkanakis; 08.02.2019
comment
@ Davelis4 di mana ConfiguratonDbContext dideklarasikan? Majelis mana yang saya maksud. Juga, saya sudah mengedit jawabannya, saya sedikit salah dalam nama metode. Ini AddConfigurationStore lagipula. - person Vidmantas Blazevicius; 08.02.2019
comment
ConfigurationDbContext dideklarasikan seperti pada pertanyaan saya sebelumnya di WebApp dan bukan di API tempat saya mencoba mengaksesnya. Selain itu, AddConfigurationStore menampilkan hal berikut: IServiceCollection tidak berisi definisi untuk ... dan metode ekstensi terbaik membebani IdentityServerEntityFrameworkBuilderExtensions.AddConfigurationStore(...) memerlukan penerima tipe 'IIdentityServerBuilder;' - person mkanakis; 08.02.2019
comment
@ Davelis4 Oke cukup adil, saya memberi Anda lebih banyak kode agar ini berfungsi langsung dengan ServicesCollection. Buat beberapa kelas ekstensi untuk menampung metode statis ini. - person Vidmantas Blazevicius; 08.02.2019
comment
Ini berhasil, terima kasih banyak. Namun harus bertanya, apa perbedaan utamanya? Karena di startup saya, saya melakukan hal serupa dengan menambahkan ConfigureDbContext sebagai AddDbContext tetapi sepertinya tidak berhasil. - person mkanakis; 08.02.2019
comment
Sesuatu yang saya lupa tanyakan, apakah ini berfungsi sama untuk Sumber Daya kecuali klien? Pernahkah Anda mencobanya sebelumnya? Terima kasih lagi. - person mkanakis; 09.02.2019
comment
@ Davelis4 ya ini juga akan berfungsi untuk menanyakan sumber daya api melalui konteksnya. Dan untuk menjawab pertanyaan Anda yang lain, versi Anda ini tidak berfungsi karena Anda menambahkan tipe ConfigurationDbContext yang konkret tetapi kemudian Anda mencoba menggunakan versi antarmuka di pengontrol Anda. - person Vidmantas Blazevicius; 09.02.2019
comment
Saya menggunakan aplikasi multi-penyewa, jadi bagaimana cara mengonfigurasi penyimpanan konfigurasi berdasarkan kredensial db penyewa? - person vijay; 22.02.2021