■ 클라이언트/서버 만들기 – 직렬화 이벤트를 사용하는 방법을 보여준다.
[Server]
▶ BookInfo.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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
using System.Runtime.Serialization; namespace TestProject { /// <summary> /// 도서 정보 /// </summary> [DataContract(Namespace = "http://company.com/bookstore/data")] public class BookInfo { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 제목 /// </summary> [DataMember] public string Title; /// <summary> /// ISBN /// </summary> [DataMember(IsRequired = true)] public readonly string ISBN; /// <summary> /// 저자 /// </summary> [DataMember] public string Author; /// <summary> /// 가격 /// </summary> [DataMember] public int Price; /// <summary> /// 할인율 /// </summary> public double MarginRate; #endregion ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 저장 가격 /// </summary> private int SavedPrice; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - BookInfo(title, isbn, author, price) /// <summary> /// 생성자 /// </summary> /// <param name="title">제목</param> /// <param name="isbn">ISBN</param> /// <param name="author">저자</param> /// <param name="price">가격</param> public BookInfo(string title, string isbn, string author, int price) { Title = title; ISBN = isbn; Author = author; Price = price; MarginRate = 0.25; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 직렬화 전 처리하기 - BeforeSerialization(streamingContext) /// <summary> /// 직렬화 전 처리하기 /// </summary> /// <param name="streamingContext">스트리밍 컨텍스트</param> [OnSerializing] private void BeforeSerialization(StreamingContext streamingContext) { SavedPrice = Price; Price = 10000; Console.WriteLine("OnSerializing 이벤트 : 직렬화 전, 상태 = {0}", streamingContext.State); } #endregion #region 직렬화 후 처리하기 - AfterSerialization(streamingContext) /// <summary> /// 직렬화 후 처리하기 /// </summary> /// <param name="streamingContext">스트리밍 컨텍스트</param> [OnSerialized] private void AfterSerialization(StreamingContext streamingContext) { Price = SavedPrice; Console.WriteLine("OnSerialized 이벤트 : 직렬화 후, 상태 = {0}", streamingContext.State); } #endregion #region 역직렬화 전 처리하기 - BeforeDeserialization(streamingContext) /// <summary> /// 역직렬화 전 처리하기 /// </summary> /// <param name="streamingContext">스트리밍 컨텍스트</param> [OnDeserializing] private void BeforeDeserialization(StreamingContext streamingContext) { MarginRate = 0.25; Console.WriteLine("OnDeserializing 이벤트 : 역직렬화 전, 상태 = {0}", streamingContext.State); } #endregion #region 직렬화 후 처리하기 - AfterDeserialization(streamingContext) /// <summary> /// 직렬화 후 처리하기 /// </summary> /// <param name="streamingContext">스트리밍 컨텍스트</param> [OnDeserialized] private void AfterDeserialization(StreamingContext streamingContext) { Console.WriteLine("OnDeserialized 이벤트 : 역직렬화 후, 상태 = {0}", streamingContext.State); } #endregion } } |
▶ IBookStore.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 |
using System.ServiceModel; namespace TestProject { /// <summary> /// 도서 관리하기 /// </summary> [ServiceContract(Namespace = "http://company.com/bookstore")] public interface IManageBook { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 도서 추가하기 - AddBook(bookInfo) /// <summary> /// 도서 추가하기 /// </summary> /// <param name="bookInfo">도서 정보</param> [OperationContract] void AddBook(BookInfo bookInfo); #endregion #region 도서 정보 구하기 - GetBookInfo(isbn) /// <summary> /// 도서 정보 구하기 /// </summary> /// <param name="isbn">ISBN</param> /// <returns>도서 정보</returns> [OperationContract] BookInfo GetBookInfo(string isbn); #endregion } } |
▶ BookStoreService.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.Generic; using System.ServiceModel; namespace TestProject { /// <summary> /// 상점 서비스 /// </summary> [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class BookStoreService : IManageBook { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 도서 정보 딕셔너리 /// </summary> private static Dictionary<string, BookInfo> _bookInfoDictionary = new Dictionary<string, BookInfo>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static #region 생성자 - BookStoreService() /// <summary> /// 생성자 /// </summary> static BookStoreService() { BookInfo bookInfo; bookInfo = new BookInfo("도서 1", "000-001", "저자 1", 40000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo("도서 2", "000-002", "저자 2", 42000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo("도서 3", "000-003", "저자 3", 53000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo("도서 4", "000-004", "저자 4", 37000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo("도서 5", "000-005", "저자 5", 18000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo("도서 6", "000-006", "저자 6", 20000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); bookInfo = new BookInfo(null , "000-007", null , 20000); _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 도서 추가하기 - AddBook(bookInfo) /// <summary> /// 도서 추가하기 /// </summary> /// <param name="bookInfo">도서 정보</param> public void AddBook(BookInfo bookInfo) { if(_bookInfoDictionary.ContainsKey(bookInfo.ISBN)) { _bookInfoDictionary[bookInfo.ISBN] = bookInfo; } else { lock(_bookInfoDictionary) { _bookInfoDictionary.Add(bookInfo.ISBN, bookInfo); } Console.WriteLine("새 책 할인율 = {0:##0}%", bookInfo.MarginRate * 100); } } #endregion #region 도서 정보 구하기 - GetBookInfo(isbn) /// <summary> /// 도서 정보 구하기 /// </summary> /// <param name="isbn">ISBN</param> /// <returns>도서 정보</returns> public BookInfo GetBookInfo(string isbn) { if(_bookInfoDictionary.ContainsKey(isbn)) { return _bookInfoDictionary[isbn]; } else { return null; } } #endregion } } |
▶ Program.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 |
using System; using System.ServiceModel; using System.ServiceModel.Description; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.WriteLine("직렬화 이벤트 테스트 서버를 시작합니다..."); ServiceHost serviceHost = new ServiceHost(typeof(BookStoreService), new Uri("http://localhost/wcf/bookstoreservice")); serviceHost.AddServiceEndpoint(typeof(IManageBook), new BasicHttpBinding(), string.Empty); ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior(); serviceMetadataBehavior.HttpGetEnabled = true; serviceHost.Description.Behaviors.Add(serviceMetadataBehavior); serviceHost.Open(); Console.WriteLine("서비스 중단을 위해 아무 키나 누르세요..."); Console.ReadKey(true); serviceHost.Close(); } #endregion } } |
[Client]
▶ Program.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 |
using System; using TestProject.BookStore; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.WriteLine("직렬화 이벤트 테스트 클라이언트를 시작합니다..."); BookInfo bookInfo = new BookInfo(); bookInfo.ISBN = "001-100"; bookInfo.Title = "간단한 것이 좋은 것이다"; bookInfo.Price = 12000; bookInfo.Author = null; using(ManageBookClient manageBookClient = new ManageBookClient()) { manageBookClient.AddBook(bookInfo); BookInfo bookInfo2 = manageBookClient.GetBookInfo("001-100"); Console.WriteLine ( "도서 정보 : \n 제목 = {0}\n 저자 = {1}\n ISBN = {2}\n Price = {3:#,##0}원", bookInfo2.Title, bookInfo2.Author, bookInfo2.ISBN, bookInfo2.Price ); } } #endregion } } |
※ ManageBookClient 클래스는 서비스 참조 추가를 통해 생성한다.