Arsitektur / layering proyek .NET MVC


11

Ketika merencanakan arsitektur untuk aplikasi web MVC skala menengah-besar, bagaimana Anda mengimplementasikan layer agar dapat dipisahkan sebanyak mungkin dan mudah untuk diuji? (pada dasarnya ikuti praktik terbaik) Katakanlah saya menggunakan kode terlebih dahulu sebagai akses data saya.

Saya berjuang dengan apa yang mendefinisikan "logika bisnis" sebagai, dan bagaimana itu dimaksudkan untuk berinteraksi dengan lapisan data. Dengan mengambil aplikasi penjualan kendaraan sebagai contoh, akankah logika bisnis menjadi kelas yang melakukan tugas-tugas seperti menghitung pita pajak untuk kendaraan yang diberikan, membandingkan statistik statistik mile per galon dll? Adapun entitas bisnis (misalnya Mobil, Vans, Sepeda Motor) saya akan menempatkan ini di lapisan data bersama dengan DataContextkelas saya .

Juga apa yang merupakan logika aplikasi yang bertentangan dengan bisnis - Saya menduga hal-hal seperti validasi input sesi / pengguna?

Jadi misalnya, pengontrol mobil mungkin mengembalikan hasil tindakan / tampilan yang mencantumkan sepuluh mobil teratas yang difilter menurut jenis dan mpg terbaik. Jadi katakanlah saya memiliki ICarRepository'carRepo' yang disuntikkan ke controller saya (menggunakan pola repositori / DI), saya memfilter mobil saya dari parameter metode tindakan misalnyavar cars = carRepo.getCarsByType("hatchback");

Jadi saya telah menyimpan pengetahuan akses data dari controller saya menggunakan repositori, sekarang untuk menjaga logika bisnis dari controller menggunakan model domain - var result = new MpgCalculator (mobil); - Katakanlah saya memerlukan kelas kalkulator karena perlu melakukan logika tambahan untuk menghitung efisiensi bahan bakar terbaik, lebih dari sekedar memuat / menyaring entitas dari DB. Jadi sekarang saya memiliki set data untuk tampilan saya untuk membuat yang menggunakan repositori untuk mengambil dari lapisan akses data, dan objek khusus domain untuk memproses dan melakukan tugas-tugas terkait bisnis pada data itu.

Apakah saya membuat kesalahan di sini? apakah kita masih perlu menggunakan pola repositori atau bisakah saya hanya kode terhadap antarmuka untuk memisahkan ORM dan menguji? Pada topik ini, karena kelas akses data konkret saya (d) konteks di lapisan data, haruskah definisi antarmuka masuk ke domain / lapisan bisnis yang berarti bahwa jika teknologi akses data pernah diubah, lapisan saya yang lain tidak terpengaruh?

Dari apa yang telah saya pelajari sejauh ini struktur saya terlihat seperti ini:

Aplikasi Internet MVC -> Proyek internet standar - model di sini adalah ViewModels

Lapisan Domain / Bisnis -> kelas / model khusus bisnis yang dapat digunakan pengendali untuk memproses entitas domain dari lapisan data sebelum meneruskan ke tampilan yang relevan

Diperlukan abstraksi repositori? -> Saya mendengar banyak perdebatan tentang ini, terutama ketika menggunakan ORM

Lapisan data -> Kelas entitas (Mobil, Van, Sepeda Motor), DbContext - Lapisan teknologi akses data konkret

Jawaban:


26

Anda memiliki banyak bagian yang bergerak dalam pertanyaan Anda, menyentuh banyak konsep, tapi inilah saran dasar saya mengenai bagaimana memikirkan aplikasi MVC skala menengah hingga besar:

Presentasi <---> Logika Bisnis <---> Akses Data

Pertama, yang terbaik adalah tidak menganggap aplikasi sebagai "aplikasi MVC". Ini adalah aplikasi yang menggunakan pola MVC sebagai komponen presentasinya. Memikirkannya dengan cara ini akan membantu Anda memisahkan masalah logika bisnis Anda dari masalah presentasi Anda . Mungkin tidak apa-apa untuk aplikasi kecil untuk menumpuk semuanya ke akses basis data ke dalam struktur MVC, tetapi akan dengan cepat menjadi tidak bisa digunakan untuk aplikasi menengah ke besar.

MVC (Presentasi)

Di aplikasi Anda, komponen ASP.NET MVC harus berurusan dengan mentransformasikan data bisnis untuk tujuan tampilan (Model), menampilkan antarmuka pengguna (Tampilan), dan masalah komunikasi seperti perutean, otentikasi, otorisasi, validasi permintaan, penanganan respons, dan seperti (Pengendali). Jika Anda memiliki kode yang melakukan sesuatu yang lain, maka itu tidak termasuk dalam komponen MVC .

Repositori / ORM (Akses Data)

Juga di aplikasi Anda, lapisan akses data harus peduli dengan mengambil dan menyimpan data persisten. Biasanya itu dalam bentuk database relasional, tetapi ada banyak cara lain data dapat bertahan. Jika Anda memiliki kode yang tidak membaca atau menyimpan data persisten, maka itu tidak termasuk dalam lapisan data . Saya membagikan pemikiran saya pada diskusi ORM / Repository sebelumnya pada SO, tetapi untuk rekap, saya tidak menganggap ORM sebagai hal yang sama dengan Repositori, karena beberapa alasan.

