在我的项目中,我有我的 Linq To SQL dbml 文件、每个数据库表的存储库层和每个存储库的服务层。
在我的服务中,我有一些用于验证的元数据,并且我扩展了每个(表)类以向对象添加一些自定义信息(您将在下面的代码中看到这一点)。
我的问题是,我应该考虑为每个(表)类构建一个自定义 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)
现在我遇到的一件事是每当我需要使用 Slug 时都需要将用户对象发送到 Slug 属性
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)
在我看来,分离是一件好事,但仍然需要大量的时间来构建。只是想知道权衡的好处,或者是否有更好的方法来完成同样的事情?