Dasar-Dasar Dependency Injection
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C# di Coddy. Pelajaran 46 dari 70.
Dependency Injection (DI) adalah teknik saat sebuah class menerima dependensinya dari luar, bukan membuatnya sendiri. Dengan begitu, kodemu menjadi lebih fleksibel, mudah diuji, dan memiliki keterkaitan yang lebih longgar.
Tanpa DI, sebuah class membuat dependensinya sendiri, sehingga sulit diubah atau diuji:
public class OrderService
{
private EmailSender sender = new EmailSender(); // Saling bergantung erat
public void PlaceOrder() => sender.Send("Order placed");
}Dengan DI, dependency diteruskan melalui constructor:
public interface IMessageSender
{
void Send(string message);
}
public class EmailSender : IMessageSender
{
public void Send(string message) => Console.WriteLine("Email: " + message);
}
public class OrderService
{
private IMessageSender sender;
public OrderService(IMessageSender sender)
{
this.sender = sender;
}
public void PlaceOrder() => sender.Send("Order placed");
}Sekarang OrderService tidak tahu atau peduli apakah ia menggunakan email, SMS, atau pengirim mock untuk pengujian. Dependensi tersebut "diinjeksi" saat object dibuat:
IMessageSender emailSender = new EmailSender();
OrderService service = new OrderService(emailSender);
service.PlaceOrder(); // Email: Pesanan dibuatPola ini mengikuti prinsip bergantung pada abstraksi (interface), bukan implementasi konkret. Pola ini memungkinkan penggantian implementasi tanpa mengubah class yang menggunakannya, yang penting untuk pengujian unit dan mempertahankan arsitektur yang fleksibel.
Tantangan
MudahMari kita bangun sistem pencatatan log yang menunjukkan keunggulan dependency injection. Alih-alih menetapkan secara langsung cara penulisan log, kamu akan membuat class Logger yang fleksibel dan dapat bekerja dengan tujuan pencatatan apa pun, konsol, simulasi file, atau lainnya, tanpa mengetahui detailnya.
Kamu akan mengatur kodemu dalam tiga file:
ILogWriter.cs: Definisikan interface bernamaILogWriterdi namespaceLogging. Interface ini mewakili kontrak untuk tujuan pencatatan log apa pun dan harus memiliki satu methodWrite(string message)yang mengembalikan string yang menjelaskan ke mana pesan ditulis.LogWriters.cs: Buat dua implementasi konkret dariILogWriterdi namespaceLogging:ConsoleLogWriter, methodWrite-nya mengembalikanConsole: {message}FileLogWriter, menerima nama file melalui constructornya dan methodWrite-nya mengembalikanFile[{filename}]: {message}
Logger.cs: Buat classLoggerdi namespaceLoggingyang menerima dependensinya melalui constructor injection.Loggerharus:- Menerima
ILogWritermelalui constructornya dan menyimpannya dalam field privat - Memiliki method
Log(string message)yang meneruskan pemanggilan ke writer yang di-inject dan mengembalikan hasilnya
- Menerima
Program.cs: Tunjukkan dependency injection dengan membuat dua logger yang berbeda, satu denganConsoleLogWriterdan satu denganFileLogWriter. Tunjukkan bagaimana classLoggeryang sama berperilaku berbeda, bergantung pada dependensi yang di-inject.
Kamu akan menerima dua input:
- Nama file untuk logger file
- Pesan yang akan dicatat
Buat Logger dengan ConsoleLogWriter lalu catat pesannya. Kemudian buat Logger lain dengan FileLogWriter (menggunakan nama file dari input) lalu catat pesan yang sama. Cetak setiap hasil pada barisnya sendiri.
Contohnya, jika inputnya adalah app.log dan System started, outputnya akan seperti ini:
Console: System started
File[app.log]: System startedPerhatikan bahwa class Logger tidak pernah berubah, class ini bekerja dengan implementasi ILogWriter apa pun. Inilah inti dependency injection: Logger bergantung pada abstraksi (interface), dan implementasi konkretnya "disuntikkan" dari luar. Kamu dapat dengan mudah menambahkan DatabaseLogWriter atau CloudLogWriter nanti tanpa mengubah class Logger sama sekali!
Coba sendiri
using System;
using Logging;
class Program
{
public static void Main(string[] args)
{
// Baca input
string filename = Console.ReadLine();
string message = Console.ReadLine();
// TODO: Buat Logger dengan ConsoleLogWriter dan catat pesan tersebut
// Cetak hasilnya
// TODO: Buat Logger lain dengan FileLogWriter (menggunakan filename) dan catat pesan yang sama
// Cetak hasilnya
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalNamespace & DirektifPengantar class & objectKata Kunci 'this'Method dan ParameterField vs PropertyKonstruktorInisialisasi objectRingkasan: Kalkulator Sederhana4Pewarisan
Sintaks Dasar Pewarisan (:)Kata Kunci 'base'Kata Kunci Virtual & OverrideClass SealedBase Class 'object'Rangkuman: Hierarki Karyawan7Fitur Lanjutan
Overloading OperatorIndexer (this[])Penimpaan ToString()Extension methodRingkasan: Custom list2Property & Anggota Statis
Property yang Diimplementasikan OtomatisProperty Hanya Baca dan Hanya TulisField dan method StatisClass StatisAnggota Berbentuk Ekspresi5Polimorfisme & Antarmuka
Polimorfisme saat kompilasi vs runtimeAntarmuka vs kelas abstrakBeberapa antarmukaAntarmuka eksplisitUpcasting & DowncastingRingkasan, Kalkulator Bentuk8Konsep OOP Lanjutan
Komposisi daripada PewarisanGenerics (class dan method)Delegate dan EventAtribut dan ReflectionIDisposable dan Pernyataan usingDasar-Dasar Dependency Injection11Pola Desain Bagian 2
Pola PerintahPola AdapterPola DecoratorPola Template MethodPola StatePola CompositeLatihan sendiri: Compiler C# online