私は OOP を初めて使用するので、これが正しい処理方法であるかどうかを理解するために助けが必要です。私は 3 層 Web プロジェクト (+ DTO) を持っており、ビジネス オブジェクトからプレゼンテーション層に「エラー」を返す最良の方法を理解しようとしています。特に今、私はこのユーザーの作成に直面しています。ウェブサイトの登録時にデータベースにユーザーを作成したいとしましょう。ユーザー名または電子メールが既に取得されているかどうかを実際のユーザーに伝える必要があります (これは単なる例です)。
たとえば、ASP.NET Membership.CreateUser() メソッドは、MembershipCreateStatus オブジェクト byRef を渡すため、このメソッドを使用して Enum (別の名前空間に存在します...) を返し、試行のステータスを渡します。これは、DuplicateEmail の可能性があります。 DuplicateUserName など。
例外に基づいて別の方法を実装しましたが、それについての意見をお願いします。ユーザーを作成する BLL マネージャー クラスで、ネストされた Excpetion クラスと、エラー タイプのネストされた Enum を次のように作成しました。
Public Class UserManager
Public Enum ErrorType
DatabaseError = 1
UserExists = 2
EmailExists = 3
End Enum
Public Class ManagerException
Inherits Exception
Public Property ErrorType As ErrorType
Public Property SuggestedUserName As String
Public Property SuggestedEmail As String
Public Sub New()
MyBase.New()
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, inner As Exception)
MyBase.New(message, inner)
End Sub
End Class
Public Function CreateUserLogin(user As EvaVwUserLogin) As Guid
If user Is Nothing Then
Throw New ApplicationException("No user suppied")
End If
If String.IsNullOrWhiteSpace(user.Password) OrElse String.IsNullOrWhiteSpace(user.UserName) Then
Throw New ApplicationException("Password or username missing")
End If
If CheckDuplicateUserName() Then
Dim ex As New ManagerException("Username exists")
ex.ErrorType = ErrorType.UserExists
ex.SuggestedUserName = "this username is free"
Throw ex
End If
End Function
End Class
次に、UI レイヤー (aspx コード ビハインド) でマネージャーを呼び出し、次のように例外を確認します。
Dim userManager As New UserManager
Try
userManager.CreateUserLogin("test", "test")
Catch ex As UserManager.ManagerException
If ex.ErrorType = userManager.ErrorType.UserExists Then
Dim suggestedUsername = ex.SuggestedUserName
' Display error message and suggested user name
End If
End Try
例外と列挙型の両方がこのマネージャーに非常に固有であるため、このルートをたどると、各マネージャーに関連する列挙型を持つネストされた ManagerException があることを考えると、これは正しいアプローチですか?
いつもご意見ありがとうございます。
Brian と Cyborg によって親切に提案された「カスタム コード」シナリオをフォローアップします (Brian の方がより完全であるという理由だけで彼の回答にマークを付けました。他のユーザーが MS のアドバイスに興味を持っている可能性があります)。良い考えでしょうか?これらの列挙型はこのマネージャー クラスに厳密に関連付けられるため (そして、BLL の各マナガー クラスには独自のクラスがあります)、ステータス コードが渡されたときにそれらを引き続き使用できると思いますか?
編集:私はこのようにリファクタリングしました...大丈夫だと思いますか?
Public Class UserManager
Public Enum ErrorType
DatabaseError = 1
UserExists = 2
EmailExists = 3
End Enum
Public Class ErrorData
Public Property ErrorType As ErrorType
Public Property SuggestedUserName As String
Public Property SuggestedEmail As String
End Class
Public Function CreateUserLogin(username As String, password As String, ByRef errorData As ErrorData) As Guid
Dim user As New EvaVwUserLogin
user.UserName = username
user.Password = password
Return CreateUserLogin(user, errorData)
End Function
Public Function CreateUserLogin(user As EvaVwUserLogin, ByRef errorData As ErrorData) As Guid
If user Is Nothing Then
Throw New ApplicationException("No user object")
End If
If String.IsNullOrWhiteSpace(user.Password) OrElse String.IsNullOrWhiteSpace(user.UserName) Then
Throw New ApplicationException("Missing password or username")
End If
Dim hashedPassword As String
hashedPassword = Crypto.HashPassword(user.Password)
If UserExists(user) Then
errorData.ErrorType = ErrorType.UserExists
errorData.SuggestedUserName = "this username is free"
Return Nothing
End If
.....
End Function
End Class
そして、プレゼンテーション層では:
Dim userManager As New UserManager
Dim managerError As New UserManager.ErrorData
Dim userId As Guid
userId = userManager.CreateUserLogin("test", "test", managerError)
If userId = Nothing Then
If managerError.ErrorType = userManager.ErrorType.UserExists Then
Dim suggestedUserName = managerError.SuggestedUserName
' Do something with suggested user name
End If
End If