Akademi C# · Pelajaran

Suntikan Konstruktor & Antara Muka

Gunakan suntikan konstruktor dengan reka bentuk berasaskan antara muka untuk menyahgandingkan komponen dan membolehkan ujian unit.

Pelajaran 3 daripada 413 langkah

Suntikan Konstruktor & Antara Muka ialah pelajaran Akademi C# percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Akademi C#, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.

Asas Suntikan melalui Pembina

Suntikan melalui pembina ialah corak DI yang paling biasa. Kelas mengisytiharkan kebergantungannya sebagai parameter pembina, dan bekas menyediakannya semasa penciptaan tika.

Ini menjadikan kebergantungan jelas, wajib dan kelihatan.

Mendefinisikan Antara Muka

Mulakan dengan antara muka yang mentakrifkan kontrak. Ini membolehkan pelaksanaan yang berbeza, sama ada sebenar, palsu atau dalam memori, ditukar tanpa mengubah kod yang bergantung padanya.

public interface IProductRepository
{
    Task<Product?> GetByIdAsync(int id);
    Task<IEnumerable<Product>> GetAllAsync();
    Task AddAsync(Product product);
}

Melaksanakan Antara Muka

Pelaksanaan konkrit mengendalikan kerja sebenar — panggilan pangkalan data, permintaan HTTP dan sebagainya. Pengguna tidak perlu mengetahui pelaksanaan yang diterimanya.

public class SqlProductRepository : IProductRepository
{
    private readonly AppDbContext _db;

    public SqlProductRepository(AppDbContext db) => _db = db;

    public async Task<Product?> GetByIdAsync(int id)
        => await _db.Products.FindAsync(id);

    public async Task<IEnumerable<Product>> GetAllAsync()
        => await _db.Products.ToListAsync();

    public async Task AddAsync(Product product)
    {
        _db.Products.Add(product);
        await _db.SaveChangesAsync();
    }
}

Menggunakan melalui Pembina

Lapisan perkhidmatan menerima IProductRepository sebagai parameter pembina. Ia tidak pernah mengetahui tentang SqlProductRepository — hanya kontrak antara muka.

public class ProductService
{
    private readonly IProductRepository _repo;
    private readonly ILogger<ProductService> _logger;

    public ProductService(
        IProductRepository repo,
        ILogger<ProductService> logger)
    {
        _repo = repo;
        _logger = logger;
    }

    public async Task<Product?> GetProductAsync(int id)
    {
        _logger.LogInformation("Fetching product {Id}", id);
        return await _repo.GetByIdAsync(id);
    }
}

Mendaftarkan Rantaian

Daftarkan setiap perkhidmatan dalam rantaian. Bekas menyelesaikan keseluruhan graf kebergantungan secara automatik — ProductService → IProductRepository → AppDbContext.

builder.Services.AddDbContext<AppDbContext>(opt =>
    opt.UseSqlite("Data Source=app.db"));

builder.Services.AddScoped<IProductRepository, SqlProductRepository>();
builder.Services.AddScoped<ProductService>();

Menguji dengan Objek Palsu

Oleh sebab kebergantungan disuntik melalui antara muka, ujian unit boleh menghantar objek palsu tanpa menyentuh pangkalan data. Ini ialah salah satu manfaat terbesar DI.

// Using NSubstitute or Moq in a unit test
var mockRepo = Substitute.For<IProductRepository>();
mockRepo.GetByIdAsync(1).Returns(new Product { Id = 1, Name = "Widget" });

var logger = Substitute.For<ILogger<ProductService>>();
var svc = new ProductService(mockRepo, logger);

var result = await svc.GetProductAsync(1);
Assert.Equal("Widget", result?.Name);

Berbilang Parameter Pembina

Sesuatu kelas boleh mempunyai banyak parameter pembina. Bekas akan menyelesaikan kesemuanya selagi setiap satu didaftarkan. Pastikan pembina tertumpu — terlalu banyak parameter ialah petanda bahawa kelas itu mempunyai terlalu banyak tanggungjawab.

