2009-02-09 99 views
2

正如我之前說過的,我正在開發一個digg克隆來教自己ASP.NET MVC內部和外部,但我碰到了一個我似乎無法避免的道路碰撞。ASP.NET MVC設計

我希望能夠儘可能地優化這個應用程序,所以我有我的DAL這是一堆的類... Repository:Repository。現在爲了優化性能,我有我的基礎存儲庫類返回我的ViewData對象,以便他們可以選擇所需的額外字段而不必創建匿名類型。

故事有創建它們的用戶和用戶有故事投票。非常容易的DB佈局。現在我處理自己的成員資格,因爲默認的ASP.NET成員資格非常臃腫。在我看來的故事列表中,我必須確定當前用戶是否對所呈現的故事進行了投票。現在,因爲我認爲View中的數據訪問不應該發生,它應該在我的控制器或DAL中。因爲我已經從我的DAL返回ViewData,所以在名爲「UserVotedOn」的StoryViewData類型上添加了另一個屬性,如果用戶對該故事進行了投票,則返回true。

問題在於我必須A)讓DAL知道成員資格或B)將用戶ID傳遞到DAL上的查詢方法中。這些都不適合我,我正在尋找一些好的解決方案。歡迎任何反饋。

回答

3

在我的MVC應用程序中,我使用的是Rob Conery在MVC店面視頻系列中展示的架構,它對我來說就像魅力一樣。

庫=>服務+過濾器=>控制器=>查看

我試圖模仿要達到什麼和管理待辦事項這樣

EDIT1:在庫中改變的IList IQueryable的到和過濾器

public interface IRepository 
{ 
    IQueryable<Vote> GetVotes(); 
    IQueryable<Story> GetStories(); 
} 

服務爲得到你想要的

public class Service : IService 
{ 
    private IRepository _repository; 

    public Service(IRepository repository) 
    { 
     _repository = repository; 
     if (_repository == null) throw new InvalidOperationException("Repository cannot be null"); 
    } 
    public IList<Vote> GetUserVotes(int userID) 
    { 
     return _repository.GetVotes().WithUserID(userID).ToList(); 
    } 
    public IList<Story> GetNotVotedStories(IList<Vote> votes) 
    { 
     return _repository.GetStories().WithoutVotes(votes).ToList(); 
    } 
} 

過濾器來過濾你的故事和用戶投票(這些基本上是擴展方法)。不是最好的實施擺在那裏,但你以後可以改寫

public static class Filters 
{ 
    public static IQueryable<Vote> WithUserID(this IQueryable <Vote> qry, int userID) 
    { 
     return from c in qry 
       where c.UserID == userID 
       select c; 
    } 
    public static IQueryable<Story> WithoutVotes(this IQueryable <Story> qry, IList <Vote> votes) 
    { 
     return from c in qry 
       where votes.Where(x => x.StoryID == c.StoryID).ToList().Count > 0 
       select c; 
    } 
} 

然後你就可以在控制器通過當前用戶名,而不是在DAL或視圖像你不得不這樣做之前

public class HomeController : Controller 
{ 
    private readonly IRepository _repository; 
    private readonly IService _service; 

    public HomeController() 
    { 
     _repository = new Repository(); 
     _service = new Service.Service(_repository); 
    } 

    public ActionResult Index() 
    { 
     var userVotes = _service.GetUserVotes(CurrentUserID); 
     var unvotedStories = _service.GetNotVotedStories(userVotes); 

     return View(unvotedStories); 
    } 
} 

這可以讓你以避免添加用戶相關UserVotedOn屬性到您的故事模型

1

看起來你錯過了BLL。實際上,MVC應用程序的正確架構是許多人仍在試圖弄清楚的。

我個人認爲UserID有點像是跨平臺的概念。它將出現在DAL和BLL兩個層面上。

基本上,您的控制器方法應該只對BLL進行一些非常基本的調用,僅用於確定如何對用戶輸入做出反應,無論是返回視圖還是其他視圖。

您的視圖應該只處理模型對象。模型應該可能由業務邏輯填充。您可以在控制器方法中調用BL方法以初始化您的模型對象,然後將其傳遞給視圖。

控制器不應直接與數據庫通信。它也不應該處理組成你的域對象和模型的低級對象。

P.S.我會盡量避免廣泛使用ViewData。強類型模型類是一個更好的選擇。您也可以將它們按層次結構分組,以繼承一些常用屬性。就像您的域模型類可以從具有UserID屬性定義的基類派生一樣。

+0

那麼,當我說DAL技術上是一個BLL。它包裝了datacontext。當我說ViewData我的意思是我有ViewData類,我傳遞到強類型的意見。感謝您的輸入,我會把它浸入其中。 – 2009-02-09 18:41:01

+0

我自己一直在試圖想出「完美」的MVC架構。經過幾個月的試驗後,我可以說完美的架構和理想的關注分離是不可能的(誰會懷疑)。你只需要認同你自己並做出一些妥協。 – User 2009-02-09 18:49:26