2010-07-12 25 views
0

在我的項目,我有我的LINQ to SQL的dbml文件,每個數據庫表A庫層,併爲每個庫服務層。問題有關ASP.NET MVC 2定製的ViewModels

在我的服務,我有一些元數據驗證以及我向每個(表)類的一些自定義信息添加到對象(你會看到這個在下面的代碼)。

我的問題是,我應該考慮在服務層使用擴展類的構建自定義ViewModal每個(表)類呢?

下面是什麼,我現在有一個例子。

Namespace Domain 
#Region "Interface" 
    Public Interface IUserRepository 
     Sub AddUser(ByVal openid As OpenID) 
     Function GetUsers() As IQueryable(Of User) 
     Sub UpdateUser(ByVal user As User) 
     Sub SubmitChanges() 
    End Interface 
#End Region 
#Region "Repository" 
    Public Class UserRepository : Implements IUserRepository 
     Private dc As MyDatabaseDataContext 
     Public Sub New() 
      dc = New MyDatabaseDataContext 
     End Sub 

     Public Sub AddUser(ByVal openid As OpenID) Implements IUserRepository.AddUser 
      Dim user As New User 
      user.MemberSince = DateTime.Now 
      openid.User = user 

      dc.OpenIDs.InsertOnSubmit(openid) 
     End Sub 

     Public Function GetUsers() As IQueryable(Of User) Implements IUserRepository.GetUsers 
      Dim users = (From u In dc.Users 
         Select u) 
      Return users.AsQueryable 
     End Function 

     Public Sub UpdateUser(ByVal user As User) Implements IUserRepository.UpdateUser 
      Dim _user = (From u In dc.Users 
       Where u.ID = user.ID 
       Select u).Single 

      With _user 
       .About = user.About 
       .BirthDate = user.BirthDate 
       .Email = user.Email 
       .isClosed = user.isClosed 
       .isProfileComplete = user.isProfileComplete 
       .RegionID = user.RegionID 
       .Reputation = user.Reputation 
       .UserName = user.UserName 
       .WebSite = user.WebSite 
      End With 

     End Sub 

     Public Sub SubmitChanges() Implements IUserRepository.SubmitChanges 
      dc.SubmitChanges() 
     End Sub 
    End Class 
#End Region 
End Namespace 

服務

Imports System.ComponentModel.DataAnnotations 

Namespace Domain 
#Region "Validation" 
    <MetadataType(GetType(UserMetaData))> _ 
    Partial Public Class User 
     Public Property UserRegion As String 
     Public Property LastSeen As DateTime 
     Public ReadOnly Property Slug(ByVal user As User) As String 
      Get 
       Return Replace(user.UserName, " ", "-") 
      End Get 
     End Property 
    End Class 


    ''' <summary> 
    ''' Validation for all User data. 
    ''' </summary> 
    ''' <remarks>All validation is done at the Service Layer</remarks> 
    Public Class UserMetaData 

     <DisplayName("name")> _ 
     <Required(ErrorMessage:="Username is required.")> _ 
     <StringLength(30, ErrorMessage:="Username cannot exceed 30 characters.")> _ 
     <RegularExpression("^\w{3,30}$", ErrorMessage:="Not a valid username.")> _ 
     Public Property UserName As String 

     <DisplayName("email")> _ 
     <StringLength(50, ErrorMessage:="Email Address cannot exceed 50 characters.")> _ 
     <RegularExpression("^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$", ErrorMessage:="Not a valid email address.")> _ 
     Public Property Email As String 

     <DisplayName("website")> _ 
     <StringLength(256, ErrorMessage:="Web Address cannot exceed 256 characters.")> _ 
     <RegularExpression("^http(s?)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$", ErrorMessage:="Not a valid website address.")> _ 
     Public Property WebSite As String 

     <DisplayName("about")> _ 
     <StringLength(2000, ErrorMessage:="Profile cannot exceed 2000 characters.")> _ 
     Public Property About As String 

     <DisplayName("region")> _ 
     <Required(ErrorMessage:="Region is required.")> _ 
     Public Property UserRegion As Integer 

     <DisplayName("birthdate")> _ 
     <DisplayFormat(ApplyFormatInEditMode:=True, ConvertEmptyStringToNull:=True, DataFormatString:="{0:MM/dd/yyyy}")> _ 
     Public Property BirthDate As DateTime 

    End Class 
