Entitas gaya DDD dengan Entity Framework Core

Artikel ini adalah tentang bagaimana menerapkan prinsip-prinsip Domain-Driven Design (DDD) untuk kelas yang dipetakan oleh Entity Framework Core (EF Core) ke database, dan mengapa ini mungkin berguna.

TLDR


Ada banyak keuntungan dari pendekatan DDD, tetapi yang utama adalah bahwa DDD mentransfer kode buat / modifikasi operasi di dalam kelas entitas. Ini secara signifikan mengurangi kemungkinan pengembang salah paham / menafsirkan aturan untuk membuat, menginisialisasi, dan menggunakan instance kelas.

  1. Buku Eric Evans dan pidatonya tidak memiliki banyak informasi mengenai hal ini:
  2. Memberikan pelanggan dengan model sederhana untuk mendapatkan objek (kelas) persisten dan mengelola siklus hidup mereka.
  3. Kelas entitas Anda harus secara eksplisit menyatakan apakah mereka dapat diubah, bagaimana, dan dengan aturan apa.
  4. Dalam DDD ada konsep agregat. Agregat adalah pohon entitas terkait. Menurut aturan DDD, pekerjaan dengan agregat harus dilakukan melalui "akar agregasi" (esensi akar pohon).

Eric menyebutkan repositori dalam pidatonya. Saya tidak merekomendasikan menerapkan repositori dengan EF Core, karena EF sudah mengimplementasikan repositori dan unit pola kerja per se. Saya akan bercerita lebih banyak tentang ini di artikel terpisah, “ Apakah layak menggunakan repositori dengan EF Core ?”

Entitas gaya DDD


