-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDemoNotes.txt
186 lines (106 loc) · 12.2 KB
/
DemoNotes.txt
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
Dynamisch und gefährlich?
C# Dynamics in freier Wildbahn
Seit der Einführung des "dynamic" Schlüsselworts in der 4.0-Version von C# streitet sich die .NET-Community zwischen "böse und gefährlich" und "praktisch und cool". Von ASP.NET ViewBags, ExpandoObjects, ElasticObjects, JSON Parser mit ExpandoObjects oder NancyFx Model Objekte bis Simple.Data und Oak's Gemini Bindings, dieses Vortrag wird böse dynamische Konstrukte unter die Lupe nehmen, die in unserer stark typisierten .NET-Welt nicht nur Sinn haben sondern von echtem Vorteil sind.
http://www.herbstcampus.de/hc13/program/sessions.html#13
------------------------------------------------------------
<intro>I've heard more than once that hell will simply break loose if somebody uses the C# keyword "dynamic". Another interpretation of the same rule says that god will kill a kitten for each usage... and if I'm not that scared of the first one... kittens... damn. To be honest, since its introduction (2009) in the 4th version of the .NET Framework, I tried to spare the lovely kittens... until last year. Since then, if those balls of fur really do get in trouble when I use dynamics ; well, I'm going to be in trouble with the PETA very soon.</intro>
Let's backtrack a little bit. C# is a statically typed language, so what's that 'dynamic' I'm talking about?
C# is indeed a statically typed language. The language expresses type restrictions that can be verified and validated at compile time. For example, the following code does not compile. The compiler notices that the "++" operator cannot be applied to operands of type 'string' and throws an error:
string lang = "C#";
lang++;
Similarly, unless we define such an extension function, the following will not compile either since the compiler will not find any definition of a 'ToUpper' method accepting a first argument of type 'int':
int zeAnswer = 42;
zeAnswer.ToUpper();
Now try replacing the 'string' and 'int' types with 'dynamic' and you should notice the compiler instantly smiling back at you with no errors to notify. With dynamic typing, the type-safety is determined at runtime. Thus, if the examples above compile, they will also spectacularly crash once you try to execute them anyway.
<h1>Why do we have a "dynamic" keyword in C# then?</h1>
Let's consider the following examples[scotthanselmansblogpost]:
Calculator calc = GetCalculator();
int sum = calc.Add(10, 20);
What about using the type 'object' instead of Calulator? In this case, the compiler does not know that an "Add" function exists, thus cannot allow us to call it. We have to use reflection to get to the member and invoke it, using that way less clean syntax below:
object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
The 'Add' function is there. So if we could bypass the compile time check, we know the application would behave fine at runtime. Using a dynamic makes this possible:
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
The Dynamic Language Runtime (DLC) basically allows other languages like IronPython or IronRuby to talk to the Common Language Runtime (CLR). This keyword was specifically introduced to enable that behavior.
In addition to losing the compile time type checks, using dynamics comes with another drawback (some might argue that it's actually an advantage): the compiler cannot infer what methods and properties you can use, and thus prevents the usage of a code completion tool like IntelliSense[].
<h1>So why bother?</h1>
I know what you're thinking: this is neither new nor really exciting so why bother writing an article about it? And you would be right if it stopped there. Dynamics can be very useful in interoperability cases but the use of that naked 'dynamic' keyword doesn't make much sense outside those boundaries.
Users of ASP.NET MVC experienced a first use of that dynamic power under the hood of the 'ViewBag'. Lately, some Frameworks or tools like 'Simple.Data' or 'Oak' started using dynamics publicly and extensively (poor kittens). So there seems to be something to it ; that's why. So let's digg deeper in those usages and structures.
<h1>The basics</h1>
<h2>DynamicObject</h2>
The System.Dynamic.DynamicObject is the base class for all those behaviors. As described previously, a DynamicObject exposes members at run time instead of at compile time. Among others, it has three important functions that you can override:
* The TrySetMember
* The TryGetMember method is called when a member of a dynamic class is requested and no arguments are specified. Ex: 'myDynamicObject.Property'.
* The TryInvokeMember method is called when a member of a dynamic class is requested with arguments. Ex: 'myDynamicObject.Function()'.
<h2>ExpandoObject</h2>
The System.Dynamic.ExpandoObject represents an object whose members can be dynamically added and removed at run time.
dynamic myExpandoObject = new ExpandoObject();
myExpandoObject.number = 10; //Add a property
myExpandoObject.Increment = (Action)(() => { myExpandoObject.number++; }); //Add a function via a lambda expression
Console.WriteLine(sampleObject.number); //Prints 10
sampleObject.Increment(); //Call the function
Console.WriteLine(sampleObject.number); //Prints 11
Note how I used 'dynamic' to declare myExpandoObject. If I had used "ExpandoObject" or even "var", the object would then be statically typed and 'myExpandoObject.number' would not compile anymore.
The ViewBag used in ASP.NET MVC is very similar in behavior to the ExpandoObject. As a matter of fact, most of the time, the ExpandoObjects are used as a property-bag, like a wild Dictionary<string, object> or strange Hashtable. Those usages can already be very interesting. Alexandra Rusina[http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx] described for example how it can simplify access to XML documents.
But even more interesting are the facts that the ExpandoObject also implements the INotifyPropertyChanged and can host events directly as properties.
<h2>ElasticObject</h2>
The ElasticObject[http://elasticobject.codeplex.com/], as a smart cousin (sic) of the ExpandoObject, goes a bit further. Where the ExpandoObject supports only one level, the ElasticObject supports the direct creation of hierarchical dynamic data structure and dynamic collections for instance. It also supports direct to XML and to Elastic conversions.
//No need to define "Customer first"
customerBaseElastic.Customer.FirstName = "Bob";
var p1 = store.Products.Product(); //The '()' acts as a factory
p1.Name = "Acme Floor Cleaner";
var p2 = store.Products.Product();
p1.Name = "Acme Bun";
//Elastic -> XML
XElement element = store > FormatType.XML;
//XML -> Elastic
dynamic elasticStore = element.ToElastic();
<h2>Pre-Conclusion</h2>
The DynamicObjects, ExpandoObjects and ElasticObjects are in fact nothing new. Introduced in 2009 and blogged about right away, it's really history. What interests me more is the fact that after barely hearing from dynamics for a few years (other than to warn about kittens of hell), I saw a few projects pop-up in the end of 2011 and 2012 that brought back the use of dynamics, namely NancyFx, Oak and Simple.Data.
<h1>Discoverability</h1>
One
<h1>NancyFx</h1>
Nancy is a Micro-Webframework. Its goal is to provide a lightweight and low-ceremony way of serving web pages (per opposition to ASP.NET MVC which tends to do everything and its contrary). Nancy is ready-to-go out of the box and can be extended when needed.
When you define a "route", Nancy will capture parameters for you and serve them up using a dynamic object. For instance the route below will be activated for a HTTP-GET Request on the "/hello/bob" or "/hello/nancy" URIs. Nancy will then capture the "bob" and "nancy" parameters and pack them up in the dynamic dictionary represented by the variable "parameters".
Get["/hello/{name}"] = parameters => {
return "Hello " + parameters.name;
};
This use of a dynamic is very smart. Nancy has many ways to capture parameters (query string, captured parameters & body of the request) and can capture any kind of data, thus packing them in a dynamic object drastically reduces the complexity of the binding the framework has to offer. Furthermore, since the definition of the ".name" value and its usage are beside one another, there is no discoverability problem in this case. Still, it is not easy to see what's in the parameters variable ; you'd better know it once designing the application. For instance if a query string was also passed "/hello/nancy?option=default", it is not easy to know that this "option" is also available.
Nancy also uses dynamics in the objects returned by the routes. #########
<h1>Oak's Gemini</h1>
Oak is an open-source framework that attempts to disrupt the process of Single Page Application (SPA) development in the .NET space. It tries to bridge the gap between C# and Javascript by many means and ease the general development livecycle imitating some Rails / node.js development tools. Among others, Oak makes heavy use of a self-written component called 'Gemini' that brings some capabilities of dynamic type systems to C#. A Gemini object is able to create properties on the fly, define functions and supports introspection. All in all, it could be seen as a cherry-picked subset of the Dynamic/Expando/Elastic-Objects with introspection on top.
Again, it is for model-binding that Oak uses Gemini the most. For passing data in and out of his models from and toward the views. But also as a key component for accessing its databases, converting Json data and so on.
<h1>Simple.Data</h1>
Simple.Data takes another approach. Making an extensive use of the TryGetMember function, it allows the on-the-fly definition of Query-Like structures to manipulate Databases using a syntax much closer to human-language than any other query mean. For example, the following query (where "database" is a dynamic type) would produce a "SELECT * FROM Customers WHERE CustomerId = 3" query: "database.Customers.FindAllByCustomerId(3);". The strength of Simple.Data is to combine objects, commands and data in a very readable way.
Most of Simple.Data's classes extend the DynamicObject and uses regexes to parse the called members in the TryGetMember functions. Providing a relatively small set of commands (Find, FindAllByXXX, OrderByXXX, Select, WithXXX, Where etc.) Simple.Data provides an extremely rich O/RM API without the hurdle of a mapping configuration and SQL statements.
<h1>Conclusion</h1>
We've seen a few interesting "alternative" usages.
------------------------------------------------------------
"The dynamic keyword is important when using these kinds of objects in that it tells to compiler to bind the method calls at runtime rather than compile time"
------------------------------------------------------------
Dynamic Basics
Source: http://www.hanselman.com/blog/C4AndTheDynamicKeywordWhirlwindTourAroundNET4AndVisualStudio2010Beta1.aspx
Basics on the ExpandoObject
http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx
http://www.codeproject.com/Articles/62839/Adventures-with-C-4-0-dynamic-ExpandoObject-Elasti
Unusual use of ExpandoObject
http://reedcopsey.com/2009/11/06/unusual-uses-of-expandoobject-in-c-4/
ElasticObject
http://www.amazedsaint.com/2010/02/introducing-elasticobject-for-net-40.html?m=1
Oak-Gemini
https://github.com/amirrajan/Oak/wiki/Gemini-First-Look
http://amirrajan.github.io/Oak/
Simple.Data
https://github.com/markrendle/Simple.Data
------------------------------------------------------------
http://www.codeproject.com/Articles/593881/What-is-the-difference-between
http://stackoverflow.com/questions/15338429/c-sharp-dynamic-type-gotcha
http://stackoverflow.com/questions/13193799/performance-cost-of-using-dynamic-typing-in-net
http://www.codetails.com/punitganshani/complete-guide-to-dynamic-keyword-in-c/20130330
http://sinairv.wordpress.com/2012/07/23/an-example-for-c-dynamic-in-action/
http://www.felienne.com/?p=698
http://tech.collectedit.com/post/2012/08/20/Using-C-dynamic-objects-to-perform-runtime-text-templates.aspx
http://counsellingbyabhi.blogspot.de/2013/03/difference-between-var-object-and.html