#End Region 
#Region "Interface" 
    Public Interface IUserService 
     Sub AddUser(ByVal claimedidentifier As String, ByVal notes As String) 
     Function GetAllUsers() As IList(Of User) 
     Function GetUserByID(ByVal id As Integer) As User 
     Sub UpdateUser(ByVal user As User) 
     Sub SubmitChanges() 
    End Interface 
#End Region 
#Region "Service" 
    Public Class UserService : Implements IUserService 
     Private _UserRepository As IUserRepository 
     Public Sub New(ByVal UserRepository As IUserRepository) 
      _UserRepository = UserRepository 
     End Sub 

     Public Sub AddUser(ByVal claimedidentifier As String, ByVal notes As String) Implements IUserService.AddUser 
      Dim openid As New OpenID 
      openid.ClaimedIdentifier = claimedidentifier 
      openid.UserNotes = notes 
      _UserRepository.AddUser(openid) 
     End Sub 

     Public Function GetAllUsers() As System.Collections.Generic.IList(Of User) Implements IUserService.GetAllUsers 
      Return _UserRepository.GetUsers().Where(Function(u) (Not u.isClosed)).ToList 
     End Function 

     Public Function GetUserByID(ByVal id As Integer) As User Implements IUserService.GetUserByID 
      Return _UserRepository.GetUsers().Where(Function(u) (Not u.isClosed And u.ID = id)).SingleOrDefault 
     End Function 

     Public Sub UpdateUser(ByVal user As User) Implements IUserService.UpdateUser 
      _UserRepository.UpdateUser(user) 
     End Sub 

     Public Sub SubmitChanges() Implements IUserService.SubmitChanges 
      _UserRepository.SubmitChanges() 
     End Sub 

    End Class 
#End Region 

End Namespace 

,目前在我控制我送模態數據我的看法是這樣

Dim user As Domain.User = UserService.GetUserByID(id) 
    Return View(user) 

現在有一件事我有跑到是需要向用戶發送對象的彈頭特性,每當我需要使用的彈頭

Dim user As Domain.User = UserService.GetUserByID(id) 
    user.Slug = user.Slug(user) ''# this seems like a bit of a pain in the ass 
    Return View(user) 

的是因爲這一點,是它更好地爲我爲每個(表)創建一個自定義ViewModal,並簡單做以下

Dim user As Domain.UserViewModal = New Domain.UserViewModal(UserService.GetUserByID(id)) 
    ''# The UserViewModal will automatically do all the work to create the 
    ''# Slug as well as other pertinent information 
    Return View(user) 

在我看來,分離是一件好事,但仍需要時間的建設。只是想知道折中的好處,還是有更好的方法來完成同樣的事情?

+0

對於漫長的問題抱歉。 – 2010-07-12 01:58:20

回答

1

你可能會發現,你的模型類並不一定對應1:1的觀點。僅憑此原因,創建ViewModel對象並使用它們與視圖進行交互是有意義的,因爲視圖模型對象可以是各種模型信息的組合。

這樣做有責任確保您的視圖模型對象特別適合於用戶界面和可能包含特定屏幕列表或沒有任何業務的正常模型對象的其他屬性的額外好處。這可以讓你相反地實現好處,因爲你的視圖模型對象不需要被雜亂的/臃腫的除了他們的生活目的之外的任何東西。 (Linq to SQL對象必須跟蹤狀態並完成一系列與UI完全無關的事情)。

儘管分離是一種很好的做法,但如您所說,它可能是一種「屁股疼痛」。爲了讓您的類實例之間的信息傳輸變得更輕鬆,請查看Automapper,它可以很好地完成此任務,並且可以消除無數繁瑣而必要的代碼。

編碼愉快!

+0

感謝您的見解。你是否也使用ViewModal來插入和編輯視圖? – 2010-07-12 03:33:11

+0

是的,我幾乎在所有情況下都使用視圖模型。我通常沒有一個專門用於插入或者只是編輯的視圖,但是當我這樣做時,通常至少有一個下拉列表,我想通過將List 作爲ViewModel的屬性傳遞給查看以便在視圖中填充dd。(在大多數情況下,我更喜歡將ViewModel對象用於ViewData []。) – Tahbaza 2010-07-12 21:33:48