1

OOP에 익숙하지 않아이를 처리하는 올바른 방법인지 이해하는 데 도움이 필요합니다. 3 레이어 웹 프로젝트 (+ DTOs)가 있으며 비즈니스 개체에서 프레젠테이션 레이어로 "오류"를 반환하는 가장 좋은 방법임을 이해하려고합니다. 특히 나는 사용자 생성과 마주하고 있습니다. 웹 사이트 등록시 DB에 사용자를 생성하고 실제 사용자에게 사용자 이름 또는 이메일을 이미 가져 왔는지 여부를 알려주고 싶다고 가정 해 봅시다 (이는 단지 예일뿐입니다).비즈니스 레이어에서 ASP.NET 사용자 정의 예외 처리

ASP.NET Membership.CreateUser() 메서드는 MembershipCreateStatus 개체 byRef를 전달하므로이 메서드는 Enum (다른 네임 스페이스에 상주 함)을 반환하여 시도 상태를 전달하는 데 사용됩니다. DuplicateEmail, DuplicateUserName 등이 될 수 있습니다.

예외를 기반으로 다른 방법을 구현했지만 그 점에 대해 귀하의 의견을 말씀드립니다. UI 계층에서 다음

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 

(뒤에 영문 코드) 내가 관리자를 호출하고 같은 예외를 확인 : 사용자를 생성 BLL 관리자 클래스에서 나는 오류 유형이 방법을 중첩 Excpetion 클래스와 중첩 된 열거 형을 생성 이 :

 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을 수 있도록 예외와 열거 모두이 관리자에게 매우 구체적인 것을 고려하고, 올바른 방법인가?

언제나처럼 당신의 의견에 미리 감사드립니다.


친절 브라이언과 사이보그가 제시 한 "사용자 지정 코드"시나리오를 따라 당신이 생각 (어쩌면 다른 사용자가 MS의 조언에 관심이 더 완전한 브라이언 그냥 때문에 그의 대답을 표시)가 사용자 정의 반환 객체를 중첩 관리자 클래스의 상대적 열거 형은 좋은 아이디어일까요? 이 열거 형은이 관리자 클래스와 엄격하게 관련이 있으므로 (BLL의 각 managar 클래스는 자신 만 소유하게됩니다) 상태 코드가 전달 될 때 계속 사용할 수 있다고 생각합니까?

편집 :이 방법으로 리팩터링했는데 ... 괜찮습니까?

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 

답변

2

(이 대답은 @BrianMains가 예외가 아닌 반환 코드를 사용하도록 제안하는 것입니다. 관련 문서가 너무 커서 설명에 맞지 않습니다.) 예외에 대한 MSDN 문서에서

: 당신은 던지거나 예외를 처리 할 때 시스템 리소스와 실행 시간의

상당한 양이 사용된다. 예측 가능한 이벤트 나 흐름 제어를 다루지 않고 진정한 특별한 조건을 처리하기 위해서만 예외를 던집니다. 예를 들어 유효한 매개 변수로 메소드를 호출 할 것이기 때문에 메소드 인수가 유효하지 않으면 응용 프로그램에서 예외를 발생시킬 수 있습니다. 잘못된 메소드 인수는 특별한 것이 발생했음을 의미합니다. 반대로 은 사용자 입력이 잘못된 경우을 예외로 처리하지 않으므로 사용자가 때때로 잘못된 데이터를 입력 할 수 있기 때문입니다. 이러한 경우 사용자가 유효한 입력을 입력 할 수 있도록 재시도 메커니즘을 제공하십시오.

예외 조건에만 예외를 발생시킨 다음 특정 예외에 적용되는 처리기가 아니라 대부분의 응용 프로그램에 적용되는 범용 예외 처리기에서 예외를 catch합니다. 이 접근법의 이론적 근거는 대부분의 오류가 유효성 검사 및 오류 처리 코드에 의해 오류 근처에서 처리 될 수 있다는 것입니다. 예외를 던지거나 잡힐 필요가 없습니다. 범용 예외 처리기는 응용 프로그램의 어디에서나 발생하는 예기치 않은 예외를 포착합니다.

또한 은 반환 코드가 충분할 때 예외를 throw하지 않습니다.; 반환 코드를 예외로 변환하지 마십시오. 그리고 일상적으로 예외를 잡아 내지 않으며 무시하고 처리를 계속합니다.

http://msdn.microsoft.com/en-us/library/system.exception.aspx

+0

모두들 감사합니다. 내가 정확한 어딘가 반대편을 읽기 때문에 나는 "custom exception"경로를 사용했다. 필자는 다중 레이어 아키텍처가 준수한다고 생각하는 구성 요소 기반 시나리오에서 구성 요소가 "매직 넘버"또는 코드가 아니라 예외를 반환해서는 안된다는 것을 읽었습니다. 하지만 매번 사용자 지정 예외를 인스턴스화하고 사용자 지정 열거 형을 확인해야하므로이 코드는 사용자 지정 반환 코드를 처리하는 것과 매우 유사하지만 훨씬 비쌉니다. – Manight

+0

나는 예외적 인 일이 생겼을 때 함수가 "매직 넘버"를 반환해서는 안된다는 것을 읽은 것으로 생각한다. 예를 들어, 성공했을 때 0을 반환하고 실패한 경우 -1을 반환하는 함수는 .NET에서 눈살을 찌푸리게됩니다. 이 경우 예외가 선호됩니다. 그러나 함수가 * 무언가를하고 * 결과가 여러 * 예상 * 것들 중 하나가 될 수 있다면 반환 코드가 적합합니다. – JDB

2

, 나는 회원 API가 무엇을 따를 것입니다. 보기에서 응답을 확인하는 데 사용할 수있는 비즈니스 구성 요소의 열거 형을 반환합니다. 따라서 ASP.NET 페이지에 언급 한 값을 가진 열거 형을 반환하고 거기에서 유형을 확인하십시오. 당신은 당신이하고있는 일을 할 수는 있지만, 필요하다고 생각하지는 않습니다. 게다가 예외를 던지는 것은 비싸다.

열거 형의 의미를 명확히하기 위해 비즈니스 구성 요소를 호출 한 사람이 예외를 사용하지 않고 반환합니다.

+1

한 리턴 코드가이 경우에 해당 될 것이다 (강조 광산). 경우에 따라 많은 값 (데이터 세트, 상태 코드 등)을 반환하려는 경우 적절한 값으로 초기화 된보다 복잡한 'CreateLoginResult'객체를 반환 할 수 있습니다. – JDB

+0

동의. 여기에 필요한 것처럼 보이지 않았지만 나는 그 상황에 처했다. –