Logika bisnis

Jadi sekarang Anda memiliki lapisan presentasi (MVC), dan lapisan data Anda (repositori atau ORM) ... Yang lainnya adalah lapisan logika bisnis (BLL) Anda. Semua kode Anda yang memutuskan data mana yang akan diambil, atau melakukan perhitungan rumit, atau membuat keputusan bisnis, harus ada di sini. Saya biasanya mengatur logika bisnis saya dalam bentuk 'layanan', yang dapat diminta oleh lapisan presentasi saya untuk melakukan pekerjaan yang diminta. Semua model domain saya ada di sini.

Pendekatan Anda

Di sinilah pendekatan Anda sedikit rusak bagi saya. Anda menggambarkan pengontrol MVC Anda sebagai tempat Anda akan mendapatkan data dari repositori, dan memanggil MPGCalculator untuk melakukan pekerjaan, dll. Saya tidak ingin pengontrol saya melakukan semua ini, tetapi sebaliknya akan mendelegasikan semua ini ke layanan di BLL.

Dengan kata lain, saya tidak akan menyuntikkan repositori dan MPGCalculator ke controller, yang memberi controller terlalu banyak tanggung jawab (itu sudah menangani semua hal-hal controller yang saya sebutkan di atas). Sebagai gantinya, saya akan memiliki layanan di BLL menangani semua itu, dan meneruskan hasilnya kembali ke controller. Pengontrol kemudian dapat mentransformasikan hasilnya ke model yang benar, dan meneruskannya ke tampilan yang benar. Controller tidak memiliki logika bisnis di dalamnya, dan satu-satunya hal yang disuntikkan ke controller adalah layanan BLL yang sesuai.

Melakukannya dengan cara ini berarti logika bisnis Anda (misalnya, diberikan seperangkat kendaraan, menghitung MPG dan menyortir yang terbaik hingga yang terburuk ) adalah independen dari masalah presentasi dan kegigihan. Biasanya akan berada di perpustakaan yang tidak tahu atau tidak peduli tentang strategi kegigihan data atau strategi presentasi.


Hai Eric, balasan yang sangat baik - mengenai repositori, saya berasumsi kelas konkret akan hidup di lapisan akses data dan 'ICarRepository' dll di lapisan bisnis / layanan? Lalu saya bisa menyuntikkan layanan ke controller saya yang mungkin berisi 1 atau lebih repositori tergantung pada persyaratan?
Michael Harper

@MichaelHarper Ya, itu terdengar seperti cara yang sangat baik untuk melakukannya.
Eric King

1
Sementara otentikasi adalah masalah pengontrol (UI yang berbeda mengautentikasi secara berbeda) Saya akan mengatakan otorisasi adalah logika bisnis dan termasuk dalam lapisan bisnis. Apa kamu setuju?
tom

1
@ Tom Ya, Anda punya poin bagus. Saya berpikir otorisasi sederhana seperti apakah pengguna memiliki akses ke rute ini , tetapi mungkin ada lebih dari itu. Bagian "lebih banyak untuk itu" termasuk dalam lapisan bisnis.
Eric King

1
@HunterNelson Jika Anda memetakan ke dalam viewmodel, maka pemetaan harus terjadi di mana tampilan berada, di lapisan presentasi. Itu tidak masuk akal di tempat lain.
Eric King

0

Sepertinya semuanya benar untuk struktur Anda. Satu-satunya hal yang saya tidak yakin tentang adalah bahwa Anda menyebutkan bahwa model dalam MVC adalah "ViewModels" dan bahwa pengendali Anda berbicara dengan lapisan domain. Saya pikir ini masuk akal jika pola default Anda adalah menggunakan pengontrol untuk mengakses lapisan domain dan kemudian menggunakan "ViewModels" Anda sebagai kompilasi informasi tampilan yang lebih spesifik dari beberapa entitas domain yang masuk akal untuk tampilan tertentu. Jika itu yang Anda lakukan, kemungkinan besar Anda baik-baik saja.

Ada aliran pemikiran bahwa Anda harus memiliki abstraksi lengkap dari lapisan domain Anda di aplikasi MVC Anda jika Anda akan memilikinya. Secara pribadi, pemikiran untuk melakukan itu dalam aplikasi perusahaan menyebabkan saya sakit mental yang parah.

Saya lebih suka menggunakan pola repositori untuk mengelola akses ke Layer Data karena meningkatkan testability dan fleksibilitas. Dua hal yang cenderung membuat perubahan paling drastis adalah UI dan database. Bayangkan jika beberapa informasi yang Anda tarik langsung dari database diubah sehingga harus diambil dari panggilan layanan daripada panggilan database, atau beberapa informasi dipindahkan ke database yang berbeda yang membutuhkan .edmx berbeda mengajukan. Pola repositori menyediakan abstraksi untuk mendukung ini.


Terima kasih atas balasannya William 😊 Saya akan mempertimbangkan objek / logika bisnis dan entitas domain saya sebagai 'model' yang digunakan pengontrol untuk memproses tindakan pengguna dan model tampilan sebagai model tertentu yang dapat berisi kelompok model dll.
Michael Harper
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.