asp.net mvc menempatkan pengontrol ke dalam proyek terpisah

107

Saya baru saja mempelajari asp.net MVC dan saya mencoba mencari cara untuk memindahkan pengontrol saya ke dalam proyek terpisah. Biasanya ketika saya telah mendesain aplikasi web asp.net sebelumnya, saya membuat satu proyek untuk model saya, satu lagi untuk logika saya, dan kemudian ada web.

Sekarang setelah saya belajar asp.net MVC, saya berharap untuk mengikuti pola yang sama dan menempatkan model dan pengontrol masing-masing ke dalam proyek mereka sendiri yang terpisah, dan biarkan tampilan / scripts / css di web. Bagian modelnya mudah, tetapi yang tidak saya mengerti adalah bagaimana membuat pengontrol saya dalam proyek terpisah dapat "ditemukan". Juga, saya ingin tahu apakah ini disarankan. Terima kasih!

Aaron Palmer
sumber

Jawaban:

92

Pertama-tama, merupakan ide bagus untuk menempatkan model Anda ke dalam proyek terpisah. Seperti yang Anda temukan, ini sepele.

Mengenai Pengontrol dan Tampilan, saya tidak melihat keuntungan yang jelas untuk memisahkannya untuk sebagian besar proyek dasar, meskipun Anda mungkin memiliki kebutuhan khusus untuk melakukannya dalam aplikasi tertentu.

Jika Anda memilih untuk melakukan ini, Anda harus memberi tahu framework cara menemukan pengontrol Anda. Cara dasar untuk melakukannya adalah dengan menyediakan ControllerFactory Anda sendiri. Anda dapat melihat kode sumber untuk DefaultControllerFactory untuk mendapatkan ide tentang cara melakukannya. Membuat subtipe kelas ini dan menimpa metode GetControllerType (string controllerName) mungkin cukup untuk menyelesaikan apa yang Anda minta.

Setelah Anda membuat ControllerFactory kustom Anda sendiri, Anda menambahkan baris berikut ke Application_Start di global.asax untuk memberi tahu framework di mana menemukannya:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

Pembaruan: Baca posting ini dan posting yang ditautkan untuk info lebih lanjut. Lihat juga komentar Phil Haack di postingan itu tentang:

ControllerBuilder.Current.DefaultNamespaces.Add(
    "ExternalAssembly.Controllers");

... yang bukan merupakan solusi lengkap, tetapi mungkin cukup baik untuk kasus sederhana.

Craig Stuntz
sumber
2
Terima kasih Craig! Inilah yang saya cari-cari. Apakah informasi ini ada di web? Saya telah mencari-cari di Google untuk itu dengan tidak banyak keberuntungan. StackOverflow muncul lagi!
Aaron Palmer
11
Saya setuju, pengontrol menangani masukan pengguna, memanipulasi model, lalu meneruskan data ke tampilan. Mereka biasanya sangat spesifik untuk suatu aplikasi. Logika apa pun yang tidak spesifik untuk aplikasi mungkin lebih baik di perpustakaan atau model. Tetapi pengontrol secara umum seharusnya ada di proyek web.
Haacked
2
Saya memiliki pengontrol kesalahan dan tampilan yang identik antara dua aplikasi. Masuk akal bagi saya untuk memilikinya dalam satu rakitan yang dapat digunakan kedua aplikasi.
Sailing Judo
3
Bukankah lebih mudah untuk menguji pengontrol dan menggunakan IoC saat pengontrol berada dalam proyek terpisah - itu akan menjadi alasan utama
Samuel G
1
@Chev, saya rasa tidak ada bedanya di sana. Testabilitas pengontrol Anda lebih berkaitan dengan cara Anda mengkodekannya , bukan di mana mereka tinggal.
Craig Stuntz
19

Meskipun masuk akal untuk membuat ControllerFactory Anda sendiri, saya merasa lebih nyaman untuk menentukan semua Pengontrol saya di setiap proyek, tetapi memperolehnya dari Pengontrol di proyek Bersama saya:

namespace MyProject1.Controllers
{
   public class MyController : MySharedProject.Controllers.MyController
   {
      // nothing much to do here...
   }
}

namespace MySharedProject.Controllers
{
   public abstract class MyController : System.Web.Mvc.Controller
   {
      // all (or most) of my controller logic here...
   }
}

Ini memiliki keuntungan tambahan yaitu Anda memiliki tempat untuk meletakkan logika Controller Anda yang berbeda dari proyek ke proyek. Selain itu, lebih mudah bagi pengembang lain untuk dengan cepat menemukan logika Pengontrol Anda karena Pengontrol ada di tempat standar.

Mengenai apakah ini disarankan, saya pikir memang demikian. Saya telah membuat beberapa logika Manajemen Akun umum yang ingin saya bagikan di antara proyek-proyek yang memiliki logika bisnis yang sangat berbeda. Jadi saya membagikan Akun dan Pengontrol Admin saya, tetapi Pengontrol lain dikhususkan untuk proyek masing-masing.

Orang ini
sumber
1
Ini bekerja dengan sangat baik, tetapi saya harus menghilangkan beberapa kode yang berlebihan untuk mencegah kesalahan perutean
Ken Mc
Hai, Bagaimana saya dapat mengelola perutean dalam jenis proyek ini? saya ingin menggunakan perutean atribut ...
محمد
Anda dapat menggunakan perutean atribut seperti yang biasa Anda lakukan.
ThisGuy
2
Tidak yakin mengapa ini tidak memiliki lebih banyak suara positif ... jauh lebih elegan daripada jawaban yang diterima, saya kira. Terima kasih!
jleach
Ini tidak berhasil untuk saya. Bisakah Anda tahu apakah ini .Net Core atau .Net Framework?
Homayoun Behzadian
4
  • Tambahkan Perpustakaan Kelas untuk proyek mvc Anda.
  • Di kelas tambahkan kode berikut (Untuk Kode Pengontrol u'r)

    namespace ContactController
    {
    public class ContactController : Controller
    {
        public ActionResult Call()
        {
            ViewBag.Title = "Inside MyFirst Controller.";
            return View();
        }
    }
    

    }

  • Pada folder tampilan proyek mvc tambahkan folder untuk Kontak dan buat file Call.cshtml. Lihat Folder

  • Tambahkan referensi proyek perpustakaan kelas ke dalam proyek MVC utama Anda.

Referensi

  • Terakhir untuk merujuk namespace pengontrol kontak ke Route Config.

RouteConfig

RandyMohan
sumber
3
Itu sedikit disayangkan bahwa Anda memiliki namespace dengan nama yang sama dengan pengontrol.
Mariusz Jamro
3

Masalah saya teratasi setelah saya memperbarui System.Web.Mvcreferensi NuGet sehingga MvcWebsite dan Class Library menggunakan System.Web.Mvcversi yang sama

Tidak perlu menambahkan ruang nama default

Homayoun Behzadian
sumber
Masalahnya adalah bahwa MvcWebsite tidak mengeluarkan pengecualian sementara perakitan mvc saat ini memiliki versi yang lebih rendah daripada perakitan mvc yang dirujuk perpustakaan kelas
Homayoun Behzadian
1

Bentuk pemisahan paling sederhana yang saya gunakan adalah mempertahankan Tampilan "sebagaimana adanya" dalam proyek MVC asli tetapi menghapus Pengontrol. Kemudian dalam proyek ClassLibrary baru tambahkan kelas Controller dan pastikan mereka mewarisi dari Controller.

Mesin perutean MVC akan secara otomatis merutekan ke Pengontrol di Perpustakaan Kelas dan Pengontrol akan secara otomatis membuat Tampilan dari proyek MVC asli, asalkan Anda memiliki referensi dan penggunaan yang benar.

Saya menggunakan arsitektur ini untuk mengimplementasikan modul Laporan Html yang dapat dikompilasi dan digunakan secara terpisah dari solusi utama. Akhirnya saya bebas dari SSRS!

Jamie
sumber