MVC + 3 ชั้น ที่ ViewModels เข้ามาเล่น?


11

ฉันออกแบบแอพพลิเคชั่น 3 ชั้นโดยใช้ ASP.NET MVC 4 ฉันใช้ทรัพยากรต่อไปนี้เป็นข้อมูลอ้างอิง

ฉันมีดีไซน์ดังต่อไปนี้

Presentation Layer (PL) (โครงการ MVC หลักที่MของMVCถูกย้ายไปยัง Data Access Layer):

MyProjectName.Main
    Views/
    Controllers/
    ...

ชั้นตรรกะทางธุรกิจ (BLL) :

MyProjectName.BLL
    ViewModels/
    ProjectServices/
    ...

ชั้นการเข้าถึงข้อมูล (DAL) :

MyProjectName.DAL
    Models/
    Repositories.EF/
    Repositories.Dapper/
    ...

ตอนนี้ PL อ้างอิง BLL และ BLL อ้างอิง DAL วิธีนี้เลเยอร์ที่ต่ำกว่าจะไม่ขึ้นอยู่กับชั้นบน

ในการออกแบบนี้ PL จะเรียกใช้บริการของ BLL PL สามารถส่ง View Model ไปที่ BLL และ BLL สามารถส่ง View Model กลับไปที่ PL ได้

นอกจากนี้ BLL เรียกใช้ชั้น DAL และชั้น DAL สามารถส่งคืนแบบจำลองกลับไปที่ BLL BLL สามารถสร้างมุมมองแบบจำลองและส่งคืนเป็น PL ได้

ถึงตอนนี้รูปแบบนี้ใช้งานได้สำหรับฉัน อย่างไรก็ตามฉันพบปัญหาที่ ViewModels ของฉันบางรายต้องรวมกับเอนทิตีหลายแห่ง ในวิธีการ MVC ธรรมดาในการควบคุมที่ผมใช้แบบสอบถาม LINQ เพื่อทำjoins select new MyViewModel(){ ... }แล้ว แต่ตอนนี้ใน DAL ฉันไม่สามารถเข้าถึงที่กำหนด ViewModels (ใน BLL)

นี่หมายความว่าฉันไม่สามารถเข้าร่วมใน DAL และส่งคืนให้ BLL ได้ ดูเหมือนว่าฉันต้องทำแบบสอบถามแยกต่างหากใน DAL (แทนที่จะรวมในแบบสอบถามเดียว) และ BLL จะใช้ผลลัพธ์เหล่านี้เพื่อสร้าง ViewModel สิ่งนี้ไม่สะดวกมาก แต่ฉันไม่คิดว่าฉันควรเปิดเผย DAL ให้กับ ViewModels

ความคิดใด ๆ ที่ฉันสามารถแก้ปัญหานี้ได้อย่างไร ขอบคุณ

คำตอบ:


18

โครงการ MVC หลักที่ M ของ MVC ถูกย้ายไปยัง Data Access Layer

ความเข้าใจผิดที่พบบ่อย ส่วนMของMVCไม่มีอะไรเกี่ยวข้องกับข้อมูลแม้จะมีตัวอย่างและแบบฝึกหัดมากมายที่อ้างว่าเป็นเช่นนั้น

M เป็น ViewModel ของคุณและควรอยู่ในโครงการ MVC ของคุณ ViewModels ที่คุณมีใน BLL ของคุณนั้นมีชื่อว่า DataContracts หรือ BusinessModels

ในตัวควบคุมของคุณคุณมีสิ่งที่เทียบเคียงได้กับสิ่งนี้:

Get(id):
    dataContract = _service.Get(id);
    viewModel = Map(dataContract);
    return viewModel

ในบริการของคุณมีดังนี้:

Get(id):
    dataModel = _dataAccess.Get(id);
    dataContract = Map(dataModel);
    return dataContract;

และใน DataAccess คุณทำการเชื่อมต่อที่เหมาะสมตามวัตถุที่ร้องขอ อย่างไรก็ตามคุณสามารถเพิ่มวิธีการแบบกำหนดเองลงใน DataAccess ของคุณได้ตามต้องการดังนั้นบริการของคุณสามารถเรียกวิธีการเหล่านั้นได้:

GetWithBars():
    dataModels = _repository.Query("select from foos join bars");
    return dataModels;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.