public class OrderService
{
    public OrderService(
        IOrderRepository orders,
        IProductRepository products,
        IEmailSender email,
        ILogger<OrderService> logger)
    {
        // all injected by DI container
    }
}

Mengelakkan Corak Anti-Pencari Perkhidmatan

Jangan NOT suntik IServiceProvider dan panggil GetService di dalam kaedah logik perniagaan. Ini menyembunyikan kebergantungan dan menyukarkan ujian. Utamakan suntikan melalui pembina untuk kod yang jelas dan mudah diuji.

// BAD
public void Process(IServiceProvider sp)
{
    var repo = sp.GetService<IProductRepository>(); // hidden dep!
}

// GOOD
public class Processor
{
    private readonly IProductRepository _repo;
    public Processor(IProductRepository repo) => _repo = repo;
}

Sintaks Pembina primary (C# 12)

C# 12 memperkenalkan pembina primary untuk semua jenis kelas, yang membolehkan anda mengisytiharkan parameter terus pada pengisytiharan kelas bagi menghasilkan kod DI yang ringkas.

// C# 12 primary constructor
public class ProductService(
    IProductRepository repo,
    ILogger<ProductService> logger)
{
    public async Task<Product?> GetAsync(int id)
    {
        logger.LogInformation("Getting {Id}", id);
        return await repo.GetByIdAsync(id);
    }
}

Menukar Pelaksanaan

Satu kelebihan utama DI berasaskan antara muka ialah anda boleh menukar pelaksanaan dalam satu baris tanpa mengubah sebarang kod penggunaannya. Ini berguna untuk menukar pangkalan data, penyedia e-mel atau bendera ciri.

// Switch from SQL to in-memory for integration tests
if (environment.IsEnvironment("Test"))
    builder.Services.AddScoped<IProductRepository, InMemoryProductRepository>();
else
    builder.Services.AddScoped<IProductRepository, SqlProductRepository>();

Dunia Sebenar: Pengawal dengan DI

Pengawal ASP.NET Core menggunakan suntikan melalui pembina secara semula jadi. Rangka kerja menyelesaikan semua parameter dan menghantarnya.

[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    private readonly ProductService _svc;

    public ProductsController(ProductService svc) => _svc = svc;

    [HttpGet("{id}")]
    public async Task<IActionResult> Get(int id)
    {
        var product = await _svc.GetProductAsync(id);
        return product is null ? NotFound() : Ok(product);
    }
}

Semakan Pantas

Apakah manfaat utama memprogram berdasarkan antara muka apabila menggunakan DI?

Imbas Kembali: Suntikan melalui Pembina & Antara Muka

Perkara penting:

  • Isytiharkan kebergantungan sebagai parameter pembina — bekas menyediakannya
  • Takrifkan antara muka untuk kontrak perkhidmatan; suntik antara muka, bukan jenis konkrit
  • Antara muka membolehkan olokan mudah dalam ujian unit dan penukaran pelaksanaan
  • Pembina primary C# 12 mengurangkan kod berulang untuk kelas yang banyak menggunakan DI
  • Elakkan corak anti-pencari perkhidmatan — pastikan kebergantungan jelas
Percuma untuk bermula

Pelajari C# dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
93
Pelajaran
346

Soalan Lazim

Adakah pelajaran “Suntikan Konstruktor & Antara Muka” percuma?

Ya — teks penuh “Suntikan Konstruktor & Antara Muka” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Akademi C#, tingkat taraf kepada CoddyKit PRO. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Suntikan Konstruktor & Antara Muka”?

Gunakan suntikan konstruktor dengan reka bentuk berasaskan antara muka untuk menyahgandingkan komponen dan membolehkan ujian unit. Anda berlatih Akademi C# menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Akademi C#?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Akademi C# di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Suntikan Konstruktor & Antara Muka” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Akademi C# ini?

Ya. Setiap pelajaran Akademi C# menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Asas Bekas DI
  2. Jangka Hayat Perkhidmatan: Transient, Scoped, Singleton
  3. Suntikan Konstruktor & Antara Muka
  4. Corak Kilang & Pilihan
← Kembali ke Akademi C#