私のプロジェクトでは、Linq To SQL dbml ファイル、各 DB テーブルのリポジトリ レイヤー、および各リポジトリのサービス レイヤーがあります。
私のサービスでは、検証用のメタデータがいくつかあり、各 (テーブル) クラスを拡張して、オブジェクトにカスタム情報を追加します (これは以下のコードで確認できます)。
私の質問は、サービス層で拡張されたクラスを使用する代わりに、各 (テーブル) クラスのカスタム 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)
今私が遭遇したことの 1 つは、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)
分離は良いことのように思えますが、構築するにはまだかなりの時間が必要です。トレードオフの利点について疑問に思っているだけですか、それとも同じことを達成するためのより良い方法があるのでしょうか?