Saya akan mulai dengan menunjukkan kode entitas dalam gaya DDD dan kemudian membandingkannya dengan bagaimana entitas dengan EF Core biasanya dibuat toko buku (versi Amazon yang sangat disederhanakan. ”Struktur basis data ditunjukkan pada gambar di bawah ini.

gambar

Empat tabel pertama mewakili segala sesuatu tentang buku: buku itu sendiri, penulisnya, ulasan. Dua tabel di bawah ini digunakan dalam kode logika bisnis. Topik ini dijelaskan secara rinci dalam artikel terpisah.
Semua kode untuk artikel ini telah diunggah ke gudang GenericBizRunner di GitHub . Selain kode perpustakaan GenericBizRunner, ada contoh lain dari aplikasi Core ASP.NET yang menggunakan GenericBizRunner untuk bekerja dengan logika bisnis. Lebih lanjut tentang ini ditulis dalam artikel " Perpustakaan untuk bekerja dengan logika bisnis dan Entity Framework Core ."
Dan di sini adalah kode entitas yang sesuai dengan struktur basis data.

public class Book { public const int PromotionalTextLength = 200; public int BookId { get; private set; } //… all other properties have a private set //These are the DDD aggregate propties: Reviews and AuthorLinks public IEnumerable<Review> Reviews => _reviews?.ToList(); public IEnumerable<BookAuthor> AuthorsLink => _authorsLink?.ToList(); //private, parameterless constructor used by EF Core private Book() { } //public constructor available to developer to create a new book public Book(string title, string description, DateTime publishedOn, string publisher, decimal price, string imageUrl, ICollection<Author> authors) { //code left out } //now the methods to update the book's properties public void UpdatePublishedOn(DateTime newDate)… public IGenericErrorHandler AddPromotion(decimal newPrice, string promotionalText)… public void RemovePromotion()… //now the methods to update the book's aggregates public void AddReview(int numStars, string comment, string voterName, DbContext context)… public void RemoveReview(Review review)… } 

Apa yang harus dicari:

  1. Baris 5: mengatur akses ke semua properti entitas yang dinyatakan pribadi. Ini berarti bahwa data dapat dimodifikasi baik menggunakan konstruktor, atau menggunakan metode publik yang dijelaskan nanti dalam artikel ini.
  2. Baris 9 dan 10. Koleksi terkait (agregat yang sama dari DDD) menyediakan akses publik ke IEnumerable <T>, bukan ICollection <T>. Ini berarti Anda tidak dapat menambah atau menghapus item dari koleksi secara langsung. Anda harus menggunakan metode khusus dari kelas Buku.
  3. Jalur 13. EF Core membutuhkan konstruktor tanpa parameter, tetapi dapat memiliki akses pribadi. Ini berarti bahwa kode aplikasi lain tidak akan dapat memotong inisialisasi dan membuat instance kelas menggunakan konstruktor tanpa parameter (komentar seorang penerjemah. Kecuali tentu saja Anda membuat entitas menggunakan refleksi saja)
  4. Baris 16-20: Satu-satunya cara Anda dapat membuat instance kelas Buku adalah dengan menggunakan konstruktor publik. Konstruktor ini berisi semua informasi yang diperlukan untuk menginisialisasi objek. Dengan demikian, objek dijamin dalam keadaan valid.
  5. Baris 23-25: Baris ini berisi metode untuk mengubah keadaan buku.
  6. Baris 28-29: Metode ini memungkinkan Anda mengubah entitas terkait (agregat)

Metode pada baris 23-39, saya akan terus memanggil "metode yang menyediakan akses." Metode-metode ini adalah satu-satunya cara untuk mengubah properti dan hubungan dalam suatu entitas. Intinya adalah bahwa kelas Buku "ditutup." Ini dibuat melalui konstruktor khusus dan hanya dapat dimodifikasi sebagian melalui metode khusus dengan nama yang sesuai. Pendekatan ini menciptakan kontras yang tajam dengan pendekatan standar untuk membuat / memodifikasi entitas di EF Core, di mana semua entitas mengandung konstruktor default kosong dan semua properti dinyatakan publik. Pertanyaan selanjutnya adalah, mengapa pendekatan pertama lebih baik?

Perbandingan Pembuatan Entitas


Mari kita bandingkan kode untuk memperoleh data pada beberapa buku dari json dan membuat instance kelas-kelas Buku berdasarkan basisnya.

a. Pendekatan standar


 var price = (decimal) (bookInfoJson.saleInfoListPriceAmount ?? DefaultBookPrice) var book = new Book { Title = bookInfoJson.title, Description = bookInfoJson.description, PublishedOn = DecodePubishDate(bookInfoJson.publishedDate), Publisher = bookInfoJson.publisher, OrgPrice = price, ActualPrice = price, ImageUrl = bookInfoJson.imageLinksThumbnail }; byte i = 0; book.AuthorsLink = new List<BookAuthor>(); foreach (var author in bookInfoJson.authors) { book.AuthorsLink.Add(new BookAuthor { Book = book, Author = authorDict[author], Order = i++ }); } 

b. Gaya DDD


 var authors = bookInfoJson.authors.Select(x => authorDict[x]).ToList(); var book = new Book(bookInfoJson.title, bookInfoJson.description, DecodePubishDate(bookInfoJson.publishedDate), bookInfoJson.publisher, ((decimal?)bookInfoJson.saleInfoListPriceAmount) ?? DefaultBookPrice, bookInfoJson.imageLinksThumbnail, authors); 

Kode konstruktor kelas buku

 public Book(string title, string description, DateTime publishedOn, string publisher, decimal price, string imageUrl, ICollection<Author> authors) { if (string.IsNullOrWhiteSpace(title)) throw new ArgumentNullException(nameof(title)); Title = title; Description = description; PublishedOn = publishedOn; Publisher = publisher; ActualPrice = price; OrgPrice = price; ImageUrl = imageUrl; _reviews = new HashSet<Review>(); if (authors == null || !authors.Any()) throw new ArgumentException( "You must have at least one Author for a book", nameof(authors)); byte order = 0; _authorsLink = new HashSet<BookAuthor>( authors.Select(a => new BookAuthor(this, a, order++))); } 

Apa yang harus dicari:

  1. Baris 1-2: konstruktor memaksa Anda untuk melewatkan semua data yang diperlukan untuk inisialisasi yang tepat.
  2. Baris 5, 6, dan 17-9: Kode ini berisi beberapa pemeriksaan untuk aturan bisnis. Dalam kasus khusus ini, pelanggaran aturan dianggap sebagai kesalahan dalam kode, oleh karena itu, dalam kasus pelanggaran, pengecualian akan dilemparkan. Jika pengguna dapat memperbaiki kesalahan ini, mungkin saya akan menggunakan pabrik statis yang mengembalikan Status <T> (penerjemah komentar. Saya akan menggunakan Opsi <T> atau Hasil <T>, sebagai nama yang lebih umum). Status adalah jenis yang mengembalikan daftar kesalahan.
  3. Baris 21-23: Penjilidan BookAuthor dibuat di konstruktor. Konstruktor BookAuthor dapat dideklarasikan dengan tingkat akses internal. Dengan cara ini kita bisa mencegah terciptanya hubungan di luar DAL.

Seperti yang mungkin Anda perhatikan, jumlah kode untuk membuat entitas kurang lebih sama dalam kedua kasus. Jadi mengapa gaya DDD lebih baik? Gaya DDD lebih baik karena:

  1. Mengontrol akses. Perubahan properti yang tidak disengaja dikecualikan. Setiap perubahan terjadi melalui konstruktor atau metode publik dengan nama yang sesuai. Jelas apa yang terjadi.
  2. Sesuai dengan KERING (jangan ulangi diri Anda sendiri). Anda mungkin perlu membuat instance Buku di beberapa tempat. Kode tugas ada di konstruktor dan Anda tidak perlu mengulanginya di beberapa tempat.
  3. Menyembunyikan kompleksitas. Kelas Buku memiliki dua properti: ActualPrice dan OrgPrice. Kedua nilai ini harus sama ketika membuat buku baru. Dalam pendekatan standar, setiap pengembang harus mengetahui hal ini. Dalam pendekatan DDD, cukup bagi pengembang kelas Buku untuk mengetahuinya. Selebihnya akan belajar tentang aturan ini karena secara eksplisit ditulis dalam konstruktor.
  4. Menyembunyikan pembuatan agregat. Dalam pendekatan standar, pengembang harus secara manual membuat instance dari BookAuthor. Dalam gaya DDD, kompleksitas ini dienkapsulasi untuk kode panggilan.
  5. Mengizinkan properti memiliki akses tulis pribadi
  6. Salah satu alasan untuk menggunakan DDD adalah untuk mengunci entitas, mis. Jangan berikan kemampuan untuk mengubah properti secara langsung. Mari kita bandingkan operasi perubahan dengan dan tanpa DDD.

Perbandingan Perubahan Properti


Eric Evans menyebut salah satu keunggulan utama entitas gaya DDD sebagai berikut: "Mereka mengkomunikasikan keputusan desain tentang akses objek".
Catatan penerjemah. Ungkapan aslinya sulit diterjemahkan ke dalam bahasa Rusia. Dalam hal ini, keputusan desain adalah keputusan yang dibuat tentang bagaimana perangkat lunak harus bekerja. Ini berarti bahwa keputusan telah didiskusikan dan dikonfirmasi. Kode dengan konstruktor yang menginisialisasi entitas dan metode dengan nama yang benar yang mencerminkan makna operasi secara eksplisit memberi tahu pengembang bahwa penugasan nilai-nilai tertentu dibuat dengan maksud, dan bukan karena kesalahan, dan bukan keinginan pengembang lain atau detail implementasi.
Saya mengerti frasa ini sebagai berikut.

  1. Jelaskan bagaimana cara memodifikasi data dalam suatu entitas dan data apa yang harus diubah bersama.
  2. Jelaskan saat Anda tidak boleh memodifikasi data tertentu dalam entitas.
Mari kita bandingkan dua pendekatan. Contoh pertama sederhana, dan yang kedua lebih rumit.

1. Perubahan tanggal publikasi


Misalkan kita ingin bekerja dulu dengan konsep buku dan baru kemudian menerbitkannya. Pada saat penulisan draft, perkiraan tanggal publikasi diatur, yang sangat mungkin akan berubah selama proses pengeditan. Untuk menyimpan tanggal publikasi, kami akan menggunakan properti PublishedOn.

a. Entitas dengan Properti Publik


 var book = context.Find<Book>(dto.BookId); book.PublishedOn = dto.PublishedOn; context.SaveChanges(); 

b. Entitas gaya DDD


Dalam gaya DDD, setter properti dinyatakan pribadi, jadi kami akan menggunakan metode akses khusus.

 var book = context.Find<Book>(dto.BookId); book.UpdatePublishedOn( dto.PublishedOn); context.SaveChanges(); 

Dua kasus ini hampir sama. Versi DDD bahkan sedikit lebih lama. Namun masih ada perbedaan. Dalam gaya DDD, Anda tahu pasti bahwa tanggal publikasi dapat diubah karena ada metode dengan nama yang jelas. Anda juga tahu bahwa Anda tidak dapat mengubah penerbit karena properti Publisher tidak memiliki metode yang tepat untuk berubah. Informasi ini akan berguna bagi setiap programmer yang bekerja dengan kelas buku.

2. Kelola diskon untuk buku


Syarat lain adalah kita harus bisa mengelola diskon. Diskon terdiri dari harga baru dan komentar, misalnya, "50% sebelum akhir minggu ini!"

Implementasi aturan ini sederhana, tetapi tidak terlalu jelas.

  1. Properti OrgPrice adalah harga tanpa diskon.
  2. ActualPrice - Harga saat buku dijual. Jika diskon tersebut valid, maka harga saat ini akan berbeda dari OrgHarga dengan ukuran diskon. Jika tidak, maka nilai properti akan sama.
  3. Properti PromotionText harus mengandung teks diskon jika diskon diterapkan atau nol jika diskon saat ini tidak diterapkan.

Aturannya cukup jelas bagi orang yang menerapkannya. Namun, untuk pengembang lain, katakanlah, kembangkan UI untuk menambahkan diskon. Menambahkan metode AddPromotion dan RemovePromotion ke kelas entitas menyembunyikan detail implementasi. Sekarang pengembang lain memiliki metode publik dengan nama yang sesuai. Semantik penggunaan metode jelas.

Lihatlah penerapan metode AddPromotion dan RemovePromotion.

 public IGenericErrorHandler AddPromotion(decimal newPrice, string promotionalText) { var status = new GenericErrorHandler(); if (string.IsNullOrWhiteSpace(promotionalText)) { status.AddError( "You must provide some text to go with the promotion.", nameof(PromotionalText)); return status; } ActualPrice = newPrice; PromotionalText = promotionalText; return status; } 

Apa yang harus dicari:

  1. Baris 4-10: menambahkan komentar PromotionalText diperlukan. Metode memeriksa apakah teks tidak kosong. Karena Pengguna dapat memperbaiki kesalahan ini. Metode ini mengembalikan daftar kesalahan untuk diperbaiki.
  2. Baris 12, 13: metode ini menetapkan nilai properti sesuai dengan implementasi yang telah dipilih pengembang. Pengguna metode AddPromotion tidak harus mengetahuinya. Untuk menambahkan diskon, cukup tulis:

 var book = context.Find<Book>(dto.BookId); var status = book.AddPromotion(newPrice, promotionText); if (!status.HasErrors) context.SaveChanges(); return status; 

Metode RemovePromotion jauh lebih sederhana: itu tidak melibatkan penanganan kesalahan. Oleh karena itu, nilai pengembaliannya batal.

 public void RemovePromotion() { ActualPrice = OrgPrice; PromotionalText = null; } 

Dua contoh ini sangat berbeda satu sama lain. Pada contoh pertama, mengubah properti PublishOn sangat sederhana sehingga implementasi standar baik-baik saja. Dalam contoh kedua, detail implementasi tidak jelas bagi seseorang yang belum bekerja dengan kelas Buku. Dalam kasus kedua, gaya DDD dengan metode akses khusus menyembunyikan detail implementasi dan membuat kehidupan pengembang lain lebih mudah. Juga, dalam contoh kedua, kode tersebut berisi logika bisnis. Meskipun jumlah logikanya kecil, kami dapat menyimpannya secara langsung dalam metode akses dan mengembalikan daftar kesalahan jika metode tersebut tidak digunakan dengan benar.

3. Bekerja dengan Ulasan agregat - koleksi properti


DDD menawarkan untuk bekerja dengan unit hanya melalui root. Dalam kasus kami, properti Ulasan menimbulkan masalah. Bahkan jika setter dinyatakan pribadi, pengembang masih dapat menambah atau menghapus objek menggunakan metode add and remove, atau bahkan memanggil metode hapus untuk menghapus seluruh koleksi. Di sini, fitur EF Core baru, bidang dukungan, akan membantu kami.

Bidang dukungan memungkinkan pengembang untuk merangkum koleksi nyata dan menyediakan akses publik ke tautan antarmuka <n> IEnumerable. Antarmuka IEnumerable <T> tidak menyediakan metode tambah, hapus, atau hapus. Dalam kode di bawah ini adalah contoh menggunakan bidang dukungan.

 public class Book { private HashSet<Review> _reviews; public IEnumerable<Review> Reviews => _reviews?.ToList(); //… rest of code not shown } 

Agar ini berfungsi, Anda harus memberi tahu EF Core bahwa ketika membaca dari database, Anda harus menulis ke bidang pribadi, bukan milik umum. Kode konfigurasi ditunjukkan di bawah ini.

 protected override void OnModelCreating (ModelBuilder modelBuilder) { modelBuilder.Entity<Book>() .FindNavigation(nameof(Book.Reviews)) .SetPropertyAccessMode(PropertyAccessMode.Field); //… other non-review configurations left out } 

Untuk bekerja dengan ulasan, saya menambahkan dua metode: AddReview dan RemoveReview ke kelas buku. Metode AddReview lebih menarik. Ini kodenya:

 public void AddReview(int numStars, string comment, string voterName, DbContext context = null) { if (_reviews != null) { _reviews.Add(new Review(numStars, comment, voterName)); } else if (context == null) { throw new ArgumentNullException(nameof(context), "You must provide a context if the Reviews collection isn't valid."); } else if (context.Entry(this).IsKeySet) { context.Add(new Review(numStars, comment, voterName, BookId)); } else { throw new InvalidOperationException("Could not add a new review."); } } 

Apa yang harus dicari:

  1. Baris 4-7: Saya sengaja tidak menginisialisasi bidang ¢ dalam konstruktor tanpa parameter pribadi yang digunakan EF Core saat memuat entitas dari basis data. Ini memungkinkan kode saya untuk menentukan apakah koleksi dimuat menggunakan metode .Include (p => p.Reviews). Di konstruktor publik, saya menginisialisasi bidang, sehingga NRE tidak akan terjadi ketika bekerja dengan entitas yang dibuat.
  2. Baris 8-12: Jika koleksi Ulasan tidak dimuat, kode harus menggunakan DbContext untuk menginisialisasi.
  3. Baris 13-16: Jika buku itu berhasil dibuat dan berisi ID, maka saya menggunakan teknik lain untuk menambahkan ulasan: Saya cukup menginstal kunci asing dalam instance dari kelas Review dan menulisnya ke database. Ini dijelaskan secara lebih rinci di bagian 3.4.5 dari buku saya.
  4. Baris 19: Jika kita di sini, maka ada semacam masalah dengan logika kodenya. Jadi saya melemparkan pengecualian.

Saya telah merancang semua metode akses saya untuk kasus terbalik di mana hanya entitas root dimuat. Cara memperbarui unit ini berdasarkan kebijaksanaan metode. Anda mungkin perlu memuat entitas tambahan.

Kesimpulan


Untuk membuat entitas dalam gaya DDD dengan EF Core, Anda harus mematuhi aturan berikut:

  1. Buat konstruktor publik untuk membuat instance kelas yang diinisialisasi dengan benar. Jika kesalahan dapat terjadi selama proses pembuatan yang dapat dikoreksi oleh pengguna, buat objek tidak menggunakan konstruktor publik, tetapi menggunakan metode pabrik yang mengembalikan Status <T>, di mana T adalah tipe entitas yang sedang dibuat
  2. Semua properti adalah properti setter. Yaitu semua properti hanya-baca di luar kelas.
  3. Untuk properti navigasi koleksi, deklarasikan bidang dukungan, dan jenis properti publik menyatakan IEnumerable <T>. Ini akan mencegah pengembang lain mengubah koleksi tidak terkendali.
  4. Alih-alih setter publik, buat metode publik untuk semua operasi perubahan objek yang diizinkan. Metode-metode ini harus kembali batal jika operasi tidak dapat gagal dengan kesalahan yang dapat diperbaiki pengguna atau Status <T> jika mereka bisa.
  5. Ruang lingkup masalah kewajiban entitas. Saya pikir yang terbaik adalah membatasi entitas untuk mengubah kelas itu sendiri dan kelas lain di dalam agregat, tetapi tidak di luar. Aturan validasi harus dibatasi untuk memeriksa kebenaran penciptaan dan perubahan status entitas. Yaitu Saya tidak memeriksa aturan bisnis seperti saldo stok. Ada kode logika bisnis khusus untuk ini.
  6. Metode perubahan negara harus mengasumsikan bahwa hanya akar agregasi yang dimuat. Jika suatu metode perlu memuat data lain, ia harus mengurusnya sendiri.
  7. Metode perubahan negara harus mengasumsikan bahwa hanya akar agregasi yang dimuat. Jika suatu metode perlu memuat data lain, ia harus mengurusnya sendiri. Pendekatan ini menyederhanakan penggunaan entitas oleh pengembang lain.

Pro dan kontra entitas DDD saat bekerja dengan EF Core


Saya suka pendekatan kritis terhadap pola atau arsitektur apa pun. Inilah yang saya pikirkan tentang menggunakan entitas DDD.

Pro


  1. Menggunakan metode khusus untuk mengubah keadaan adalah pendekatan yang lebih bersih. Ini jelas merupakan solusi yang baik, hanya karena metode yang disebutkan dengan benar mengungkapkan niat kode jauh lebih baik dan memperjelas apa yang bisa dan tidak bisa diubah. Selain itu, metode dapat mengembalikan daftar kesalahan jika pengguna dapat memperbaikinya.
  2. Mengubah agregat hanya melalui root juga berfungsi dengan baik
  3. Detail hubungan satu-ke-banyak antara kelas Buku dan Tinjauan sekarang disembunyikan bagi pengguna. Enkapsulasi adalah prinsip dasar OOP.
  4. Menggunakan konstruktor khusus memungkinkan Anda memastikan bahwa entitas dibuat dan dijamin diinisialisasi dengan benar.
  5. Memindahkan kode inisialisasi ke konstruktor secara signifikan mengurangi kemungkinan bahwa pengembang tidak menafsirkan dengan benar bagaimana kelas harus diinisialisasi.

Cons


  1. Pendekatan saya berisi dependensi pada implementasi EF Core.
  2. Beberapa orang bahkan menyebutnya anti-pola. Masalahnya adalah bahwa sekarang entitas model subjek bergantung pada kode akses database. Dalam hal DDD, ini buruk. Saya menyadari bahwa jika saya tidak melakukan ini, saya harus mengandalkan penelepon untuk mengetahui apa yang harus dimuat. Pendekatan ini mematahkan prinsip pemisahan keprihatinan.
  3. DDD memaksa Anda untuk menulis lebih banyak kode.

Apakah benar-benar layak untuk kasus sederhana, seperti memperbarui tanggal penerbitan buku?
Seperti yang Anda lihat, saya suka pendekatan DDD. Namun, saya perlu waktu untuk menyusunnya dengan benar, tetapi saat ini pendekatannya telah diselesaikan dan saya menerapkannya dalam proyek yang sedang saya kerjakan. Saya sudah berhasil mencoba gaya ini dalam proyek-proyek kecil dan saya puas, tetapi semua pro dan kontra belum ditemukan ketika saya menggunakannya dalam proyek-proyek besar.

Keputusan saya untuk mengizinkan penggunaan kode spesifik EFCore dalam argumen metode entitas model entitas tidaklah sederhana. Saya mencoba untuk mencegah hal ini, tetapi pada akhirnya saya sampai pada kesimpulan bahwa kode panggilan harus memuat banyak properti navigasi. Dan jika ini tidak dilakukan, maka perubahan itu tidak akan diterapkan tanpa kesalahan (terutama dalam hubungan satu-ke-satu). Ini tidak dapat saya terima, jadi saya mengizinkan penggunaan EF Core di dalam beberapa metode (tetapi bukan konstruktor).

Sisi buruk lainnya adalah bahwa DDD memaksa Anda untuk menulis lebih banyak kode secara signifikan untuk operasi CRUD. Saya masih tidak yakin apakah akan terus makan kaktus dan menulis metode terpisah untuk semua properti, atau dalam beberapa kasus layak untuk menjauh dari Puritanisme radikal. Saya tahu bahwa hanya ada kereta dan truk kecil CRUD yang membosankan, yang lebih mudah untuk ditulis secara langsung. Hanya bekerja pada proyek nyata akan menunjukkan mana yang lebih baik.

Aspek DDD lainnya yang tidak dibahas dalam artikel ini


Artikelnya ternyata terlalu panjang, jadi saya akan berakhir di sini. Tapi, ini berarti masih banyak material yang dirahasiakan. Saya sudah menulis tentang sesuatu, tentang sesuatu yang akan saya tulis dalam waktu dekat. Inilah yang tersisa ke laut:

  1. Logika bisnis dan DDD. Saya telah menggunakan konsep DDD dalam kode logika bisnis selama beberapa tahun dan, menggunakan fitur-fitur baru EF Core, saya berharap bahwa saya dapat mentransfer beberapa logika ke kode entitas. Baca artikel "Lagi tentang Arsitektur Lapisan Logika Bisnis dengan Kerangka Entitas (Core dan v6)"
  2. DDD dan pola repositori. Eric Evans merekomendasikan menggunakan repositori untuk abstrak akses data. , «» EF Core – . Mengapa - .
  3. DBContext' / (bounded contexts). DbContext'. , BookContext Book OrderContext, . , « » , . , .

Semua kode untuk artikel ini tersedia di repositori GenericBizRunner di GitHub . Repositori ini berisi contoh aplikasi Core ASP.NET dengan metode akses khusus untuk memodifikasi kelas Buku. Anda dapat mengkloning repositori dan menjalankan aplikasi secara lokal. Ia menggunakan Sqlite dalam memori sebagai basis data, sehingga harus dijalankan pada infrastruktur apa pun.

Perkembangan senang!

Source: https://habr.com/ru/post/id432410/


All Articles