-
Notifications
You must be signed in to change notification settings - Fork 0
/
internals.htm
228 lines (185 loc) · 11 KB
/
internals.htm
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="generator" content="Bootply" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>Pomona - Contributors guide
</title>
<link href="content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="content/prism.css" rel="stylesheet" type="text/css" />
<link href="content/theme.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
<link rel="apple-touch-icon" href="/bootstrap/img/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="/bootstrap/img/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="/bootstrap/img/apple-touch-icon-114x114.png">
<!-- CSS code from Bootply.com editor -->
<link href="content/affix.css" rel="stylesheet" type="text/css" />
</head>
<!-- HTML code from Bootply.com editor -->
<body>
<a href="https://github.com/Pomona/Pomona"><img style="z-index: 5000; position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67"
alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
<nav class="navbar navbar-default navbar-fixed-top" role="banner">
<div class="container">
<div class="navbar-header">
<a href="index.htm" class="navbar-brand">Pomona</a>
</div>
<nav class="collapse navbar-collapse" role="navigation">
<ul class="nav navbar-nav pull-right">
<li>
<a href="https://ci.appveyor.com/project/Pomona/pomona/branch/master"><img src="https://camo.githubusercontent.com/292475f55ea801049dca2b513810703735ccebce/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f766a33637734396e34393975363034362f6272616e63682f6d61737465723f7376673d74727565"
alt="Build Status" data-canonical-src="https://ci.appveyor.com/api/projects/status/vj3cw49n499u6046/branch/master?svg=true" style="max-width:100%;"></a>
</li>
<li>
<a href="https://travis-ci.org/Pomona/Pomona"><img src="https://camo.githubusercontent.com/b95255081c0290893d299b926d4bd29dca156ffd/68747470733a2f2f7472617669732d63692e6f72672f506f6d6f6e612f506f6d6f6e612e7376673f6272616e63683d6d6173746572" alt="Build Status" data-canonical-src="https://travis-ci.org/Pomona/Pomona.svg?branch=master"
style="max-width:100%;"></a>
</li>
<li>
<a href="https://gitter.im/Pomona/Pomona?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://camo.githubusercontent.com/da2edb525cde1455a622c58c0effc3a90b9a181c/68747470733a2f2f6261646765732e6769747465722e696d2f4a6f696e253230436861742e737667" alt="Join the chat at https://gitter.im/Pomona/Pomona" data-canonical-src="https://badges.gitter.im/Join%20Chat.svg"
style="max-width:100%;"></a>
</li>
<li><a href="https://www.nuget.org/packages/Pomona/"><img src="https://img.shields.io/nuget/v/Pomona.svg" alt="Nuget package" /></a></li>
<li><a href="generated_client.htm" title="Generated client">Previous</a></li>
</ul>
<div class="navbar-form navbar-left" role="search">
<div class="form-group">
<input id="search" type="search" class="form-control" placeholder="Search">
</div>
</div>
</nav>
</div>
</nav>
<div class="container">
<nav class="navbar">
<ol class="breadcrumb"><li><a href="index.htm">Pomona</a></li><li class="active">Contributors guide</li></ol>
</nav>
</div>
<!--main-->
<div class="container">
<div class="row">
<!--left-->
<div class="col-md-3" id="leftCol">
<ul class="nav nav-stacked affix" id="sidebar">
<li>
<h3><img src="/content/images/pomona-icon-210.png" width="210" height="210" alt="Pomona " /></h3></li>
<li>
</li>
<li>
<h3 class="no-margin">Previous</h3><a href="generated_client.htm">Generated client</a></p></li>
</ul>
</div>
<!--/left-->
<!--right-->
<div class="col-md-9">
<h1>Contributors guide <a href="https://github.com/Pomona/Pomona/blob/develop/documentation/internals.md" class="text-muted small pull-right fa fa-github" style="margin-top: 10px"> Edit on GitHub</a></h1>
<hr />
<div id="main-pane">
<!--Title:Contributors guide-->
<!--Url:internals-->
<h1>Building Pomona</h1>
<p>You can build Pomona using Visual Studio 2015 or Mono (4.2.3+).</p>
<p>Only standard .NET 4.5.1 assemblies need to be installed, all other
assemblies is included in the repository or will be restored by nuget.</p>
<h1>Design</h1>
<p>Pomona was built from the bottom up. If some architectural decisions
might seem arbitrary, it's probably because they are.</p>
<h2>Architecture</h2>
<h5><strong>Pomona architecture diagram</strong></h5><img src="content/diagrams/pomona_architecture.png" style="max-width:100%" />
<h2>Request lifecycle</h2>
<h5><strong>Code path of request</strong></h5><img src="content/diagrams/request_code_path.png" style="max-width:100%" />
<h2>Routing</h2>
<p>During early stages of Pomona development the intention was to let Nancy
handle the routing. Unfortunately we ran into some corner cases related to
child resource sets which was hard to fix.</p>
<p>As a result Pomona now has its own routing logic, inside the <code>Pomona.Routing</code>
namespace. The routes are organized as a tree with the <code>Route</code> class as the
base node type.</p>
<h3>Route node types</h3>
<ul>
<li><code>DataSourceRootRoute</code> - Default root <code>/</code> route, listing all root resources</li>
<li><code>DataSourceCollectionRoute</code> - Route to collection of a root resource type, like <code>/customers</code></li>
<li><code>GetByIdRoute</code> - Route to an identified item in a collection, like <code>/customers/{id}</code></li>
<li><code>ResourcePropertyRoute</code> - Route to a child resource collection bound to a property
of another resource, like <code>/customers/{id}/contacts</code></li>
</ul>
<h2>Queries</h2>
<h3>Expression parsing</h3>
<p><code>QueryExpressionParser</code> will orchestrate the conversion of an expression as
a string to a LINQ expression tree in the following way:</p>
<p>The lexing and parsing of an expression is performed using an ANTLR 3
compatible grammar named <code>PomonaQueryParser</code>. This grammar will create an initial
<a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">abstract syntax tree</a> .</p>
<p>The tree will then be transformed in <code>PomonaQueryTreeParser</code> to an intermediate form,
with more semantic information and error checking.</p>
<p>Finally <code>NodeTreeToExpressionConverter</code> will convert the intermediate tree to a LINQ
<code>Expression</code>.</p>
<h2>Type mapping</h2>
<p>Pomona has its own type system, which mirrors the CLR types combined with
Pomona-specific mapping details and metadata.</p>
<p>Here's some different types of type specs (...)</p>
<ul>
<li><code>RuntimeTypeSpec</code>: For shared and primitive types, also the base class for other type specs</li>
<li><code>ResourceType</code>: For structured types exposed at an URI as a resource</li>
<li><code>ComplexType</code>: For structured types with no URI, can be inlined in other objects</li>
<li><code>EnumerableTypeSpec</code>: Sequences and collections</li>
<li><code>AnonymousType</code>: For anonymous types generated by C# compiler</li>
</ul>
<p>By default most primitive types maps to <code>RuntimeTypeSpec</code>, and types implementing
the IEnumerable<T> interface maps to <code>EnumerableTypeSpec</code>.</p>
<p>All types specified in <code>SourceTypes</code> property of the <code>PomonaConfigurationBase</code> will
be mapped to <code>ResourceType</code> by default.</p>
<p>This behavior can be changed through either <a href="configuration/convention.htm">Changing conventions</a> or
<a href="configuration/rules.htm">Fluent rules</a>.</p>
<h3>Querying the type system</h3>
<p>Usually an end-user application will not need to touch the Pomona type system,
so the information below is mostly for corner cases and contributors.</p>
<h3>Converting from and to System.Type</h3>
<p>A <code>TypeSpec</code> can be converted to its wrapped <code>System.Type</code> by either explicit
or implicit casting.</p>
<p>To get a <code>TypeSpec</code> from a <code>System.Type</code> we need to use the <code>FromType</code> method
of the <code>ITypeResolver</code> interface.</p>
<h1>Ideas for future changes</h1>
<h2>Root resource</h2>
<p>For a long time the plan has been to abandon the <code>IPomonaDataSource</code> interface, and
instead rely on having a root resource with navigation properties to all root resources.</p>
</div>
<hr />
<nav>
<span>
<strong>Previous: </strong><a href="generated_client.htm">Generated client</a>
</span>
<span class="pull-right">
</span>
</nav>
</div>
<!--/right-->
</div>
<!--/row-->
<footer><p><small><i>Documentation created using <a href="https://storyteller.github.io/">Storyteller</a></i></small></p></footer>
</div>
<!--/container-->
</body>
<foot>
<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="content/prism.js"></script>
<script type="text/javascript" src="content/sidebar.js"></script>
<script type="text/javascript" src="content/affix.js"></script>
<script>
$('#search').keyup(function(e) {
if (e.keyCode == 13) {
var search = $('#search').val();
var url = 'https://www.google.com/#q=site:pomona.io ' + search;
url = encodeURI(url);
//alert(url);
window.location.href = url;
e.stopPropagation();
if (e.cancelBubble != null) e.cancelBubble = true;
return false;
}
});
</script>
</foot>
</html>