mengapa mendaftarkan layanan ganda saat menggunakan fungsi pabrik

Saya sedang membaca buku yang menunjukkan cara kerja Dependency Injection saat menggunakan fungsi pabrik, di bawah ini kodenya:

//MemoryRepository implements IRepository

public class Startup
{
    private IHostingEnvironment env;

    public Startup(IHostingEnvironment hostEnv) => env = hostEnv;

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IRepository>(provider =>
        {
            if (env.IsDevelopment())
            {
                var x = provider.GetService<MemoryRepository>();
                return x;
            }
            else
            {
                return new XXX();  //return sth else;
            }
        });
        services.AddTransient<MemoryRepository>();
        ...//register other components which are dependencies of MemoryRepository
        services.AddMvc();
    }
    ...
}

Saya tidak tahu mengapa services.AddTransient<MemoryRepository>(); diperlukan?

Karena services.AddTransient<IRepository>{...} sudah mendefinisikan ruang lingkup "Transient", yang berarti bahwa "setiap kali IRepository diperlukan, objek MemoryRepository baru akan disediakan (jika itu adalah lingkungan pengembangan)", jadi semuanya sudah diatur, dependensi MemoryRepository lainnya akan ditangani dengan registrasi berikut ini.

Q1-Jadi kenapa kita masih perlu memiliki services.AddTransient<MemoryRepository>(); lagi? kalau saya komen, aplikasinya tidak bisa jalan, jadi pernyataan ini perlu, cuma gak tau kenapa

Q2- jika saya mengubah konfigurasi Layanan sebagai:

public void ConfigureServices(IServiceCollection services)
{
   services.AddTransient<IRepository, MemoryRepository>();
   ...
}

aplikasi berjalan dengan sukses, jadi mengapa saya tidak perlu menambahkan services.AddTransient<MemoryRepository>(); sebagai:

public void ConfigureServices(IServiceCollection services)
{
   services.AddTransient<IRepository, MemoryRepository>();
   services.AddTransient<MemoryRepository>();
   ...
}

person Community    schedule 01.08.2019    source sumber


Jawaban (1)


Yang pertama

services.AddTransient<IRepository>(...

memberi tahu penyedia apa yang harus dilakukan ketika diminta untuk menyelesaikan IRepository

Yang kedua

services.AddTransient<MemoryRepository>();

memberi tahu penyedia apa yang harus dilakukan ketika diminta untuk menyelesaikan MemoryRepository

Anda secara teknis tidak mendaftar "ganda".

Jadi mengapa kita masih perlu memiliki services.AddTransient<MemoryRepository>()

Sehingga kapan

provider.GetService<MemoryRepository>();

dipanggil dalam delegasi pabrik, penyedia mengetahui cara menyelesaikannya untuk memenuhi kondisi lingkungan pengembangan.

Contoh kode pada dasarnya menunjukkan cara melakukan ketergantungan bersyarat, yang menurut saya sudah Anda pahami.

Q2

Dalam skenario kedua, pendaftaran kedua tidak diperlukan

services.AddTransient<MemoryRepository>();

karena dalam hal ini hanya implementasi tunggal yang diperlukan kecuali ada kebutuhan eksplisit untuk menggunakan MemoryRepository sebagai ketergantungan yang disuntikkan

person Nkosi    schedule 01.08.2019
comment
Saya mengedit postingan saya, bisakah Anda melihat Q2, sesuai dengan apa yang Anda katakan, saya perlu memiliki services.AddTransient<MemoryRepository>(), tetapi saya tidak memilikinya dan aplikasi masih berjalan dengan sukses. - person ; 01.08.2019
comment
Mengapa? bukankah services.AddTransient<IRepository, MemoryRepository>(); artinya ketika ditanya 'IRepository' menyediakan objek MemoryRepository baru, bukankah penyedia masih perlu diinstruksikan apa yang harus dilakukan ketika diminta untuk menyelesaikan MemoryRepository? - person ; 01.08.2019
comment
Hanya jika Anda perlu menggunakan MemoryRepository secara eksplisit sebagai ketergantungan yang disuntikkan - person Nkosi; 01.08.2019
comment
jadi maksud Anda services.AddTransient<XXX, YYY>(); adalah fungsi pembungkus untuk services.AddTransient<XXX>(provider =>...? inti asp.net melakukan hal-hal di belakang layar? - person ; 01.08.2019
comment
Di satu sisi, ya. Itu bisa menjadi cara untuk melihatnya - person Nkosi; 01.08.2019