■ IErrorHandler 인터페이스를 사용해 중앙집중적으로 예외를 처리하는 방법을 보여준다.
[TestServer 프로젝트]
▶ GlobalErrorHandler.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
using System; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; namespace TestServer { /// <summary> /// 글로벌 에러 핸들러 /// </summary> public class GlobalErrorHandler : IErrorHandler { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 에러 처리하기 - HandleError(exception) /// <summary> /// 에러 처리하기 /// </summary> /// <param name="exception">예외</param> /// <returns>처리 여부</returns> public bool HandleError(Exception exception) { // 예외 처리 로그를 작성한다. return true; } #endregion #region 폴트 제공하기 - ProvideFault(exception, messageVersion, faultMessage) /// <summary> /// 폴트 제공하기 /// </summary> /// <param name="exception">예외</param> /// <param name="messageVersion">메시지 버전</param> /// <param name="faultMessage">폴트 메시지</param> public void ProvideFault(Exception exception, MessageVersion messageVersion, ref Message faultMessage) { if(exception is FaultException) { return; } FaultException faultException = new FaultException("일반적인 서비스 오류가 발생했습니다."); MessageFault messageFault = faultException.CreateMessageFault(); faultMessage = Message.CreateMessage(messageVersion, messageFault, null); } #endregion } } |
▶ GlobalErrorHandlerBehaviourAttribute.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
using System; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; namespace TestServer { /// <summary> /// 글로벌 에러 핸들러 행동 어트리뷰트 /// </summary> public class GlobalErrorHandlerBehaviourAttribute : Attribute, IServiceBehavior { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 에러 핸들러 타입 /// </summary> private readonly Type errorHandlerType; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - GlobalErrorHandlerBehaviourAttribute(errorHandlerType) /// <summary> /// 생성자 /// </summary> /// <param name="errorHandlerType">에러 핸들러 타입</param> public GlobalErrorHandlerBehaviourAttribute(Type errorHandlerType) { this.errorHandlerType = errorHandlerType; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 무결성 조사하기 - Validate(serviceDescription, serviceHostBase) /// <summary> /// 무결성 조사하기 /// </summary> /// <param name="serviceDescription">서비스 설명</param> /// <param name="serviceHostBase">서비스 호스트 베이스</param> public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } #endregion #region 바인딩 매개 변수 추가하기 - AddBindingParameters(serviceDescription, serviceHostBase, serviceEndpointCollection, bindingParameterCollection) /// <summary> /// 바인딩 매개 변수 추가하기 /// </summary> /// <param name="serviceDescription">서비스 설명</param> /// <param name="serviceHostBase">서비스 호스트 베이스</param> /// <param name="serviceEndpointCollection">서비스 종점 컬렉션</param> /// <param name="bindingParameterCollection">바인딩 매개 변수 컬렉션</param> public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> serviceEndpointCollection, BindingParameterCollection bindingParameterCollection) { } #endregion #region 디스패처 행동 적용하기 - ApplyDispatchBehavior(serviceDescription, serviceHostBase) /// <summary> /// 디스패처 행동 적용하기 /// </summary> /// <param name="serviceDescription">서비스 설명</param> /// <param name="serviceHostBase">서비스 호스트 베이스</param> public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { IErrorHandler errorHandler = (IErrorHandler)Activator.CreateInstance(this.errorHandlerType); foreach(ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) { ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher; if(channelDispatcher != null) { channelDispatcher.ErrorHandlers.Add(errorHandler); } } } #endregion } } |
▶ CalculatorService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
namespace TestServer { /// <summary> /// 계산기 서비스 /// </summary> [GlobalErrorHandlerBehaviour(typeof(GlobalErrorHandler))] public class CalculatorService : ICalculatorService { ////////////////////////////////////////////////////////////////////////////////////////// Method //////////////////////////////////////////////////////////////////////////////// Public #region 나누기 - Divide(numerator, denominator) /// <summary> /// 나누기 /// </summary> /// <param name="numerator">분모</param> /// <param name="denominator">분자</param> /// <returns>몫</returns> public int Divide(int numerator, int denominator) { return numerator / denominator; } #endregion } } |
[TestClient 프로젝트]
▶ MainForm.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
using System; using System.ServiceModel; using System.Windows.Forms; using TestClient.CalculatorService; namespace TestClient { /// <summary> /// 메인 폼 /// </summary> public partial class MainForm : Form { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainForm() /// <summary> /// 생성자 /// </summary> public MainForm() { InitializeComponent(); this.calculateButton.Click += calculateButton_Click; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 계산하기 - calculateButton_Click(sender, e) /// <summary> /// 계산하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void calculateButton_Click(object sender, EventArgs e) { int numerator = Convert.ToInt32(this.numeratorTextBox.Text ); int denominator = Convert.ToInt32(this.denominatorTextBox.Text); using(CalculatorServiceClient client = new CalculatorServiceClient("BasicHttpBinding_ICalculatorService")) { try { this.resultTextBox.Text = client.Divide(numerator, denominator).ToString(); } catch(FaultException faultException) { MessageBox.Show(this, faultException.Message); } } } #endregion } } |