Dynamic import
: Dynamic lookup과 같이 사용되어서 COM에 대한 명시적 선언이 없이 COM 객체에 대한 접근 및 사용이 가능하다.
IDispatch의 이용과 거의 동일하게 사용 가능하다.
- //old code
- ((Excel.Range)excel.Cells[1,1]).value2 = "Hello";
- //New Code
- excel.Cells[1,1].Value = "Hello";
: Dynamic lookup과 같이 사용되어서 COM에 대한 명시적 선언이 없이 COM 객체에 대한 접근 및 사용이 가능하다.
IDispatch의 이용과 거의 동일하게 사용 가능하다.
: 가장 바라던 기능. 수많은 overload 함수들을 제거할 수 있게 된다. 다른 .NET Framework API들에서도 많은 변화가 있을 것 같다는 생각이 든다.
method나 instance를 동적으로 가능하도록 변경.
COM, IronPython, HTML DOM 또는 Reflection을 통해 얻어진 객체에 대한 동적인 접근이 가능.
The Dynamic Type
C# 4.0에서는 "dynamic" 으로 지정된 Type의 경우에는 runtime 시에 객체의 Byte code를 생성하게 된다.
C# compiler에서 Compile시에 dynamic으로 지정된 Instance의 경우에는 Compile시에 넘어가게 되고, runtime시에 method를 각 parameter의 type에 따라서 구현, 실행하게 된다.
이는 Type에서만 구현되는 것이 아닌, Method, Property 에서도 역시 같이 구현되게 된다.
: 상당히 멋진 기능이라고 생각되긴 하는데.. C#이 가진 선언적 언어 특성을 많이 버리는 느낌이 든다. 일단 백서에도 나와있듯이 안정성과 속도를 조금은 버리는 작업이기 때문에 사용하는 것에 있어서 많은 생각을 해봐야지 될것 같다. 무엇보다 Python이 아닌 IronPython의 객체를 얻어오는 것이라서, MS 가 아닌 다른 언어의 객체에 대한 구현은 조금 후에 알아봐야지 될것 같다. (분명히 Python도 되게 하는 방법이 생길것이다.)
: 그리고, 이미 사용되고 있는 곳은 매우 많다. Reflection을 통한 invoke와 너무나도 유사한 기능으로 Reflection의 확장으로 보이는 것은 나만의 착각인것일까?
: 생각하지 못했던 내용이 있었다. JSON 데이터 포멧의 경우에는 자유롭게 확장들이 가능해진다. 사용되는 Class의 Property가 무엇인지만 알면 dynamic으로 선언해서 데이터를 얻어오고, 데이터에 대한 객체화가 매우 자유롭게 바뀌게 된다.
Visual Studio 2010과 더불어서 같이 준비중인 C# 4.0에서의 새로운 기능들을 간단히 알아보려고 생각중.
참고 자료 사이트는
http://code.msdn.microsoft.com/csharpfuture
C# 4.0은 Dynamic programming을 기본 Theme로 가지고 있다.
Dynamic Programming언어라고 할 수 있는 Python이나 Ruby정도까지는 아니지만, Compile 할때가 아닌 Runtime시에 자신의 type을 결정할 수 있는 방법으로 구현되고자 한다. 이러한 Dynamic의 예는 다음과 같은 수 있다.
1. Python이나 Ruby와 같은 Dynamic Programming language에서 생성된 object
2. IDispatch를 통해 구현된 COM objects
3. refrection을 통해 구현된 .NET framework의 객체들
4. 구조체가 변경된 object. (HTML DOM object)
C# 4.0의 주요한 기능은 다음과 같다.
Visual Studio 2008에서는 Targeting을 정해줄 수 있다 : .NET Framework의 종류를 지정해서 compile을 시킬 수 있다.
class AutoImplementedClass { public string Name { get; set; } public string Customer { get; private set; } }
List<int> powers = new List<int>{ 1, 2, 3, 4, 5, 6, 7 }; class Point { public int x, y; } Point point = new Point{x = 0, y = 1};
static void Main(string[] args) { var x = new {a =3 , b = 5, c ="some text"} assert.AreEqual(3, x.a) assert.AreEqual(5, x.b) assert.AreEqual("some text", x.c) }
SomeDelegate d3 = s => s.ToUpper(); SomeDelegate d4 = (string s) => {return s.ToUpper()} string a = d3("abcde")
public static class Extensions { public static int ToInt32(this string s) { return 0; } }
class Customer { public string CustomerID { get; set; } public string ContactName { get; set; } public string City { get; set; } } public class Program { static void Main(string[] args) { List<Customers> customers = LoadCustomers(); var query = from c in customers where c.City == "London" select (new {c.CustomerID, c.ContactName} ); foreach (var item in query) { Console.WriteLine(item); } } }
Windows Mobile에서는 지원하지 않음.
재미있어보이는 소스라서 들고오기.
WA_ACTIVE | 1 |
WA_CLICKACTIVE | 2 |
WA_INACTIVE | 0 |
WM_ACTIVATE | 6 |
WM_ACTIVATEAPP | 28 |
WM_AFXFIRST | 864 |
WM_AFXLAST | 895 |
WM_APP | 32768 |
WM_ASKCBFORMATNAME | 780 |
WM_CANCELJOURNAL | 75 |
WM_CANCELMODE | 31 |
WM_CAPTURECHANGED | 533 |
WM_CHANGECBCHAIN | 781 |
WM_CHAR | 258 |
WM_CHARTOITEM | 47 |
WM_CHILDACTIVATE | 34 |
WM_CLEAR | 771 |
WM_CLOSE | 16 |
WM_COMMAND | 273 |
WM_COMMNOTIFY | 68 |
WM_COMPACTING | 65 |
WM_COMPAREITEM | 57 |
WM_CONTEXTMENU | 123 |
WM_COPY | 769 |
WM_COPYDATA | 74 |
WM_CREATE | 1 |
WM_CTLCOLORBTN | 309 |
WM_CTLCOLORDLG | 310 |
WM_CTLCOLOREDIT | 307 |
WM_CTLCOLORLISTBOX | 308 |
WM_CTLCOLORMSGBOX | 306 |
WM_CTLCOLORSCROLLBAR | 311 |
WM_CTLCOLORSTATIC | 312 |
WM_CUT | 768 |
WM_DEADCHAR | 259 |
WM_DELETEITEM | 45 |
WM_DESTROY | 2 |
WM_DESTROYCLIPBOARD | 775 |
WM_DEVICECHANGE | 537 |
WM_DEVMODECHANGE | 27 |
WM_DISPLAYCHANGE | 126 |
WM_DRAWCLIPBOARD | 776 |
WM_DRAWITEM | 43 |
WM_DROPFILES | 563 |
WM_ENABLE | 10 |
WM_ENDSESSION | 22 |
WM_ENTERIDLE | 289 |
WM_ENTERMENULOOP | 529 |
WM_ENTERSIZEMOVE | 561 |
WM_ERASEBKGND | 20 |
WM_EXITMENULOOP | 530 |
WM_EXITSIZEMOVE | 562 |
WM_FONTCHANGE | 29 |
WM_GETDLGCODE | 135 |
WM_GETFONT | 49 |
WM_GETHOTKEY | 51 |
WM_GETICON | 127 |
WM_GETMINMAXINFO | 36 |
WM_GETOBJECT | 61 |
WM_GETTEXT | 13 |
WM_GETTEXTLENGTH | 14 |
WM_HANDHELDFIRST | 856 |
WM_HANDHELDLAST | 863 |
WM_HELP | 83 |
WM_HOTKEY | 786 |
WM_HSCROLL | 276 |
WM_HSCROLLCLIPBOARD | 782 |
WM_ICONERASEBKGND | 39 |
WM_IME_CHAR | 646 |
WM_IME_COMPOSITION | 271 |
WM_IME_COMPOSITIONFULL | 644 |
WM_IME_CONTROL | 643 |
WM_IME_ENDCOMPOSITION | 270 |
WM_IME_KEYDOWN | 656 |
WM_IME_KEYLAST | 271 |
WM_IME_KEYUP | 657 |
WM_IME_NOTIFY | 642 |
WM_IME_REQUEST | 648 |
WM_IME_SELECT | 645 |
WM_IME_SETCONTEXT | 641 |
WM_IME_STARTCOMPOSITION | 269 |
WM_INITDIALOG | 272 |
WM_INITMENU | 278 |
WM_INITMENUPOPUP | 279 |
WM_INPUTLANGCHANGE | 81 |
WM_INPUTLANGCHANGEREQUEST | 80 |
WM_KEYDOWN | 256 |
WM_KEYFIRST | 256 |
WM_KEYLAST | 264 |
WM_KEYUP | 257 |
WM_KILLFOCUS | 8 |
WM_LBUTTONDBLCLK | 515 |
WM_LBUTTONDOWN | 513 |
WM_LBUTTONUP | 514 |
WM_MBUTTONDBLCLK | 521 |
WM_MBUTTONDOWN | 519 |
WM_MBUTTONUP | 520 |
WM_MDIACTIVATE | 546 |
WM_MDICASCADE | 551 |
WM_MDICREATE | 544 |
WM_MDIDESTROY | 545 |
WM_MDIGETACTIVE | 553 |
WM_MDIICONARRANGE | 552 |
WM_MDIMAXIMIZE | 549 |
WM_MDINEXT | 548 |
WM_MDIREFRESHMENU | 564 |
WM_MDIRESTORE | 547 |
WM_MDISETMENU | 560 |
WM_MDITILE | 550 |
WM_MEASUREITEM | 44 |
WM_MENUCHAR | 288 |
WM_MENUCOMMAND | 294 |
WM_MENUDRAG | 291 |
WM_MENUGETOBJECT | 292 |
WM_MENURBUTTONUP | 290 |
WM_MENUSELECT | 287 |
WM_MOUSEACTIVATE | 33 |
WM_MOUSEFIRST | 512 |
WM_MOUSEHOVER | 673 |
WM_MOUSELEAVE | 675 |
WM_MOUSEMOVE | 512 |
WM_MOUSEWHEEL | 522 |
WM_MOVE | 3 |
WM_MOVING | 534 |
WM_NCACTIVATE | 134 |
WM_NCCALCSIZE | 131 |
WM_NCCREATE | 129 |
WM_NCDESTROY | 130 |
WM_NCHITTEST | 132 |
WM_NCLBUTTONDBLCLK | 163 |
WM_NCLBUTTONDOWN | 161 |
WM_NCLBUTTONUP | 162 |
WM_NCMBUTTONDBLCLK | 169 |
WM_NCMBUTTONDOWN | 167 |
WM_NCMBUTTONUP | 168 |
WM_NCMOUSEMOVE | 160 |
WM_NCPAINT | 133 |
WM_NCRBUTTONDBLCLK | 166 |
WM_NCRBUTTONDOWN | 164 |
WM_NCRBUTTONUP | 165 |
WM_NEXTDLGCTL | 40 |
WM_NEXTMENU | 531 |
WM_NOTIFY | 78 |
WM_NOTIFYFORMAT | 85 |
WM_NULL | 0 |
WM_PAINT | 15 |
WM_PAINTCLIPBOARD | 777 |
WM_PAINTICON | 38 |
WM_PALETTECHANGED | 785 |
WM_PALETTEISCHANGING | 784 |
WM_PARENTNOTIFY | 528 |
WM_PASTE | 770 |
WM_PENWINFIRST | 896 |
WM_PENWINLAST | 911 |
WM_POWER | 72 |
WM_POWERBROADCAST | 536 |
WM_PRINT | 791 |
WM_PRINTCLIENT | 792 |
WM_QUERYDRAGICON | 55 |
WM_QUERYENDSESSION | 17 |
WM_QUERYNEWPALETTE | 783 |
WM_QUERYOPEN | 19 |
WM_QUEUESYNC | 35 |
WM_QUIT | 18 |
WM_RBUTTONDBLCLK | 518 |
WM_RBUTTONDOWN | 516 |
WM_RBUTTONUP | 517 |
WM_RENDERALLFORMATS | 774 |
WM_RENDERFORMAT | 773 |
WM_SETCURSOR | 32 |
WM_SETFOCUS | 7 |
WM_SETFONT | 48 |
WM_SETHOTKEY | 50 |
WM_SETICON | 128 |
WM_SETREDRAW | 11 |
WM_SETTEXT | 12 |
WM_SETTINGCHANGE | 26 |
WM_SHOWWINDOW | 24 |
WM_SIZE | 5 |
WM_SIZECLIPBOARD | 779 |
WM_SIZING | 532 |
WM_SPOOLERSTATUS | 42 |
WM_STYLECHANGED | 125 |
WM_STYLECHANGING | 124 |
WM_SYNCPAINT | 136 |
WM_SYSCHAR | 262 |
WM_SYSCOLORCHANGE | 21 |
WM_SYSCOMMAND | 274 |
WM_SYSDEADCHAR | 263 |
WM_SYSKEYDOWN | 260 |
WM_SYSKEYUP | 261 |
WM_TCARD | 82 |
WM_TIMECHANGE | 30 |
WM_TIMER | 275 |
WM_UNDO | 772 |
WM_UNINITMENUPOPUP | 293 |
WM_USER | 1024 |
WM_USERCHANGED | 84 |
WM_VKEYTOITEM | 46 |
WM_VSCROLL | 277 |
WM_VSCROLLCLIPBOARD | 778 |
WM_WINDOWPOSCHANGED | 71 |
WM_WINDOWPOSCHANGING | 70 |
WM_WININICHANGE | 26 |
Visual Studio 2005, 2008을 설치할때마다 "이건 뭐하는 것일까.."하는 생각이 드는 내용이였는데, 잘가는 blog에서 포스팅 한 결과를 보고 구경중.
Flow chart를 그리고, 그 flow chart에 따른 코드를 넣는 것으로 모든 내용이 다 만들어지고, 그에 따른 흐름이 가능해지는 방법으로 여러가지로 살펴볼 내용들이 많다는 생각이 든다.
각 흐름에 따른 Flow를 만들어주고, 그 Flow에 맞는 code를 작성해주고..
마치 개발을 할때, PM들이 흐름도를 대강 작성하고, 프로그래머들이 코드를 채워넣기만 하면 되는 개발방향과도 너무나도 유사하게 개발을 할 수 있게 되지 않을까.. 하는 생각이 갑자기 든다.
VS2008개발 발표회때 강연자가 했던 이야기가 기억이 난다. "이렇게 편한 툴이 생긴것 자체가 개발자들에게는 악몽이 되고 있습니다. 누구나 다 개발을 할 수 있게 된다면, 우리는 이제는 필요 없게 되어버릴수도 있습니다." 약간의 엄살이 들어가 있는 이야기이긴 하지만, 왠지 모르게 많은 공감이 되고 있는 이야기들.
10월달에 볼 책이 결정이 난건가....
(SYNCmail Background worker를 이걸로 한번 만들어볼까나.)
sample code:
public sealed partial class Workflow1: SequentialWorkflowActivity
{
public string PostalCode
{
get;
set;
}
public Workflow1()
{
InitializeComponent();
}
/// <summary>
/// check code in IF-ELSE
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EvaluatiePostalCode(object sender, ConditionalEventArgs e)
{
string USCode = @"^(\d{5}$)|(\d{5}$\-\d{4}$)";
string CanadianCode = @"^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$";
e.Result = ( Regex.IsMatch(PostalCode, USCode) || Regex.IsMatch(PostalCode, CanadianCode) );
}
/// <summary>
/// method when true result from EvaluatiePostalCode
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ValidatePostalCode(object sender, EventArgs e)
{
Console.WriteLine("Right Postal code");
}
/// <summary>
/// method when false result from EvaluatiePostalCode
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void NotValidatePostalCode(object sender, EventArgs e)
{
Console.WriteLine("Wrong Postal code");
}
}
Name | Support Reliability | Default Reliability | Supports ordered | Default Ordered |
BasicHttpBinding | No | N/A | No | N/A |
NetTcpBinding | Yes | OFF | Yes | On |
NetPeerTcpBinding | No | N/A | No | N/A |
NetNamedPipeBinding | No | N/A (ON) | Yes | N/A (On) |
WSHttpBinding | Yes | Off | Yes | On |
WSFederationHttpBinding | Yes | OFF | Yes | On |
WSDualHttpBinding | Yes | On | Yes | On |
NetMsmqBinding | No | N/A | No | N/A |
MsmqIntegrationBinding | No | N/A | No | N/A |
OperationContract : 반드시 Method에서만 구현 가능하다. 이는 WCF Model에서의 제약조건으로 가지고 있으며, 동작에 의해서 구현되는 모델의 기본 사양이 된다. (property 또는 index, value에서는 절대로 구현할 수 없다.)
The endpoint is the fusion of the address, contract and binding
HTTP-GET protocol을 이용한 metadata의 제공
WebService에서의 web browser를 이용한 Method view와 비슷한 내용을 제공한다.
<client> <endpoint address="http://localhost:8000/WCFProduct" binding="basicHttpBinding" bindingConfiguration="NewBinding0" contract="WCFProduct.IProduct" name="HttpHost"> <identity> <certificateReference storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectDistinguishedName" /> </identity> </endpoint> <endpoint address="http://localhost:8000/WCFProduct" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IProduct" contract="WCFProduct.IProduct" name="BasicHttpBinding_IProduct" /> </client>
svcutil.exe http://localhost:8002/MyService /out:proxy.cs /config:app.config
//Method 1 : Declare open and close client.Open(); //Open proxy client.ListProducts(); client.Close(); //Close proxy //Method 2 : use using statement using ( client = new WCFCLient.WCFProduct.ProductClient()) { client.ListProducts(); } //Method 3 : Use IDisposable interface IDisposable disposable = client as IDisposable; if ( disposable != null ) { disposable.Dispose(); }
//Declare endpoint address with URL EndpointAddress endpointAddress = new EndpointAddress("http://localhost/WCFProduct/Service.svc"); //Declare Binding method : http, https, tcp .... WSHttpBinding wsBinding = new WSHttpBinding(); WCFProduct.ProductClient client = new WCFCLient.WCFProduct.ProductClient(wsBinding, endpointAddress);
Windows Communication Foundation was official released with .NET 3.0 a couple of months ago. For those people who're doing connected, distributed systems or are in any way interested in communication aspects of systems, this ought to be a God-send. WCF basically rolled all the different Microsoft messaging formats into one, making it extremely easy to architect the communication layer of simple to complex applications. This tutorial aims to explain the basic concepts behind the common terminology used in WCF development and design.
Below is a quick overview of the WCF architecture
WCF Programs
WCF programs are basically divided into 3 different types of programs. They are common known as
Messages
All services and clients communicate via messages, which are made up of one body, and one or more header. All WCF messages are XML formatted and transport neutral. In other words, you can specify different forms of transport (HTTP, MSMQ, Named Pipes etc) for different messages. Within each application, you can specify different messaging transport depending on the communication needs of the system. Basically, messages can be divided into
Channels
Before a client and service can talk to each other, they have to go through a channel. Imagine a channel as a pipe, with one end being the input message and the other end with the results of the message. There're different channels that can be stacked onto each other, they are commonly known as Channel Stacks. They can be of these different types:
The way in which messages are sent through the pipe (Channel) is known as a Transport and they way at which they are encoded are known as Encodings. Transport can be made up of the following: