■ 클라이언트/서버 만들기 – 알려진 타입을 사용하는 방법을 보여준다.
[Server]
▶ Geometry.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 |
using System; using System.Runtime.Serialization; namespace TestProject { /// <summary> /// 도형 /// </summary> [DataContract(Namespace = "http://company.com/graphics/geometry")] [KnownType(typeof(Rectangle))] [KnownType(typeof(Circle))] [KnownType(typeof(Arc))] // 상기 typeof(...) 설정 대신 IEnumerable을 리턴하는 메소드로 대체할 수 있다. //[KnownType("GetKnownTypeArray")] public class Geometry { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// ID /// </summary> [DataMember] public int ID; /// <summary> /// 왼쪽 /// </summary> [DataMember] public int Left = 0; /// <summary> /// 위쪽 /// </summary> [DataMember] public int Top = 0; /// <summary> /// 너비 /// </summary> [DataMember] public int Width = 0; /// <summary> /// 높이 /// </summary> [DataMember] public int Height = 0; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 알려진 타입 배열 구하기 - GetKnownTypeArray() /// <summary> /// 알려진 타입 배열 구하기 /// </summary> /// <returns>알려진 타입 배열</returns> private static Type[] GetKnownTypeArray() { return new Type[] { typeof(Rectangle), typeof(Circle), typeof(Arc) }; } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Public #region 그리기 - Draw() /// <summary> /// 그리기 /// </summary> public virtual void Draw() { Console.WriteLine("도형 그리기 ({0},{1})-({2},{3})", Left, Top, Left + Width, Top + Height); } #endregion } } |
▶ Rectangle.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.Runtime.Serialization; namespace TestProject { /// <summary> /// 사각형 /// </summary> [DataContract(Namespace = "http://company.com/graphics/geometry")] public class Rectangle : Geometry { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 채우기 여부 /// </summary> [DataMember] public bool Fill = true; /// <summary> /// 채우기 색상 /// </summary> [DataMember] public int FillColor = 0; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 그리기 - Draw() /// <summary> /// 그리기 /// </summary> public override void Draw() { Console.Write("사각형 그리기 ({0},{1})-({2},{3})", Left, Top, Left + Width, Top + Height); if(Fill) { Console.WriteLine(" 채우기 색상 값 {0}", FillColor); } else { Console.WriteLine(" 채우지 않음"); } } #endregion } } |
▶ Circle.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.Runtime.Serialization; namespace TestProject { /// <summary> /// 원 /// </summary> [DataContract(Namespace = "http://company.com/graphics/geometry")] public class Circle : Geometry { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 채우기 여부 /// </summary> [DataMember] public bool Fill = true; /// <summary> /// 반지름 /// </summary> [DataMember] public int Radius = 0; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 그리기 - Draw() /// <summary> /// 그리기 /// </summary> public override void Draw() { Console.WriteLine("원 그리기 ({0},{1}) R={2}", Left, Top, Radius); } #endregion } } |
▶ Arc.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 |
using System; using System.Runtime.Serialization; namespace TestProject { /// <summary> /// 원호 /// </summary> [DataContract(Namespace = "http://company.com/graphics/geometry")] public class Arc : Circle { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 시작 각도 /// </summary> [DataMember] public int StartAngle = 0; /// <summary> /// 종료 각도 /// </summary> [DataMember] public int EndAngle = 90; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 그리기 - Draw() /// <summary> /// 그리기 /// </summary> public override void Draw() { Console.WriteLine ( "원호 그리기 ({0},{1}) 반지름={2} 시작 각도={3}, 종료 각도={4}", Left, Top, Radius, StartAngle, EndAngle ); } #endregion } } |
▶ IGraphics.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/graphics")] public interface IGraphics { //////////////////////////////////////////////////////////////////////////////////////////////////// Method #region 도형 추가하기 - AddGeometry(geometry) /// <summary> /// 도형 추가하기 /// </summary> /// <param name="geometry">도형</param> [OperationContract] void AddGeometry(Geometry geometry); #endregion #region 도형 구하기 - GetGeometry(id) /// <summary> /// 도형 구하기 /// </summary> /// <param name="id">ID</param> /// <returns>도형</returns> [OperationContract] Geometry GetGeometry(int id); #endregion } } |
▶ GraphicsService.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 |
using System.Collections.Generic; using System.ServiceModel; namespace TestProject { /// <summary> /// 그래픽스 서비스 /// </summary> [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class GraphicsService : IGraphics { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 도형 딕셔너리 /// </summary> private static Dictionary<int, Geometry> _geometryDictionary = new Dictionary<int, Geometry>(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static #region 생성자 - GraphicsService() /// <summary> /// 생성자 /// </summary> static GraphicsService() { Geometry geometry = new Geometry(); geometry.ID = 0; geometry.Left = 0; geometry.Top = 0; geometry.Width = 0; geometry.Height = 0; _geometryDictionary.Add(geometry.ID, geometry); Circle circle = new Circle(); circle.ID = 1; circle.Left = 100; circle.Top = 100; circle.Width = 100; circle.Height = 100; circle.Fill = false; _geometryDictionary.Add(circle.ID, circle); Rectangle rectangle = new Rectangle(); rectangle.ID = 2; rectangle.Left = 200; rectangle.Top = 200; rectangle.Width = 200; rectangle.Height = 200; rectangle.Fill = true; rectangle.FillColor = 2; _geometryDictionary.Add(rectangle.ID, rectangle); Arc arc = new Arc(); arc.ID = 3; arc.Left = 300; arc.Top = 300; arc.Width = 300; arc.Height = 300; arc.StartAngle = 180; arc.EndAngle = 270; _geometryDictionary.Add(arc.ID, arc); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 도형 추가하기 - AddGeometry(geometry) /// <summary> /// 도형 추가하기 /// </summary> /// <param name="geometry">도형</param> public void AddGeometry(Geometry geometry) { if(_geometryDictionary.ContainsKey(geometry.ID) == true) { _geometryDictionary[geometry.ID] = geometry; } else { lock(_geometryDictionary) { _geometryDictionary.Add(geometry.ID, geometry); geometry.Draw(); } } } #endregion #region 도형 구하기 - GetGeometry(id) /// <summary> /// 도형 구하기 /// </summary> /// <param name="id">ID</param> /// <returns>도형</returns> public Geometry GetGeometry(int id) { if(_geometryDictionary.ContainsKey(id) == true) { return _geometryDictionary[id]; } 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 |
using System; using System.ServiceModel; using System.ServiceModel.Description; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.WriteLine("데이터 계약 상속 테스트 서버를 시작합니다..."); ServiceHost serviceHost = new ServiceHost(typeof(GraphicsService), new Uri("http://localhost/wcf/graphics")); serviceHost.AddServiceEndpoint(typeof(IGraphics), 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 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 |
using System; using TestProject.Graphics; namespace TestProject { /// <summary> /// 프로그램 /// </summary> public class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Console.WriteLine("데이터 계약 상속 테스트 클라이언트를 시작합니다..."); Geometry geometry = new Rectangle(); geometry.ID = 101; geometry.Left = 1; geometry.Top = 1; geometry.Width = 111; geometry.Height = 111; using(GraphicsClient graphicsClient = new GraphicsClient()) { graphicsClient.AddGeometry(geometry); geometry = graphicsClient.GetGeometry(0); Console.WriteLine ( "도형 객체 = {0}", geometry.GetType().Name ); Console.WriteLine ( " ({0},{1}) - ({2}, {3})", geometry.Left, geometry.Top, geometry.Left + geometry.Width, geometry.Top + geometry.Height ); geometry = graphicsClient.GetGeometry(1); Console.WriteLine ( "도형 객체 = {0}", geometry.GetType().Name ); Console.WriteLine ( " ({0},{1}) - ({2}, {3})", geometry.Left, geometry.Top, geometry.Left + geometry.Width, geometry.Top + geometry.Height ); geometry = graphicsClient.GetGeometry(2); Console.WriteLine ( "도형 객체 = {0}", geometry.GetType().Name ); Console.WriteLine ( " ({0},{1}) - ({2}, {3})", geometry.Left, geometry.Top, geometry.Left + geometry.Width, geometry.Top + geometry.Height ); geometry = graphicsClient.GetGeometry(3); Console.WriteLine ( "도형 객체 = {0}", geometry.GetType().Name ); Console.WriteLine ( " ({0},{1}) - ({2}, {3})", geometry.Left, geometry.Top, geometry.Left + geometry.Width, geometry.Top + geometry.Height ); } } #endregion } } |
※ GraphicsClient 클래스는 서비스 참조 추가를 통해 생성한다.