<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:georss="http://www.georss.org/georss" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">
  <channel>
    <title>Nesterovsky bros - Tips and tricks</title>
    <link>http://www.nesterovsky-bros.com/weblog/</link>
    <description />
    <language>en-us</language>
    <copyright>Nesterovsky bros</copyright>
    <lastBuildDate>Fri, 26 Jan 2024 13:27:16 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.12105.0</generator>
    <managingEditor>contact@nesterovsky-bros.com</managingEditor>
    <webMaster>contact@nesterovsky-bros.com</webMaster>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=371a8329-d392-4d20-bcbc-db9503816f26</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=371a8329-d392-4d20-bcbc-db9503816f26</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h4>Introduction
</h4>
        <p>
We migrate code out of MF to Azure. Tool we use produces plain good functionally equivalent
C# code. But it turns it's not enough!
</p>
        <p>
So, what's the problem?
</p>
        <p>
Converted code is very slow, especially for batch processing, where MF completes job,
say in 30 minutes, while converted code finishes in 8 hours.
</p>
        <p>
At this point usually someone appears and whispers in the ear:
</p>
        <blockquote>
          <p>
Look, those old technologies are proven by the time. It worth to stick to old good
Cobol, or better to Assembler if you want to do the real thing.
</p>
        </blockquote>
        <p>
We're curious though: why is there a difference?
</p>
        <p>
Turns out the issue lies in differences of network topology between MF and Azure solutions.
On MF all programs, database and file storage virtually sit in a single box, thus
network latency is negligible. 
</p>
        <p>
It's rather usual to see chatty SQL programs on MF that are doing a lot of small
SQL queries.
</p>
        <p>
In Azure - programs, database, file storage are different services most certainly
sitting in different phisical boxes. You should be thankfull if they are co-located
in a single datacenter. So, network latency immediately becomes a factor. Even if
it just adds 1 millisecond per SQL roundtrip, it adds up in loops, and turns in the
showstopper.
</p>
        <p>
There is no easy workaround on the hardware level.
</p>
        <p>
People advice to write programs differently: "<a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/performance-guidance">Tune
applications and databases for performance in Azure SQL Database</a>".
</p>
        <p>
That's a good advice for a new development but discouraging for migration done
by a tool.
</p>
        <p>
So, what is the way forward?
</p>
        <p>
Well, there is one. While accepting weak sides of Azure we can exploit its strong
sides.
</p>
        <h4>Parallel refactoring
</h4>
        <p>
Before continuing let's consider a <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/SerialProcessor.cs#L5-L29">code</a> demoing
the problem:
</p>
        <pre>
          <code class="lang-C#">
            <span class="hljs-keyword">public</span>
            <span class="hljs-literal">void</span> CreateReport(StringWriter
writer) { <span class="hljs-built_in">var</span> index = <span class="hljs-number">0</span>;
foreach(<span class="hljs-built_in">var</span> transaction <span class="hljs-keyword">in</span> dataService.
GetTransactions(). OrderBy(item =&gt; (item.At, item.SourceAccountId))) { <span class="hljs-built_in">var</span> sourceAccount
= dataService.GetAccount(transaction.SourceAccountId); <span class="hljs-built_in">var</span> targetAccount
= transaction.TargetAccountId != <span class="hljs-built_in">null</span> ? dataService.GetAccount(transaction.TargetAccountId)
: <span class="hljs-built_in">null</span>; ++index; <span class="hljs-keyword">if</span> (index
% <span class="hljs-number">100</span> == <span class="hljs-number">0</span>) { Console.WriteLine(index);
} writer.WriteLine($<span class="hljs-string">"{index},{transaction.Id},{ transaction.At},{transaction.Type},{transaction.Amount},{
transaction.SourceAccountId},{sourceAccount?.Name},{ transaction.TargetAccountId},{targetAccount?.Name}"</span>);
} } </code>
        </pre>
        <p>
This cycle queries transactions, along with two more small queries to get source and
target accounts for each transaction. Results are printed into a report.
</p>
        <p>
If we assume query latency just 1 millisecond, and try to run such code for 100K transactions
we easily come to 200+ seconds of execution. 
</p>
        <p>
Reality turns to be much worse. Program spends most of its lifecycle waiting for database
results, and iterations don't advance until all work of previous iterations is
complete.
</p>
        <p>
We could do better even without trying to rewrite all code! Let's articulate our
goals:
</p>
        <ol>
          <li>
To make code fast.</li>
          <li>
To leave code recognizable.</li>
        </ol>
        <p>
The idea is to form two processing pipelines:
</p>
        <ul>
          <li>
(a) one that processes data in parallel out of order;</li>
          <li>
(b) other that processes data serially, in original order;</li>
        </ul>
        <p>
Each pipeline may post sub-tasks to the other, so (a) runs its tasks in parallel unordered,
while (b) runs its tasks as if everything was running serially.
</p>
        <p>
So, parallel plan would be like this:
</p>
        <ol>
          <li>
Queue parallel sub-tasks (a) for each transaction.</li>
          <li>
Parallel sub-task in (a) reads source and target accounts, and queues serial sub-task
(b) passing transaction and accounts.</li>
          <li>
Serial sub-task (b) increments index, and writes report record.</li>
          <li>
Wait for all tasks to complete.</li>
        </ol>
        <p>
To reduce burden of task piplelines we use <a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library">Dataflow
(Task Parallel Library)</a>, and encapsulate everything in a small wrapper.
</p>
        <p>
Consider refactored <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/ParallelProcessor.cs#L14-L48">code</a>:
</p>
        <pre>
          <code class="lang-C#">
            <span class="hljs-keyword">public</span>
            <span class="hljs-literal">void</span> CreateReport(StringWriter
writer) { using <span class="hljs-built_in">var</span> parallel = <span class="hljs-literal">new</span> Parallel(options.Value.Parallelism); <span class="hljs-comment">//
⬅️ 1</span><span class="hljs-built_in">var</span> index = <span class="hljs-number">0</span>;
parallel.ForEachAsync( <span class="hljs-comment">// ⬅️ 2</span> dataService. GetTransactions().
OrderBy(item =&gt; (item.At, item.SourceAccountId)), transaction =&gt; <span class="hljs-comment">//
⬅️ 3</span> { <span class="hljs-built_in">var</span> sourceAccount = dataService.GetAccount(transaction.SourceAccountId); <span class="hljs-built_in">var</span> targetAccount
= transaction.TargetAccountId != <span class="hljs-built_in">null</span> ? dataService.GetAccount(transaction.TargetAccountId)
: <span class="hljs-built_in">null</span>; parallel.PostSync( <span class="hljs-comment">//
⬅️ 4</span> (transaction, sourceAccount, targetAccount), <span class="hljs-comment">//
⬅️ 5</span><span class="hljs-built_in">data</span> =&gt; { <span class="hljs-built_in">var</span> (transaction,
sourceAccount, targetAccount) = <span class="hljs-built_in">data</span>; <span class="hljs-comment">//
⬅️ 6</span> ++index; <span class="hljs-keyword">if</span> (index % <span class="hljs-number">100</span> == <span class="hljs-number">0</span>)
{ Console.WriteLine(index); } writer.WriteLine($<span class="hljs-string">"{index},{transaction.Id},{
transaction.At},{transaction.Type},{transaction.Amount},{ transaction.SourceAccountId},{sourceAccount?.Name},{
transaction.TargetAccountId},{targetAccount?.Name}"</span>); }); }); } </code>
        </pre>
        <p>
Consider ⬅️ points:
</p>
        <ol>
          <li>
We create <code>Parallel</code> utility class passing degree of parallelism requested.</li>
          <li>
We iterate transactions using <code>parallel.ForEachAsync()</code> that queues parallel
sub-tasks for each transaction, and then waits until all tasks are complete.</li>
          <li>
Each parallel sub-task recieves a transaction. It may be called from a different thread.</li>
          <li>
Having recieved required accounts we queue a sub-task for synchronous execution using <code>parallel.PostSync()</code>,
and</li>
          <li>
Pass there data collected in parallel sub-task: transaction and accounts.</li>
          <li>
We deconstruct data passed into variables, and then proceed with serial logic.</li>
        </ol>
        <p>
What we achieve with this refactoring:
</p>
        <ol>
          <li>
Top level query that brings transactions is done and iterated serially.</li>
          <li>
But each iteration body is run in parallel. By default we set it up to allow up to
100 parallel executions. All those parallel sub-task do not wait on each other so
their waitings do not add up.</li>
          <li>
Sync sub-tasks are queued and executed in order of their serial appearance, so increments
and report records are not a subject of race conditions, nor a subject of reordering
of output records.</li>
        </ol>
        <p>
We think that such refactored code is still recognizible.
</p>
        <p>
As for performance this is what log shows:
</p>
        <pre>
          <code class="lang-log">
            <span class="hljs-selector-tag">Serial</span>
            <span class="hljs-selector-tag">test</span> 100
... <span class="hljs-selector-tag">Execution</span><span class="hljs-selector-tag">time</span>:
00<span class="hljs-selector-pseudo">:01</span><span class="hljs-selector-pseudo">:33.8152540</span><span class="hljs-selector-tag">Parallel</span><span class="hljs-selector-tag">test</span> 100
... <span class="hljs-selector-tag">Execution</span><span class="hljs-selector-tag">time</span>:
00<span class="hljs-selector-pseudo">:00</span><span class="hljs-selector-pseudo">:05.8705468</span></code>
        </pre>
        <h4>Reference
</h4>
        <p>
Please take a look at project to understand implementation details, and in particular <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/Parallel.cs"><code>Parallel</code></a> class
implementing API to post parallel and serial tasks, run cycles and some more.
</p>
        <p>
Please continue reading on <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master?tab=readme-ov-file#parallel-refactoring">GitHub</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=371a8329-d392-4d20-bcbc-db9503816f26" />
      </body>
      <title>Experience of parallel refactoring</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2024/01/26/ExperienceOfParallelRefactoring.aspx</link>
      <pubDate>Fri, 26 Jan 2024 13:27:16 GMT</pubDate>
      <description>&lt;h4&gt;Introduction
&lt;/h4&gt;
&lt;p&gt;
We migrate code out of MF to Azure. Tool we use produces plain good functionally equivalent
C# code. But it turns it&amp;#39;s not enough!
&lt;/p&gt;
&lt;p&gt;
So, what&amp;#39;s the problem?
&lt;/p&gt;
&lt;p&gt;
Converted code is very slow, especially for batch processing, where MF completes job,
say in 30 minutes, while converted code finishes in 8 hours.
&lt;/p&gt;
&lt;p&gt;
At this point usually someone appears and whispers in the ear:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Look, those old technologies are proven by the time. It worth to stick to old good
Cobol, or better to Assembler if you want to do the real thing.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
We&amp;#39;re curious though: why is there a difference?
&lt;/p&gt;
&lt;p&gt;
Turns out the issue lies in differences of network topology between MF and Azure solutions.
On MF all programs, database and file storage virtually sit in a single box, thus
network latency is negligible. 
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s rather usual to see chatty SQL programs on MF that are doing a lot of small
SQL queries.
&lt;/p&gt;
&lt;p&gt;
In Azure - programs, database, file storage are different services most certainly
sitting in different phisical boxes. You should be thankfull if they are co-located
in a single datacenter. So, network latency immediately becomes a factor. Even if
it just adds 1 millisecond per SQL roundtrip, it adds up in loops, and turns in the
showstopper.
&lt;/p&gt;
&lt;p&gt;
There is no easy workaround on the hardware level.
&lt;/p&gt;
&lt;p&gt;
People advice to write programs differently: &amp;quot;&lt;a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/performance-guidance"&gt;Tune
applications and databases for performance in Azure SQL Database&lt;/a&gt;&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s a good advice for a new development but discouraging for migration done
by a tool.
&lt;/p&gt;
&lt;p&gt;
So, what is the way forward?
&lt;/p&gt;
&lt;p&gt;
Well, there is one. While accepting weak sides of Azure we can exploit its strong
sides.
&lt;/p&gt;
&lt;h4&gt;Parallel refactoring
&lt;/h4&gt;
&lt;p&gt;
Before continuing let&amp;#39;s consider a &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/SerialProcessor.cs#L5-L29"&gt;code&lt;/a&gt; demoing
the problem:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-C#"&gt; &lt;span class="hljs-keyword"&gt;public&lt;/span&gt; &lt;span class="hljs-literal"&gt;void&lt;/span&gt; CreateReport(StringWriter
writer) { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; index = &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
foreach(&lt;span class="hljs-built_in"&gt;var&lt;/span&gt; transaction &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; dataService.
GetTransactions(). OrderBy(item =&amp;gt; (item.At, item.SourceAccountId))) { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; sourceAccount
= dataService.GetAccount(transaction.SourceAccountId); &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; targetAccount
= transaction.TargetAccountId != &lt;span class="hljs-built_in"&gt;null&lt;/span&gt; ? dataService.GetAccount(transaction.TargetAccountId)
: &lt;span class="hljs-built_in"&gt;null&lt;/span&gt;; ++index; &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (index
% &lt;span class="hljs-number"&gt;100&lt;/span&gt; == &lt;span class="hljs-number"&gt;0&lt;/span&gt;) { Console.WriteLine(index);
} writer.WriteLine($&lt;span class="hljs-string"&gt;"{index},{transaction.Id},{ transaction.At},{transaction.Type},{transaction.Amount},{
transaction.SourceAccountId},{sourceAccount?.Name},{ transaction.TargetAccountId},{targetAccount?.Name}"&lt;/span&gt;);
} } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
This cycle queries transactions, along with two more small queries to get source and
target accounts for each transaction. Results are printed into a report.
&lt;/p&gt;
&lt;p&gt;
If we assume query latency just 1 millisecond, and try to run such code for 100K transactions
we easily come to 200+ seconds of execution. 
&lt;/p&gt;
&lt;p&gt;
Reality turns to be much worse. Program spends most of its lifecycle waiting for database
results, and iterations don&amp;#39;t advance until all work of previous iterations is
complete.
&lt;/p&gt;
&lt;p&gt;
We could do better even without trying to rewrite all code! Let&amp;#39;s articulate our
goals:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
To make code fast.&lt;/li&gt;
&lt;li&gt;
To leave code recognizable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The idea is to form two processing pipelines:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
(a) one that processes data in parallel out of order;&lt;/li&gt;
&lt;li&gt;
(b) other that processes data serially, in original order;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Each pipeline may post sub-tasks to the other, so (a) runs its tasks in parallel unordered,
while (b) runs its tasks as if everything was running serially.
&lt;/p&gt;
&lt;p&gt;
So, parallel plan would be like this:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Queue parallel sub-tasks (a) for each transaction.&lt;/li&gt;
&lt;li&gt;
Parallel sub-task in (a) reads source and target accounts, and queues serial sub-task
(b) passing transaction and accounts.&lt;/li&gt;
&lt;li&gt;
Serial sub-task (b) increments index, and writes report record.&lt;/li&gt;
&lt;li&gt;
Wait for all tasks to complete.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
To reduce burden of task piplelines we use &lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library"&gt;Dataflow
(Task Parallel Library)&lt;/a&gt;, and encapsulate everything in a small wrapper.
&lt;/p&gt;
&lt;p&gt;
Consider refactored &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/ParallelProcessor.cs#L14-L48"&gt;code&lt;/a&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-C#"&gt; &lt;span class="hljs-keyword"&gt;public&lt;/span&gt; &lt;span class="hljs-literal"&gt;void&lt;/span&gt; CreateReport(StringWriter
writer) { using &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; parallel = &lt;span class="hljs-literal"&gt;new&lt;/span&gt; Parallel(options.Value.Parallelism); &lt;span class="hljs-comment"&gt;//
⬅️ 1&lt;/span&gt; &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; index = &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
parallel.ForEachAsync( &lt;span class="hljs-comment"&gt;// ⬅️ 2&lt;/span&gt; dataService. GetTransactions().
OrderBy(item =&amp;gt; (item.At, item.SourceAccountId)), transaction =&amp;gt; &lt;span class="hljs-comment"&gt;//
⬅️ 3&lt;/span&gt; { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; sourceAccount = dataService.GetAccount(transaction.SourceAccountId); &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; targetAccount
= transaction.TargetAccountId != &lt;span class="hljs-built_in"&gt;null&lt;/span&gt; ? dataService.GetAccount(transaction.TargetAccountId)
: &lt;span class="hljs-built_in"&gt;null&lt;/span&gt;; parallel.PostSync( &lt;span class="hljs-comment"&gt;//
⬅️ 4&lt;/span&gt; (transaction, sourceAccount, targetAccount), &lt;span class="hljs-comment"&gt;//
⬅️ 5&lt;/span&gt; &lt;span class="hljs-built_in"&gt;data&lt;/span&gt; =&amp;gt; { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; (transaction,
sourceAccount, targetAccount) = &lt;span class="hljs-built_in"&gt;data&lt;/span&gt;; &lt;span class="hljs-comment"&gt;//
⬅️ 6&lt;/span&gt; ++index; &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (index % &lt;span class="hljs-number"&gt;100&lt;/span&gt; == &lt;span class="hljs-number"&gt;0&lt;/span&gt;)
{ Console.WriteLine(index); } writer.WriteLine($&lt;span class="hljs-string"&gt;"{index},{transaction.Id},{
transaction.At},{transaction.Type},{transaction.Amount},{ transaction.SourceAccountId},{sourceAccount?.Name},{
transaction.TargetAccountId},{targetAccount?.Name}"&lt;/span&gt;); }); }); } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Consider ⬅️ points:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We create &lt;code&gt;Parallel&lt;/code&gt; utility class passing degree of parallelism requested.&lt;/li&gt;
&lt;li&gt;
We iterate transactions using &lt;code&gt;parallel.ForEachAsync()&lt;/code&gt; that queues parallel
sub-tasks for each transaction, and then waits until all tasks are complete.&lt;/li&gt;
&lt;li&gt;
Each parallel sub-task recieves a transaction. It may be called from a different thread.&lt;/li&gt;
&lt;li&gt;
Having recieved required accounts we queue a sub-task for synchronous execution using &lt;code&gt;parallel.PostSync()&lt;/code&gt;,
and&lt;/li&gt;
&lt;li&gt;
Pass there data collected in parallel sub-task: transaction and accounts.&lt;/li&gt;
&lt;li&gt;
We deconstruct data passed into variables, and then proceed with serial logic.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
What we achieve with this refactoring:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Top level query that brings transactions is done and iterated serially.&lt;/li&gt;
&lt;li&gt;
But each iteration body is run in parallel. By default we set it up to allow up to
100 parallel executions. All those parallel sub-task do not wait on each other so
their waitings do not add up.&lt;/li&gt;
&lt;li&gt;
Sync sub-tasks are queued and executed in order of their serial appearance, so increments
and report records are not a subject of race conditions, nor a subject of reordering
of output records.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We think that such refactored code is still recognizible.
&lt;/p&gt;
&lt;p&gt;
As for performance this is what log shows:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-log"&gt;&lt;span class="hljs-selector-tag"&gt;Serial&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;test&lt;/span&gt; 100
... &lt;span class="hljs-selector-tag"&gt;Execution&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;time&lt;/span&gt;:
00&lt;span class="hljs-selector-pseudo"&gt;:01&lt;/span&gt;&lt;span class="hljs-selector-pseudo"&gt;:33.8152540&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;Parallel&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;test&lt;/span&gt; 100
... &lt;span class="hljs-selector-tag"&gt;Execution&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;time&lt;/span&gt;:
00&lt;span class="hljs-selector-pseudo"&gt;:00&lt;/span&gt;&lt;span class="hljs-selector-pseudo"&gt;:05.8705468&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Reference
&lt;/h4&gt;
&lt;p&gt;
Please take a look at project to understand implementation details, and in particular &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/Parallel.cs"&gt;&lt;code&gt;Parallel&lt;/code&gt;&lt;/a&gt; class
implementing API to post parallel and serial tasks, run cycles and some more.
&lt;/p&gt;
&lt;p&gt;
Please continue reading on &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master?tab=readme-ov-file#parallel-refactoring"&gt;GitHub&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=371a8329-d392-4d20-bcbc-db9503816f26" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0977bf46-abc6-41fe-9767-de673ef5de8b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0977bf46-abc6-41fe-9767-de673ef5de8b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As we wrote some time ago, we started to use AI and ML APIs in our applications, but
this time we've tried to use Bing chat as a tool.
</p>
        <p>
The initial task was to collect sequences of integer numbers and return a list of
pairs integers where the first number is a range's start and the second one is a count
of values in the range. For example, for sequence 1, 2, 3, 5, 8, 9 we'd like to get
the following results: 1, 3 5, 1 8, 2 
</p>
        <p>
We both started to solve this issue. My brother started to play with SSMS using his
deep knowledges in SQL and analytic functions, whereas me started to play with Bing
chat. Looking ahead, I can state that we both solved the issue using almost the same
SQL statement almost in the same time.
</p>
        <p>
Here are my prompts and Bing's answers:
</p>
        <dl>
          <dt style="font-weight: bold;">Prompt:</dt>
          <dd>
Act as database analyst and software engineer. Given the table (T) with a numeric
field (N), which values are orderd ranges of integers. In a range each next value
is greater than previous one on 1. When value differs from the previous one more than
on 1 then in belongs to another range. Generate select statement that returns rows
with two fields. The first field (R) is a number from which a range starts and the
second field (C) is count elements of that range: 
</dd>
          <dt style="font-weight: bold;">Answer:</dt>
          <dd style="white-space: normal;">
Sure, I can help with that. Here's a SQL query that should do the trick. This query
uses a self-join to identify the start of each range, and then groups by the start
of the range to count the number of elements. <code style="white-space: pre; margin: 1em; font-family: monospace;"> ```sql
SELECT start_of_range AS R, COUNT(*) AS C FROM ( SELECT N, N - ROW_NUMBER() OVER (ORDER
BY N) AS start_of_range FROM T ) subquery GROUP BY start_of_range ORDER BY start_of_range;
``` </code> In this query, `start_of_range` is calculated as the difference between
the current value of `N` and its row number (when ordered by `N`). This difference
will be the same for all `N` in the same range. Then we group by `start_of_range`
to get the count of elements in each range. The outer query selects the start of each
range (`R`) and the count of elements in that range (`C`). 
</dd>
          <dt style="padding: 1em; font-weight: 400;"> Me, scratching the head, hmmm... </dt>
          <dt style="font-weight: bold;"> Question: </dt>
          <dd style="white-space: pre;">
This is a bit incorrect SQL select. For example for values 1, 2, 3, 5, 8, 9 I'd like
to get the following results: 1, 3 5, 1 8, 2 What a SQL select shall I use to get
such results? 
</dd>
          <dt style="font-weight: bold;">Answer:</dt>
          <dd>
I apologize for the confusion earlier. You're right, the previous query doesn't handle
the scenario you've described correctly. Here's a corrected SQL query that should
give you the desired output. This query uses a window function to compare each row
with the previous one and identify the start of a new range. Then it groups by the
start of the range to count the elements. <code style="white-space: pre;font-family: monospace;"> ```sql
WITH ranges AS ( SELECT N, CASE WHEN N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1
ELSE 0 END AS is_start_of_range FROM T ), range_groups AS ( SELECT N, SUM(is_start_of_range)
OVER (ORDER BY N) AS range_group FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM
range_groups GROUP BY range_group ORDER BY R; ``` </code> In this query, `is_start_of_range`
is a flag that indicates the start of a new range (when the difference between the
current and previous `N` is more than 1). `range_group` is a running total of `is_start_of_range`
that serves as a unique identifier for each range. The outer query then groups by
`range_group` to get the start (`R`) and count (`C`) of each range. I hope this helps!
Let me know if you have any other questions. 
</dd>
        </dl>
        <p>
That answer more satisfied me, and I've checked the following example:
</p>
        <code style="white-space: pre; font-family: monospace;"> with T as ( select 10 N union
all select 11 N union all select 30 N union all select 31 N union all select 32 N
union all select 50 N union all select 80 N union all select 81 N union all select
82 N union all select 83 N union all select 90 N ), ranges AS ( SELECT N, CASE WHEN
N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1 ELSE 0 END AS is_start_of_range FROM
T ), range_groups AS ( SELECT N, SUM(is_start_of_range) OVER (ORDER BY N) AS range_group
FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM range_groups GROUP BY range_group
ORDER BY R; </code>
        <p>
The result was:
</p>
        <code style="white-space: pre; font-family: monospace;"> R C ------------ 10 2 30
3 50 1 80 4 90 1 </code>
        <p>
          <b>Conclusion:</b>
          <br />
Nowdays, using AI as a tool, you may improve your performance to the expert level
and, may be, study something new... 
</p>
        <p>
          <b>P.S.</b> Don't fool youself that AI can replace a developer (see the first answer
of the chat), but together they can be much stornger than separatelly. 
</p>
        <p>
          <b>P.P.S.</b> Another interesting solution gave us our colleague. She used an additional
field to avoid using analytics function, and she reached the same result: 
</p>
        <code style="white-space: pre; font-family: monospace;"> with T as ( select 10 ID,
1 N union all select 11 ID, 1 N union all select 30 ID, 1 N union all select 31 ID,
1 N union all select 32 ID, 1 N union all select 50 ID, 1 N union all select 80 ID,
1 N union all select 81 ID, 1 N union all select 82 ID, 1 N union all select 83 ID,
1 N union all select 90 ID, 1 N ), Groups AS ( SELECT ID, N, ROW_NUMBER() OVER (ORDER
BY ID) - ID AS GroupNumber FROM T ) SELECT MIN(ID) AS R, SUM(N) AS C FROM Groups GROUP
BY GroupNumber ORDER BY StartID; </code>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0977bf46-abc6-41fe-9767-de673ef5de8b" />
      </body>
      <title>Using Bing chat as a tool.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2024/01/01/UsingBingChatAsATool.aspx</link>
      <pubDate>Mon, 01 Jan 2024 14:02:01 GMT</pubDate>
      <description>    &lt;p&gt;
As we wrote some time ago, we started to use AI and ML APIs in our applications, but
this time we've tried to use Bing chat as a tool.
&lt;/p&gt;
&lt;p&gt;
The initial task was to collect sequences of integer numbers and return a list of
pairs integers where the first number is a range's start and the second one is a count
of values in the range. For example, for sequence 1, 2, 3, 5, 8, 9 we'd like to get
the following results: 1, 3 5, 1 8, 2 
&lt;/p&gt;
&lt;p&gt;
We both started to solve this issue. My brother started to play with SSMS using his
deep knowledges in SQL and analytic functions, whereas me started to play with Bing
chat. Looking ahead, I can state that we both solved the issue using almost the same
SQL statement almost in the same time.
&lt;/p&gt;
&lt;p&gt;
Here are my prompts and Bing's answers:
&lt;/p&gt;
&lt;dl&gt;
&lt;dt style="font-weight: bold;"&gt;Prompt:&lt;/dt&gt; 
&lt;dd&gt;
Act as database analyst and software engineer. Given the table (T) with a numeric
field (N), which values are orderd ranges of integers. In a range each next value
is greater than previous one on 1. When value differs from the previous one more than
on 1 then in belongs to another range. Generate select statement that returns rows
with two fields. The first field (R) is a number from which a range starts and the
second field (C) is count elements of that range: 
&lt;/dd&gt;
&lt;dt style="font-weight: bold;"&gt;Answer:&lt;/dt&gt; 
&lt;dd style="white-space: normal;"&gt;
Sure, I can help with that. Here's a SQL query that should do the trick. This query
uses a self-join to identify the start of each range, and then groups by the start
of the range to count the number of elements. &lt;code style="white-space: pre; margin: 1em; font-family: monospace;"&gt; ```sql
SELECT start_of_range AS R, COUNT(*) AS C FROM ( SELECT N, N - ROW_NUMBER() OVER (ORDER
BY N) AS start_of_range FROM T ) subquery GROUP BY start_of_range ORDER BY start_of_range;
``` &lt;/code&gt; In this query, `start_of_range` is calculated as the difference between
the current value of `N` and its row number (when ordered by `N`). This difference
will be the same for all `N` in the same range. Then we group by `start_of_range`
to get the count of elements in each range. The outer query selects the start of each
range (`R`) and the count of elements in that range (`C`). 
&lt;/dd&gt;
&lt;dt style="padding: 1em; font-weight: 400;"&gt; Me, scratching the head, hmmm... &lt;/dt&gt; &lt;dt style="font-weight: bold;"&gt; Question: &lt;/dt&gt; 
&lt;dd style="white-space: pre;"&gt;
This is a bit incorrect SQL select. For example for values 1, 2, 3, 5, 8, 9 I'd like
to get the following results: 1, 3 5, 1 8, 2 What a SQL select shall I use to get
such results? 
&lt;/dd&gt;
&lt;dt style="font-weight: bold;"&gt;Answer:&lt;/dt&gt; 
&lt;dd&gt;
I apologize for the confusion earlier. You're right, the previous query doesn't handle
the scenario you've described correctly. Here's a corrected SQL query that should
give you the desired output. This query uses a window function to compare each row
with the previous one and identify the start of a new range. Then it groups by the
start of the range to count the elements. &lt;code style="white-space: pre;font-family: monospace;"&gt; ```sql
WITH ranges AS ( SELECT N, CASE WHEN N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1
ELSE 0 END AS is_start_of_range FROM T ), range_groups AS ( SELECT N, SUM(is_start_of_range)
OVER (ORDER BY N) AS range_group FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM
range_groups GROUP BY range_group ORDER BY R; ``` &lt;/code&gt; In this query, `is_start_of_range`
is a flag that indicates the start of a new range (when the difference between the
current and previous `N` is more than 1). `range_group` is a running total of `is_start_of_range`
that serves as a unique identifier for each range. The outer query then groups by
`range_group` to get the start (`R`) and count (`C`) of each range. I hope this helps!
Let me know if you have any other questions. 
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
That answer more satisfied me, and I've checked the following example:
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; with T as ( select 10 N union
all select 11 N union all select 30 N union all select 31 N union all select 32 N
union all select 50 N union all select 80 N union all select 81 N union all select
82 N union all select 83 N union all select 90 N ), ranges AS ( SELECT N, CASE WHEN
N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1 ELSE 0 END AS is_start_of_range FROM
T ), range_groups AS ( SELECT N, SUM(is_start_of_range) OVER (ORDER BY N) AS range_group
FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM range_groups GROUP BY range_group
ORDER BY R; &lt;/code&gt; 
&lt;p&gt;
The result was:
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; R C ------------ 10 2 30
3 50 1 80 4 90 1 &lt;/code&gt; 
&lt;p&gt;
&lt;b&gt;Conclusion:&lt;/b&gt;
&lt;br /&gt;
Nowdays, using AI as a tool, you may improve your performance to the expert level
and, may be, study something new... 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;P.S.&lt;/b&gt; Don't fool youself that AI can replace a developer (see the first answer
of the chat), but together they can be much stornger than separatelly. 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;P.P.S.&lt;/b&gt; Another interesting solution gave us our colleague. She used an additional
field to avoid using analytics function, and she reached the same result: 
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; with T as ( select 10 ID,
1 N union all select 11 ID, 1 N union all select 30 ID, 1 N union all select 31 ID,
1 N union all select 32 ID, 1 N union all select 50 ID, 1 N union all select 80 ID,
1 N union all select 81 ID, 1 N union all select 82 ID, 1 N union all select 83 ID,
1 N union all select 90 ID, 1 N ), Groups AS ( SELECT ID, N, ROW_NUMBER() OVER (ORDER
BY ID) - ID AS GroupNumber FROM T ) SELECT MIN(ID) AS R, SUM(N) AS C FROM Groups GROUP
BY GroupNumber ORDER BY StartID; &lt;/code&gt;&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0977bf46-abc6-41fe-9767-de673ef5de8b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</comments>
      <category>AI</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b69227a9-de75-4062-aa5b-82c8dff548e1</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b69227a9-de75-4062-aa5b-82c8dff548e1</wfw:commentRss>
      <title>Collecting public data from Internet</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2021/01/01/CollectingPublicDataFromInternet.aspx</link>
      <pubDate>Fri, 01 Jan 2021 14:34:37 GMT</pubDate>
      <description>&lt;p&gt;
Earlier we wrote that recently we've gotten few tasks related to Machine Learning.
The prerequisites to such task is to collect and prepare the input data. Usually the
required data is scattered across public sites, some of them are in plain text format
(or close to it), but others are accessible as output of public applications. To obtain
the required data for such sites you have to navigate thourgh pages, which often requires
keeping state between navigations. 
&lt;/p&gt;
&lt;p&gt;
In order to implement this task you need some kind of crawler/scraper of the websites.
Fortunately, there are a lot of frameworks, libraries and tools in C# (and in other
languages too) that allow to do this (visit &lt;a href="https://nugetmusthaves.com/Tag/crawler" target="_blank"&gt;this&lt;/a&gt; or &lt;a href="https://prowebscraper.com/blog/50-best-open-source-web-crawlers/" target="_blank"&gt;this&lt;/a&gt; site
to see most popular of them), for example: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
ScrapySharp&lt;/li&gt;
&lt;li&gt;
ABot&lt;/li&gt;
&lt;li&gt;
HtmlAgilityPack&lt;/li&gt;
&lt;li&gt;
DotnetSpider&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There are pros and cons of using these libraries. Most crucial cons is a lack of support
of rich UI based on heavy client-side scripts and client-side state support. Since
not all such libraries implement fully browser emulation and even more, some of them
do not support Javascript execution. So, they suit for gathering information from
simple web pages, but no library allows to easy navigate to some page of a web application
that keeps rich client-side state. Even best of them, like ScrapySharp, require heavy
programming to achieve the result.
&lt;/p&gt;
&lt;p&gt;
Then, suddenly, we've recalled that already for several years we're using Selenium
and web drivers to automate web tests for AngularJS/Angular projects. After short
discussion we came to conclusion that there is no big difference between testing web
application and collecting data, since one of testing stages is collecting of actual
results (data) from the tested page, and usually our tests consist of chains of actions
performed on consequently visited pages. 
&lt;/p&gt;
&lt;p&gt;
This way we came to idea to use WebDriver API implemented by &lt;a href="https://www.selenium.dev/documentation/en/" target="_blank"&gt;Selenium
project&lt;/a&gt;. There are implementations of this API in different languages, and in
C# too.
&lt;/p&gt;
&lt;p&gt;
Using WebDriver we easily implement cumbersome navigation of a complex web application
and can collect required data. Moreover, it allows to run WebDriver in screenless
mode. Some of its features allow to create a snapshots of virtual screen and store
HTML sources that would resulted of Javascript execution. These features are very
useful during run-time troubleshooting. To create a complex web application navigation
we need only a bit more knowledge than usual web application's user - we need to identify
somehow pages' elements for example by CSS selectors or by id of HTML elements (as
we do this for tests). All the rest, like coockies, view state (if any), value of
hidden fields, some Javascript events will be transparent in this case. 
&lt;/p&gt;
&lt;p&gt;
Although one may say that approach with Selenium is rather fat, it's ought to mention
that it is rather scalable. You may either to run several threads with different WebDriver
instances in each thread or run several processes simultaneously. 
&lt;/p&gt;
&lt;p&gt;
However, beside pros there are cons in the solution with Selenium. They will appear
when you'll decide to publish it, e.g. to Azure environment. Take a note that approach
with Selenium requires a browser on the server, there is also a problem with Azure
itself, as it's Microsoft's platform and Selenium is a product of their main competitor
Google... So, some issues aren't techincals. The only possible solution is to use
PaaS approach instead of SaaS, but in this case you have to support everything by
yourself... 
&lt;/p&gt;
&lt;p&gt;
The other problem is that if your application will implement rather aggressive crawling,
so either servers where you gather data or your own host might ban it. So, be gentle,
play nice, and implement delays between requests. 
&lt;/p&gt;
&lt;p&gt;
Also, take into account that when you're implementing any crawler some problems may
appear on law level, since not all web sites allow pull anything you want. Many sites
use terms &amp; conditions that defines rules for the site users (that you cralwer should
follow to), otherwise legal actions may be used against them (or their owners in case
of crawler). There is &lt;a href="https://www.c-sharpcorner.com/article/web-crawling-with-c-sharp/" targte="_blank"&gt;very
interesting article&lt;/a&gt; that describes many pitfalls when you implement your own crawler. 
&lt;/p&gt;
&lt;p&gt;
To summarize everything we told early, the Selenium project could be used in many
scenarios, and one of them is to create a powerful crawler. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b69227a9-de75-4062-aa5b-82c8dff548e1" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</comments>
      <category>ML.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=638aefac-fd7a-431a-9d7f-0aeef885d9a5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,638aefac-fd7a-431a-9d7f-0aeef885d9a5.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=638aefac-fd7a-431a-9d7f-0aeef885d9a5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img src="https://i.ytimg.com/vi/VJTpbZrBAeU/hqdefault.jpg" width="200" style="float: left; margin-right: 5px;" />Eventually
we've started to deal with tasks that required machine learning. Thus, the good tutorial
for ML.NET was required and we had <a href="https://youtu.be/VJTpbZrBAeU" target="_blank">found
this one</a> that goes along with <a href="https://github.com/jeffprosise/ML.NET" target="_blank">good
simple codesamples</a>. Thanks to Jeff Prosise. Hope this may be helpfull to you too.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=638aefac-fd7a-431a-9d7f-0aeef885d9a5" />
      </body>
      <title>ML.NET tutorial</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,638aefac-fd7a-431a-9d7f-0aeef885d9a5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/12/16/MLNETTutorial.aspx</link>
      <pubDate>Wed, 16 Dec 2020 11:38:57 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img src="https://i.ytimg.com/vi/VJTpbZrBAeU/hqdefault.jpg" width="200" style="float: left; margin-right: 5px;" /&gt;Eventually
we've started to deal with tasks that required machine learning. Thus, the good tutorial
for ML.NET was required and we had &lt;a href="https://youtu.be/VJTpbZrBAeU" target="_blank"&gt;found
this one&lt;/a&gt; that goes along with &lt;a href="https://github.com/jeffprosise/ML.NET" target="_blank"&gt;good
simple codesamples&lt;/a&gt;. Thanks to Jeff Prosise. Hope this may be helpfull to you too.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=638aefac-fd7a-431a-9d7f-0aeef885d9a5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,638aefac-fd7a-431a-9d7f-0aeef885d9a5.aspx</comments>
      <category>.NET</category>
      <category>ML.NET</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ec795ede-3e18-473f-bff9-204ea1cecf49</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ec795ede-3e18-473f-bff9-204ea1cecf49</wfw:commentRss>
      <title>Groups in SQL</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/08/05/GroupsInSQL.aspx</link>
      <pubDate>Wed, 05 Aug 2020 07:44:07 GMT</pubDate>
      <description>  &lt;p&gt;
Recently our colleague turned to us and asked to help to deal with some complex query.
&lt;/p&gt;
&lt;p&gt;
It has turned out that the complex part was to understand what he wants to achieve.
&lt;/p&gt;
&lt;p&gt;
After listening to him we have forumulated the task in our words and have confirmed
that that is what he wants.
&lt;/p&gt;
&lt;p&gt;
So, that&amp;#39;s the task in our formulation:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Assume you have events. 
&lt;/li&gt;
&lt;li&gt;
Each event acts upon one or more accounts.&lt;/li&gt;
&lt;li&gt;
Find all events that act on the same set of accounts.&lt;/li&gt;
&lt;li&gt;
Note we deal with mutiple millions of events and accounts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Data is defined like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;create table dbo.Event
(
  EventID bigint not null,
  AccountID varchar(18) not null,
  primary key(EventID, AccountID)
);&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Requested query turned out to be very simple, yet, not as simple as one would think
to account big amout of data:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt; S2.EventID and
    S1.Items = S2.Items and
    S1.Hash = S2.Hash and
    not exists
    (
      select AccountID from D where EventID = S1.EventID
      except
      select AccountID from D where EventID = S2.EventID
    );&lt;/pre&gt;with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    count(*) Items,
    checksum_agg(checksum(AccountID)) Hash
  from
    D
  group by
    EventID
)
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID 
&lt;/blockquote&gt; 
&lt;p&gt;
The idea is to:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
calculate a hash derived from list of accounts for each group;&lt;/li&gt;
&lt;li&gt;
join groups with the same hash;&lt;/li&gt;
&lt;li&gt;
verify that matched groups fit perfectly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Even simpler solution that does not use hashes is not scaleable, as it&amp;#39;s performance
is slower than O(N^2), where N - is a number of events. It has unacceptable time with
N ~1e4, nothing to say about N ~1e7.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
At this point our colleague was already satisfied, as he got result in couple of minutes
for a task that he could not even formalize as SQL.
&lt;/p&gt;
&lt;p&gt;
But we felt it could be even better.
&lt;/p&gt;
&lt;p&gt;
We looked at statistics:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;
with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    count(*) Items
  from
    D
  group by
    EventID
)
select
  Items, count(*) EventCount
from
  S
group by
  Items
order by
  EventCount desc;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
and have seen that most of the events, about 90%, deal with single account, and all
other with two and more (some of them act upon big number of accounts).
&lt;/p&gt;
&lt;p&gt;
The nature of the dataset gave us a hint of more verbose but more fast query:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt; S2.EventID and
    S1.Items = 1 and
    S2.Items = 1 and
    S1.AccountID = S2.AccountID
union all
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID &lt; S2.EventID and
    S1.Items &gt;with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    min(AccountID) AccountID,
    count(*) Items,
    checksum_agg(checksum(AccountID)) Hash
  from
    D
  group by
    EventID
)
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID  1 and
    S2.Items &gt; 1 and
    S1.Items = S2.Items and
    S1.Hash = S2.Hash and
    not exists
    (
      select AccountID from D where EventID = S1.EventID
      except
      select AccountID from D where EventID = S2.EventID
    );&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This query produced results in twenty seconds instead of couple of minutes for a dataset
with ~1e7 rows.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ec795ede-3e18-473f-bff9-204ea1cecf49" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4196bfb4-24a3-4d7d-bea9-59bc907ce4ba</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4196bfb4-24a3-4d7d-bea9-59bc907ce4ba.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4196bfb4-24a3-4d7d-bea9-59bc907ce4ba</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Not sure what is use of our <a href="https://github.com/nesterovsky-bros/xslt-graph">Xslt
Graph exercises</a> but what we are sure with is that it stresses different parts
of Saxon Xslt engine and helps to find and resolve different bugs.
</p>
        <p>
While implementing <a href="https://github.com/nesterovsky-bros/xslt-graph/blob/master/biconnected-components.xslt">biconnected
components algorithm</a> we incidently run into <a href="https://github.com/nesterovsky-bros/xslt-graph/blob/master/tests/saxon-10.1-internal-error.xslt">internal
error with Saxon 10.1</a> with rather simple xslt:
</p>
        <blockquote>
          <pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
  exclude-result-prefixes="xs array"&gt;

  &lt;xsl:template match="/"&gt;
    &lt;xsl:sequence select="
      array:fold-left
      (
        [8, 9], 
        (), 
        function($first as item(), $second as item()) 
        {  
          min(($first, $second))
        }
      )"/&gt;
  &lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;</pre>
        </blockquote>
        <p>
More detail can be found at Saxon's issue tracker: <a href="https://saxonica.plan.io/issues/4578">Bug
#4578: NullPointerException when array:fold-left|right $zero argument is an empty
sequence</a>. 
</p>
        <p>
Bug is promptly resolved.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4196bfb4-24a3-4d7d-bea9-59bc907ce4ba" />
      </body>
      <title>Xslt Graph and Saxon processor</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4196bfb4-24a3-4d7d-bea9-59bc907ce4ba.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/06/08/XsltGraphAndSaxonProcessor.aspx</link>
      <pubDate>Mon, 08 Jun 2020 05:58:32 GMT</pubDate>
      <description>&lt;p&gt;
Not sure what is use of our &lt;a href="https://github.com/nesterovsky-bros/xslt-graph"&gt;Xslt
Graph exercises&lt;/a&gt; but what we are sure with is that it stresses different parts
of Saxon Xslt engine and helps to find and resolve different bugs.
&lt;/p&gt;
&lt;p&gt;
While implementing &lt;a href="https://github.com/nesterovsky-bros/xslt-graph/blob/master/biconnected-components.xslt"&gt;biconnected
components algorithm&lt;/a&gt; we incidently run into &lt;a href="https://github.com/nesterovsky-bros/xslt-graph/blob/master/tests/saxon-10.1-internal-error.xslt"&gt;internal
error with Saxon 10.1&lt;/a&gt; with rather simple xslt:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&gt;
&amp;lt;xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
  exclude-result-prefixes="xs array"&gt;

  &amp;lt;xsl:template match="/"&gt;
    &amp;lt;xsl:sequence select="
      array:fold-left
      (
        [8, 9], 
        (), 
        function($first as item(), $second as item()) 
        {  
          min(($first, $second))
        }
      )"/&gt;
  &amp;lt;/xsl:template&gt;

&amp;lt;/xsl:stylesheet&gt;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
More detail can be found at Saxon's issue tracker: &lt;a href="https://saxonica.plan.io/issues/4578"&gt;Bug
#4578: NullPointerException when array:fold-left|right $zero argument is an empty
sequence&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Bug is promptly resolved.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4196bfb4-24a3-4d7d-bea9-59bc907ce4ba" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4196bfb4-24a3-4d7d-bea9-59bc907ce4ba.aspx</comments>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
People compare these two technologies, and it seems an established fact is that Angular
is evolutionally more advanced framework. We're not going to contradict, contrary,
we agree with it, but it's better for an opinion to be grounded on facts that
one can evaluate and verify.
</p>
        <p>
Fortunately we got a chance to make such a comparison.
</p>
        <p>
We support conversions of <a href="https://en.wikipedia.org/wiki/CA_Gen">Cool:GEN</a> (a
legacy <a href="https://en.wikipedia.org/wiki/Computer-aided_software_engineering">CASE</a> tool
with roots in 80th) to java or C#. In its time Cool:GEN allowed to greatly automate
enterprise development using Mainframes as a server side and Mainframe terminals or
Win32 GUIs as clients.
</p>
        <p>
The legacy of this tool are probably hundreds of business and database models, milions
of programs generated on COBOL on Mainframes and on C or Java on Windows and Linux.
All this runs to this time in many econimic sectors.
</p>
        <p>
Usually the client is some enterprise that invested a lot into design, development
and support of their business model using Cool:GEN but now most such clients a trying
not to lose this legacy but to convert it into something that goes in parallel with
todays technologies.
</p>
        <p>
As original technology is sound, so it is possible to map it to todays Java or C#
on server, REST or SOAP as a transport, and Angular, AngularJS or some other on client.
Such automatic conversion is an essense of our conversions efforts.
</p>
        <p>
To understand a scope consider a typical enterprise client that has 2-3 thousand windows
that are backed by 20-30 thousand programs.
</p>
        <p>
Now, consider that the conversion is done. On output among other things we produce
a clean java or C# web application with REST and SOAP interface, and Angular or AngularJS
web client that encapsulates those 2-3 thousand windows.
</p>
        <p>
Each window definition is rather small 5-10 KB in html form, but whole mass of windows
takes 10-30 MB, which is not small any more.
</p>
        <p>
For AngularJS we generate just those html templates, but for Angular we need to generate
separate components for each window that includes typescript class, template and style.
</p>
        <p>
While amout of generated resource for AngularJS stays in those 10-30 MB, generated
Angular takes at least 5-10 MB more.
</p>
        <p>
The next step is build. 
</p>
        <p>
AngularJS builds distribution that includes all used libraries and a set of templates,
and it takes something like a minute from the CPU. Produced output is about 300 KB
minified script and those 10-30 MB of templates (multiple files with 5-10 KB each
one).
</p>
        <p>
Angular (here we talk about version 9) builds distribution that includes all used
libraries and a set of compiled components that are to be loaded lazily on demand.
Without of the both angular builder that performs tree shaking build takes days. With
tree shaking off it takes 40 minutes. This is the first notable difference. Produced
output for ES2015 (latest javascript) is about 1 MB, and 15-100 KB per each compiled
component. This is the second notable difference that already impacts end user rather
than developer.
</p>
        <p>
The third difference is in the end user experience. Though we have built equalvalent
Angular and AngularJS frontend we observe load time of angular is higher. This cannot
only be ascribed to bigger file sizes. It seems internal initialization also takes
more time for Angular.
</p>
        <p>
So, our experience in this particular test shows that Angular has more room to improve.
In particular: compile time, bundle size, runtime speed and simplicity of dynamic
loading (we have strong cases when template compilation is not the best approach).
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8" />
      </body>
      <title>Angular vs AngularJS. Practical comparison.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/04/04/AngularVsAngularJSPracticalComparison.aspx</link>
      <pubDate>Sat, 04 Apr 2020 12:37:15 GMT</pubDate>
      <description>  &lt;p&gt;
People compare these two technologies, and it seems an established fact is that Angular
is evolutionally more advanced framework. We&amp;#39;re not going to contradict, contrary,
we agree with it, but it&amp;#39;s better for an opinion to be grounded on facts that
one can evaluate and verify.
&lt;/p&gt;
&lt;p&gt;
Fortunately we got a chance to make such a comparison.
&lt;/p&gt;
&lt;p&gt;
We support conversions of &lt;a href="https://en.wikipedia.org/wiki/CA_Gen"&gt;Cool:GEN&lt;/a&gt; (a
legacy &lt;a href="https://en.wikipedia.org/wiki/Computer-aided_software_engineering"&gt;CASE&lt;/a&gt; tool
with roots in 80th) to java or C#. In its time Cool:GEN allowed to greatly automate
enterprise development using Mainframes as a server side and Mainframe terminals or
Win32 GUIs as clients.
&lt;/p&gt;
&lt;p&gt;
The legacy of this tool are probably hundreds of business and database models, milions
of programs generated on COBOL on Mainframes and on C or Java on Windows and Linux.
All this runs to this time in many econimic sectors.
&lt;/p&gt;
&lt;p&gt;
Usually the client is some enterprise that invested a lot into design, development
and support of their business model using Cool:GEN but now most such clients a trying
not to lose this legacy but to convert it into something that goes in parallel with
todays technologies.
&lt;/p&gt;
&lt;p&gt;
As original technology is sound, so it is possible to map it to todays Java or C#
on server, REST or SOAP as a transport, and Angular, AngularJS or some other on client.
Such automatic conversion is an essense of our conversions efforts.
&lt;/p&gt;
&lt;p&gt;
To understand a scope consider a typical enterprise client that has 2-3 thousand windows
that are backed by 20-30 thousand programs.
&lt;/p&gt;
&lt;p&gt;
Now, consider that the conversion is done. On output among other things we produce
a clean java or C# web application with REST and SOAP interface, and Angular or AngularJS
web client that encapsulates those 2-3 thousand windows.
&lt;/p&gt;
&lt;p&gt;
Each window definition is rather small 5-10 KB in html form, but whole mass of windows
takes 10-30 MB, which is not small any more.
&lt;/p&gt;
&lt;p&gt;
For AngularJS we generate just those html templates, but for Angular we need to generate
separate components for each window that includes typescript class, template and style.
&lt;/p&gt;
&lt;p&gt;
While amout of generated resource for AngularJS stays in those 10-30 MB, generated
Angular takes at least 5-10 MB more.
&lt;/p&gt;
&lt;p&gt;
The next step is build. 
&lt;/p&gt;
&lt;p&gt;
AngularJS builds distribution that includes all used libraries and a set of templates,
and it takes something like a minute from the CPU. Produced output is about 300 KB
minified script and those 10-30 MB of templates (multiple files with 5-10 KB each
one).
&lt;/p&gt;
&lt;p&gt;
Angular (here we talk about version 9) builds distribution that includes all used
libraries and a set of compiled components that are to be loaded lazily on demand.
Without of the both angular builder that performs tree shaking build takes days. With
tree shaking off it takes 40 minutes. This is the first notable difference. Produced
output for ES2015 (latest javascript) is about 1 MB, and 15-100 KB per each compiled
component. This is the second notable difference that already impacts end user rather
than developer.
&lt;/p&gt;
&lt;p&gt;
The third difference is in the end user experience. Though we have built equalvalent
Angular and AngularJS frontend we observe load time of angular is higher. This cannot
only be ascribed to bigger file sizes. It seems internal initialization also takes
more time for Angular.
&lt;/p&gt;
&lt;p&gt;
So, our experience in this particular test shows that Angular has more room to improve.
In particular: compile time, bundle size, runtime speed and simplicity of dynamic
loading (we have strong cases when template compilation is not the best approach).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</comments>
      <category>AngularJS</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=861382a1-a2b8-4b39-a9f4-1f7a2148bf59</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=861382a1-a2b8-4b39-a9f4-1f7a2148bf59</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We were asked to help with search service in one enterprise. We were told that their
SharePoint portal does not serve their need. Main complaints were about the quality
of search results.
</p>
        <p>
They have decided to implement external index of SharePoint content, using <a href="https://www.elastic.co/">Elastic</a>,
and expose custom search API within the enterprise.
</p>
        <p>
        </p>
        <p>
We questioned their conclusions, asked why did they think Elastic will give much better
results, asked did they try to figure out why SharePoint give no desired results.
</p>
        <p>
Answers did not convince us though we have joined the project.
</p>
        <p>
        </p>
        <p>
What do you think? Elastic did not help at all though they hoped very much that its
query language will help to rank results in a way that matched documents will be found.
After all they thought it was a problem of ranking of results.
</p>
        <p>
        </p>
        <p>
Here we have started our analysis. We took a specific document that must be found
but is never returned from search.
</p>
        <p>
        </p>
        <p>
It turned to be well known problem, at least we dealt with closely related one in
the past. There are two ingredients here:
</p>
        <ul>
          <li>
documents that have low chances to be found are PDFs;</li>
          <li>
we live in Israel, so most texts are Hebrew, which means words are written from right
to left, while some other texts from left to right. See <a href="https://en.wikipedia.org/wiki/Bi-directional_text" target="_blank">Bi-directional
text</a>.</li>
        </ul>
        <p>
Traditionally PDF documents are provided in a way that only distantly resembles logical
structure of original content. E.g., paragraphs of texts are often represented as
unrelated runs of text lines, or as set of text runs representing single words, or
independant characters. No need to say that additional complication comes from that
Hebrew text are often represented visually (from left to right, as if "hello"
would be stored as "olleh" and would be just printed from right to left).
Another common feature of PDF are custom fonts with uncanonical mappings, or images
with glyphs of letters.
</p>
        <p>
You can implement these tricks in other document formats but for some reason PDF is
only format we have seen that regularly and intensively uses these techniques.
</p>
        <p>
        </p>
        <p>
At this point we have realized that it's not a fault of a search engine to find
the document but the feature of the PDF to expose its text to a crawler in a form
that cannot be used for search. In fact, PDF cannot search by itself in such documents,
as when you try to find some text in the document opened in a pdf viewer, that you
clearly see in the document, you often find nothing.
</p>
        <p>
        </p>
        <p>
A question. What should you do in this case when no any PDF text extractor can give
you correct text but text is there when you looking at document in a pdf viewer?
</p>
        <p>
        </p>
        <p>
We decided it's time to go in the direction of image recognition. Thankfully,
nowdays it's a matter of available processing resources.
</p>
        <p>
Our goal was:
</p>
        <ol>
          <li>
Have images of each PDF page. This task is immediately solved with <a href="https://pdfbox.apache.org/" target="_blank">Apache
PDFBox (A Java PDF Library) - it's time to say this is java project.</a></li>
          <li>
Run Optical Character Recognition (OCR) over images, and get extracted texts. This
is perfectly done by <a href="https://github.com/tesseract-ocr/tesseract" target="_blank">tesseract-ocr/tesseract</a>,
and thankfully to its java wrapper <a href="https://github.com/bytedeco/javacpp-presets/tree/master/tesseract" target="_blank">bytedeco/javacpp-presets</a> we
can immediately call this C++ API from java.</li>
        </ol>
        <p>
The only small nuisance of tesseract is that it does not expose table recognition
info, but we can easily overcome it (we solved this task in the past), as along with
each text run tesseract exposes its position.
</p>
        <p>
        </p>
        <p>
What are results of the run of such program?
</p>
        <ol>
          <li>
Full success! It works with high quality of recognition. Indeed, there is no any physical
noise that impacts quality.</li>
          <li>
Slow speed - up to several seconds per recognition per page.</li>
          <li>
Scalable solution. Slow speed can be compensated by almost unlimited theoretical scalability.</li>
        </ol>
        <p>
        </p>
        <p>
So, what is the lesson we have taked from this experience?
</p>
        <p>
        </p>
        <p>
Well, you should question yourself, test and verify ideas on the ground before building
any theories that will lead you in completely wrong direction. After all people started
to realize there was no need to claim on SharePoint, to throw it, and to spend great
deal of time and money just to prove that the problem is in the different place.
</p>
        <p>
A sample source code can be found at <a href="https://github.com/nesterovsky-bros/pdf.ocr/blob/master/src/main/java/nesterovskyBros/pdf/ocr/App.java" target="_blank">App.java</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=861382a1-a2b8-4b39-a9f4-1f7a2148bf59" />
      </body>
      <title>Theory vs practice</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2019/07/26/TheoryVsPractice.aspx</link>
      <pubDate>Fri, 26 Jul 2019 16:38:11 GMT</pubDate>
      <description>&lt;p&gt;
We were asked to help with search service in one enterprise. We were told that their
SharePoint portal does not serve their need. Main complaints were about the quality
of search results.
&lt;/p&gt;
&lt;p&gt;
They have decided to implement external index of SharePoint content, using &lt;a href="https://www.elastic.co/"&gt;Elastic&lt;/a&gt;,
and expose custom search API within the enterprise.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We questioned their conclusions, asked why did they think Elastic will give much better
results, asked did they try to figure out why SharePoint give no desired results.
&lt;/p&gt;
&lt;p&gt;
Answers did not convince us though we have joined the project.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
What do you think? Elastic did not help at all though they hoped very much that its
query language will help to rank results in a way that matched documents will be found.
After all they thought it was a problem of ranking of results.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Here we have started our analysis. We took a specific document that must be found
but is never returned from search.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
It turned to be well known problem, at least we dealt with closely related one in
the past. There are two ingredients here:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
documents that have low chances to be found are PDFs;&lt;/li&gt;
&lt;li&gt;
we live in Israel, so most texts are Hebrew, which means words are written from right
to left, while some other texts from left to right. See &lt;a href="https://en.wikipedia.org/wiki/Bi-directional_text" target="_blank"&gt;Bi-directional
text&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Traditionally PDF documents are provided in a way that only distantly resembles logical
structure of original content. E.g., paragraphs of texts are often represented as
unrelated runs of text lines, or as set of text runs representing single words, or
independant characters. No need to say that additional complication comes from that
Hebrew text are often represented visually (from left to right, as if &amp;quot;hello&amp;quot;
would be stored as &amp;quot;olleh&amp;quot; and would be just printed from right to left).
Another common feature of PDF are custom fonts with uncanonical mappings, or images
with glyphs of letters.
&lt;/p&gt;
&lt;p&gt;
You can implement these tricks in other document formats but for some reason PDF is
only format we have seen that regularly and intensively uses these techniques.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
At this point we have realized that it&amp;#39;s not a fault of a search engine to find
the document but the feature of the PDF to expose its text to a crawler in a form
that cannot be used for search. In fact, PDF cannot search by itself in such documents,
as when you try to find some text in the document opened in a pdf viewer, that you
clearly see in the document, you often find nothing.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
A question. What should you do in this case when no any PDF text extractor can give
you correct text but text is there when you looking at document in a pdf viewer?
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We decided it&amp;#39;s time to go in the direction of image recognition. Thankfully,
nowdays it&amp;#39;s a matter of available processing resources.
&lt;/p&gt;
&lt;p&gt;
Our goal was:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Have images of each PDF page. This task is immediately solved with &lt;a href="https://pdfbox.apache.org/" target="_blank"&gt;Apache
PDFBox (A Java PDF Library) - it's time to say this is java project.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Run Optical Character Recognition (OCR) over images, and get extracted texts. This
is perfectly done by &lt;a href="https://github.com/tesseract-ocr/tesseract" target="_blank"&gt;tesseract-ocr/tesseract&lt;/a&gt;,
and thankfully to its java wrapper &lt;a href="https://github.com/bytedeco/javacpp-presets/tree/master/tesseract" target="_blank"&gt;bytedeco/javacpp-presets&lt;/a&gt; we
can immediately call this C++ API from java.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The only small nuisance of tesseract is that it does not expose table recognition
info, but we can easily overcome it (we solved this task in the past), as along with
each text run tesseract exposes its position.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
What are results of the run of such program?
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Full success! It works with high quality of recognition. Indeed, there is no any physical
noise that impacts quality.&lt;/li&gt;
&lt;li&gt;
Slow speed - up to several seconds per recognition per page.&lt;/li&gt;
&lt;li&gt;
Scalable solution. Slow speed can be compensated by almost unlimited theoretical scalability.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
So, what is the lesson we have taked from this experience?
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Well, you should question yourself, test and verify ideas on the ground before building
any theories that will lead you in completely wrong direction. After all people started
to realize there was no need to claim on SharePoint, to throw it, and to spend great
deal of time and money just to prove that the problem is in the different place.
&lt;/p&gt;
&lt;p&gt;
A sample source code can be found at &lt;a href="https://github.com/nesterovsky-bros/pdf.ocr/blob/master/src/main/java/nesterovskyBros/pdf/ocr/App.java" target="_blank"&gt;App.java&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=861382a1-a2b8-4b39-a9f4-1f7a2148bf59" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</comments>
      <category>C++</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=65627bb9-7d3e-4769-98e8-efdc138d9179</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,65627bb9-7d3e-4769-98e8-efdc138d9179.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=65627bb9-7d3e-4769-98e8-efdc138d9179</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In some code we needed to perform a circular shift of a part of array, like on the
following picture:
</p>
        <p>
          <img style="height: 10em;" src="data:image/png;base64,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" alt="" />
        </p>
        <p>
It's clear what to do, especially in case of one element shift but think about
"optimal" algorithm that does minimal number of data movemenents.
</p>
        <p>
Here is what we have came up with in C#: algorithm doing single pass over data.
</p>
        <blockquote>
          <pre>/// &lt;summary&gt;
/// &lt;para&gt;
/// Moves content of list within open range &lt;code&gt;[start, end)&lt;/code&gt;. 
/// &lt;code&gt;to&lt;/code&gt; should belong to that range.
/// &lt;/para&gt;
/// &lt;para&gt;
/// &lt;code&gt;list[start + (to - start + i) mod (end - start)] = 
/// list[start + i]&lt;/code&gt;, 
/// where i in range&lt;code&gt;[0, end - start)&lt;/ code &gt;.
/// &lt;/para&gt;
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;An element type.&lt;/typeparam&gt;
/// &lt;param name="list"&gt;A list to move data withing.&lt;/param&gt;
/// &lt;param name="start"&gt;Start position, including.&lt;/param&gt;
/// &lt;param name="end"&gt;End position, not incuding.&lt;/param&gt;
/// &lt;param name="to"&gt;Target position.&lt;/param&gt;
public static void CircularMove&lt;T&gt;(IList&lt;T&gt; list, int start, int end, int to)
{
  var size = end - start;
  var step = to - start;
  var anchor = start;
  var pos = start;
  var item = list[pos];

  for(int i = 0; i &lt; size; ++i)
  {
    pos += step;

    if (pos &gt;= end)
    {
      pos -= size;
    }

    var next = list[pos];

    list[pos] = item;
    item = next;

    if (pos == anchor)
    {
      pos = ++anchor;

      if (pos &gt;= end)
      {
        break;
      }

      item = list[pos];
    }
  }
}</pre>
        </blockquote>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=65627bb9-7d3e-4769-98e8-efdc138d9179" />
      </body>
      <title>Circular shift</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,65627bb9-7d3e-4769-98e8-efdc138d9179.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/06/07/CircularShift.aspx</link>
      <pubDate>Thu, 07 Jun 2018 10:20:27 GMT</pubDate>
      <description>  &lt;p&gt;
In some code we needed to perform a circular shift of a part of array, like on the
following picture:
&lt;/p&gt;
&lt;p&gt;
&lt;img style="height: 10em;" src="data:image/png;base64,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" alt="" /&gt; 
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s clear what to do, especially in case of one element shift but think about
&amp;quot;optimal&amp;quot; algorithm that does minimal number of data movemenents.
&lt;/p&gt;
&lt;p&gt;
Here is what we have came up with in C#: algorithm doing single pass over data.
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;/// &amp;lt;summary&gt;
/// &amp;lt;para&gt;
/// Moves content of list within open range &amp;lt;code&gt;[start, end)&amp;lt;/code&gt;. 
/// &amp;lt;code&gt;to&amp;lt;/code&gt; should belong to that range.
/// &amp;lt;/para&gt;
/// &amp;lt;para&gt;
/// &amp;lt;code&gt;list[start + (to - start + i) mod (end - start)] = 
/// list[start + i]&amp;lt;/code&gt;, 
/// where i in range&amp;lt;code&gt;[0, end - start)&amp;lt;/ code &gt;.
/// &amp;lt;/para&gt;
/// &amp;lt;/summary&gt;
/// &amp;lt;typeparam name="T"&gt;An element type.&amp;lt;/typeparam&gt;
/// &amp;lt;param name="list"&gt;A list to move data withing.&amp;lt;/param&gt;
/// &amp;lt;param name="start"&gt;Start position, including.&amp;lt;/param&gt;
/// &amp;lt;param name="end"&gt;End position, not incuding.&amp;lt;/param&gt;
/// &amp;lt;param name="to"&gt;Target position.&amp;lt;/param&gt;
public static void CircularMove&amp;lt;T&gt;(IList&amp;lt;T&gt; list, int start, int end, int to)
{
  var size = end - start;
  var step = to - start;
  var anchor = start;
  var pos = start;
  var item = list[pos];

  for(int i = 0; i &amp;lt; size; ++i)
  {
    pos += step;

    if (pos &gt;= end)
    {
      pos -= size;
    }

    var next = list[pos];

    list[pos] = item;
    item = next;

    if (pos == anchor)
    {
      pos = ++anchor;

      if (pos &gt;= end)
      {
        break;
      }

      item = list[pos];
    }
  }
}&lt;/pre&gt;&lt;/blockquote&gt; &lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=65627bb9-7d3e-4769-98e8-efdc138d9179" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,65627bb9-7d3e-4769-98e8-efdc138d9179.aspx</comments>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d5f3031a-b737-4566-a963-75011df3015a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d5f3031a-b737-4566-a963-75011df3015a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d5f3031a-b737-4566-a963-75011df3015a</wfw:commentRss>
      <title>JAXB and java.time.* types</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d5f3031a-b737-4566-a963-75011df3015a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/01/24/JAXBAndJavatimeTypes.aspx</link>
      <pubDate>Wed, 24 Jan 2018 06:46:41 GMT</pubDate>
      <description>  &lt;p&gt;
J2SE has become sole large that its different parts don&amp;#39;t play well.
&lt;/p&gt;
&lt;p&gt;
That is pitty but nothing to do. There is probably a lack of resources in Oracle to
fill gaps.
&lt;/p&gt;
&lt;p&gt;
So, to the point. 
&lt;/p&gt;
&lt;p&gt;
There is relatively new API to work with time defined in: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html"&gt;package
java.time&lt;/a&gt;. There is older API &lt;a href="https://docs.oracle.com/javase/8/docs/technotes/guides/xml/jaxb/index.html"&gt;JAXB&lt;/a&gt; to
serialize and deserialize beans to and from XML (and often to JSON). To JAXB viable,
it should be able to deal with basic primitive types. The problem is that JAXB does
not handle &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html"&gt;LocalDate&lt;/a&gt;, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html"&gt;LocalTime&lt;/a&gt;, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html"&gt;LocalDateTime&lt;/a&gt;,
and &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html"&gt;ZonedDateTime&lt;/a&gt; out
of the box.
&lt;/p&gt;
&lt;p&gt;
We do understand that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
JAXB is older and java.time is newer API; and that&lt;/li&gt;
&lt;li&gt;
JAXB has no built-in plugin to handle new types.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
But this does not help, and we should define/redefine serialization adapters using
some drop in code or third party libraries. Here are these convenience adapters:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;b&gt;LocalDateAdapter.java&lt;/b&gt;
&lt;/p&gt;
&lt;pre&gt;&lt; 0)
    {
      return LocalDate.parse(value);
    }
    
    while(++p &lt; value.length())
    {
      switch(value.charAt(p)) 
      {
        case '+':
        case '-':
        case 'Z':
        {
          return ZonedDateTime.parse(value).toLocalDate();
        }
      }
      
    }
    
    return LocalDateTime.parse(value).toLocalDate();
  }
}&lt;/pre&gt;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * An adapter for the bean properties of {@link LocalDate} type. 
 */
public class LocalDateAdapter extends XmlAdapter&amp;lt;String, LocalDate&gt;
{
  /**
   * Converts {@link LocalDate} into a string value.
   * @param value a value to convert. Can be null.
   * @return a string value.
   */
  @Override
  public String marshal(LocalDate value)
    throws Exception
  {
    return value == null ? null : value.toString();
  }

  /**
   * Converts a string value into a {@link LocalDate}
   * instance.
   * @param value a value to convert. Can be null.
   * @return a {@link LocalDate} instance.
   */
  @Override
  public LocalDate unmarshal(String value)
    throws Exception
  {
    if (value == null)
    {
      return null;
    }
    
    int p = value.indexOf('T');
    
    if (p 
        
&lt;p&gt;
&lt;b&gt;LocalDateTimeAdapter.java&lt;/b&gt;
&lt;/p&gt;
&lt;pre&gt;&lt; 0)
    {
      return LocalDateTime.of(LocalDate.parse(value), LocalTime.MIN);
    }
    
    while(++p &lt; value.length())
    {
      switch(value.charAt(p)) 
      {
        case '+':
        case '-':
        case 'Z':
        {
          return ZonedDateTime.parse(value).toLocalDateTime();
        }
      }
      
    }
    
    return LocalDateTime.parse(value);
  }
}&lt;/pre&gt;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * An adapter for the bean properties of {@link LocalDateTime} type. 
 */
public class LocalDateTimeAdapter extends XmlAdapter&amp;lt;String, LocalDateTime&gt;
{
  /**
   * Converts {@link LocalDateTime} into a string value.
   * @param value a value to convert. Can be null.
   * @return a string value.
   */
  @Override
  public String marshal(LocalDateTime value)
    throws Exception
  {
    return value == null ? null : value.toString();
  }

  /**
   * Converts a string value into a {@link LocalDateTime}  instance.
   * @param value a value to convert. Can be null.
   * @return a {@link LocalDateTime} instance.
   */
  @Override
  public LocalDateTime unmarshal(String value) 
    throws Exception
  {
    if (value == null)
    {
      return null;
    }
    
    int p = value.indexOf('T');
    
    if (p 
        
&lt;p&gt;
&lt;b&gt;LocalTimeAdapter.java&lt;/b&gt;
&lt;/p&gt;
&lt;pre&gt;import java.time.LocalDate;import java.time.LocalTime;

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * An adapter for the bean properties of {@link LocalTime} type. 
 */
public class LocalTimeAdapter extends XmlAdapter&amp;lt;String, LocalTime&gt;
{
  /**
   * Converts {@link LocalTime} into string value.
   * @param value a value to convert. Can be null.
   * @return a string value
   */
  @Override
  public String marshal(LocalTime value)
    throws Exception
  {
    return value == null ? null : value.toString();
  }

  /**
   * Converts a string value into a {@link LocalTime} instance.
   * @param value a value to convert. Can be null.
   * @return a {@link LocalTime} instance.
   */
  @Override
  public LocalTime unmarshal(String value)
    throws Exception
  {
    return value == null ? null : LocalTime.parse(value);
  }
}
&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To make them work either field/properties or package should be annotated with JAXB
xml adapters.
&lt;/p&gt;
&lt;p&gt;
The simplest way is to annotate it on package level like this:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;b&gt;package-info.java&lt;/b&gt;
&lt;/p&gt;
&lt;pre&gt;@XmlJavaTypeAdapters(
{
  @XmlJavaTypeAdapter(value = LocalDateAdapter.class, type = LocalDate.class),
  @XmlJavaTypeAdapter(value = LocalTimeAdapter.class, type = LocalTime.class),
  @XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class, type = LocalDateTime.class)
})
package com.nesterovskyBros.demo.entities;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
&lt;/pre&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d5f3031a-b737-4566-a963-75011df3015a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d5f3031a-b737-4566-a963-75011df3015a.aspx</comments>
      <category>Java</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0d98518f-b70e-4cb7-9e10-0004ebfc43b3</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0d98518f-b70e-4cb7-9e10-0004ebfc43b3.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0d98518f-b70e-4cb7-9e10-0004ebfc43b3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've run into following java function that models some variation of NULL arithmetic:
</p>
        <blockquote>
          <pre>public static Long add(Long value1, Long value2)
{
  return value1 == null ? value2 : value2 == null ? value1 : value1 + value2;
}</pre>
        </blockquote>
        <p>
When this function runs the outcome is different from what we have expected.
</p>
        <p>
Here is a quiz:
</p>
        <ol>
          <li>
            <p>
What is outcome of <code>add(1, 2)</code>:
</p>
            <ol style="list-style-type: lower-alpha">
              <li>
                <code>3</code>;</li>
              <li>
                <code>null</code>;</li>
              <li>
other.</li>
            </ol>
          </li>
          <li>
            <p>
What is outcome of <code>add(3, null)</code>:
</p>
            <ol style="list-style-type: lower-alpha">
              <li>
                <code>3</code>;</li>
              <li>
                <code>null</code>;</li>
              <li>
other.</li>
            </ol>
          </li>
          <li>
            <p>
What is outcome of <code>add(null, 4)</code>:
</p>
            <ol style="list-style-type: lower-alpha">
              <li>
                <code>null</code>;</li>
              <li>
                <code>4</code>;</li>
              <li>
other.</li>
            </ol>
          </li>
          <li>
            <p>
What is outcome of <code>add(null, null)</code>:
</p>
            <ol style="list-style-type: lower-alpha">
              <li>
                <code>null</code>;</li>
              <li>
                <code>0</code>;</li>
              <li>
other.</li>
            </ol>
          </li>
        </ol>
        <p>
Our assumptions were:
</p>
        <ol>
          <li>
            <code>add(1, 2) == 3</code>;</li>
          <li>
            <code>add(3, null) == 3</code>;</li>
          <li>
            <code>add(null, 4) == 4</code>;</li>
          <li>
            <code>add(null, null) == null</code>;</li>
        </ol>
        <p>
Java works differently:
</p>
        <ol>
          <li>
            <code>add(1, 2) == 3</code>;</li>
          <li>
            <code>add(3, null) throws NullPointerException</code>;</li>
          <li>
            <code>add(null, 4) throws NullPointerException</code>;</li>
          <li>
            <code>add(null, null) throws NullPointerException</code>;</li>
        </ol>
        <p>
The problem is with compile time type of ternary <code>?:</code> operator. Compiler
decides it's <code>long</code>, while we intuitively expected <code>Long</code>. Java
casts <code>null</code> to <code>long</code> (which results into <code>NPE</code>),
and then to <code>Long</code>.
</p>
        <p>
Correct code would be:
</p>
        <blockquote>
          <pre>public static Long add(Long value1, Long value2)
{
  if (value1 == null)
  {
    return value2;
  }
  else if (value2 == null)
  {
    return value;
  }
  else
  {
    return value1 + value2;
  }
}</pre>
        </blockquote>
        <p>
This version does not cast anything to <code>long</code>, and works as we originally
expected.
</p>
        <p>
Honestly, we're a bit anexious about this subtle difference of <code>if-then-else</code> and <code>?:</code> operator.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0d98518f-b70e-4cb7-9e10-0004ebfc43b3" />
      </body>
      <title>Ternary expression type in java.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0d98518f-b70e-4cb7-9e10-0004ebfc43b3.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2017/11/22/TernaryExpressionTypeInJava.aspx</link>
      <pubDate>Wed, 22 Nov 2017 12:00:23 GMT</pubDate>
      <description>  &lt;p&gt;
We&amp;#39;ve run into following java function that models some variation of NULL arithmetic:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public static Long add(Long value1, Long value2)
{
  return value1 == null ? value2 : value2 == null ? value1 : value1 + value2;
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
When this function runs the outcome is different from what we have expected.
&lt;/p&gt;
&lt;p&gt;
Here is a quiz:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
What is outcome of &lt;code&gt;add(1, 2)&lt;/code&gt;:
&lt;/p&gt;
&lt;ol style="list-style-type: lower-alpha"&gt;
&lt;li&gt;
&lt;code&gt;3&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
other.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
What is outcome of &lt;code&gt;add(3, null)&lt;/code&gt;:
&lt;/p&gt;
&lt;ol style="list-style-type: lower-alpha"&gt;
&lt;li&gt;
&lt;code&gt;3&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
other.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
What is outcome of &lt;code&gt;add(null, 4)&lt;/code&gt;:
&lt;/p&gt;
&lt;ol style="list-style-type: lower-alpha"&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
other.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
What is outcome of &lt;code&gt;add(null, null)&lt;/code&gt;:
&lt;/p&gt;
&lt;ol style="list-style-type: lower-alpha"&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
other.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Our assumptions were:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;add(1, 2) == 3&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(3, null) == 3&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(null, 4) == 4&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(null, null) == null&lt;/code&gt;;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Java works differently:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;add(1, 2) == 3&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(3, null) throws NullPointerException&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(null, 4) throws NullPointerException&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add(null, null) throws NullPointerException&lt;/code&gt;;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The problem is with compile time type of ternary &lt;code&gt;?:&lt;/code&gt; operator. Compiler
decides it's &lt;code&gt;long&lt;/code&gt;, while we intuitively expected &lt;code&gt;Long&lt;/code&gt;. Java
casts &lt;code&gt;null&lt;/code&gt; to &lt;code&gt;long&lt;/code&gt; (which results into &lt;code&gt;NPE&lt;/code&gt;),
and then to &lt;code&gt;Long&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Correct code would be:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public static Long add(Long value1, Long value2)
{
  if (value1 == null)
  {
    return value2;
  }
  else if (value2 == null)
  {
    return value;
  }
  else
  {
    return value1 + value2;
  }
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This version does not cast anything to &lt;code&gt;long&lt;/code&gt;, and works as we originally
expected.
&lt;/p&gt;
&lt;p&gt;
Honestly, we&amp;#39;re a bit anexious about this subtle difference of &lt;code&gt;if-then-else&lt;/code&gt; and &lt;code&gt;?:&lt;/code&gt; operator.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0d98518f-b70e-4cb7-9e10-0004ebfc43b3" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0d98518f-b70e-4cb7-9e10-0004ebfc43b3.aspx</comments>
      <category>Java</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d3a361e2-aecf-42ee-bc86-64872392d78f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d3a361e2-aecf-42ee-bc86-64872392d78f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d3a361e2-aecf-42ee-bc86-64872392d78f</wfw:commentRss>
      <title>group-combinator</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d3a361e2-aecf-42ee-bc86-64872392d78f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/03/10/groupcombinator.aspx</link>
      <pubDate>Thu, 10 Mar 2016 11:31:48 GMT</pubDate>
      <description>&lt;p&gt;
Our recent task required us to find all sets of not intersecting rectangles for a
rectangle list.
&lt;/p&gt;
&lt;p&gt;
At first glance it did not look like a trivial task. Just consider that for a list
of &lt;code&gt;N&lt;/code&gt; rectangles you can form &lt;code&gt;2^N&lt;/code&gt; different subsets. So,
even result list, theoretically, can be enormous.
&lt;/p&gt;
&lt;p&gt;
Fortunately, we knew that our result will be manageable in size. But nevertheless,
suppose you have a list of couple of hundred rectangles, how would you enumerate all
different sets of rectangles?
&lt;/p&gt;
&lt;p&gt;
By the way, this task sounds the same as one of a Google interview's question. So,
you may try to solve it by yourself before to check our solution.
&lt;/p&gt;
&lt;p&gt;
We didn't even dare to think of brute-force solution: to enumerate all sets and then
check each one whether it fits our needs.
&lt;/p&gt;
&lt;p&gt;
Instead we used induction:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Suppose S(N) - is an solution for our task for N rectangles R(n), where S(N) is a
set of sets of rectangles;&lt;/li&gt;
&lt;li&gt;
Then solution for S(N+1) will contain whole S(N), R(N+1) - a set consisting of single
rectangle, and some sets of rectangles from S(N) combinded with R(N+1) provided they
fit the condition;&lt;/li&gt;
&lt;li&gt;
S(0) - is an empty set.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The algorithm was implemented in java, and at first it was using &lt;a href="http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html"&gt;Streaming&lt;/a&gt; and
recursion.
&lt;/p&gt;
&lt;p&gt;
Then we have figured out that we can use &lt;a href="https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html"&gt;Stream.reduce
or Stream.collect&lt;/a&gt; to implement the same algorithm. That second implementation
was a little bit longer but probably faster, and besides it used standard idioms.
&lt;/p&gt;
&lt;p&gt;
But then at last step we reformulated the algorithms in terms of &lt;a href="https://docs.oracle.com/javase/tutorial/collections/"&gt;Collections&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Though the final implementation is the least similar to original induction algorithm,
it's straightforward and definitely fastest among all implementations we tried.
&lt;/p&gt;
&lt;p&gt;
So, here is the code:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;&gt;();
  
  for(T item: items)
  {
    int size = result.size();
    
    result.add(combiner.apply(identity, item));
   
    for(int i = 0; i &amp;lt; size; ++i)
    {
      G group = result.get(i);
      
      if (matcher.test(group, item))
      {
        result.add(combiner.apply(group, item));
      }
    }
  }
    
  return result;
}&lt;/pre&gt;/**
 * For a sequence of items builds a list of matching groups.
 * @param identity an identity instance used for the group.
 * @param items original sequence of items.
 * @param matcher a group matcher of item against a group.
 * @param combiner creates a new group from a group (optional) and an item.
 * @return a list of matching groups.
 */
public static &amp;lt;T, G&gt; List&amp;lt;G&gt; matchingGroups(
  G identity,
  Iterable&amp;lt;T&gt; items, 
  BiPredicate&amp;lt;G, T&gt; matcher,
  BiFunction&amp;lt;G, T, G&gt; combiner)
{
  ArrayList&amp;lt;G&gt; result = new ArrayList
&lt;/blockquote&gt; 
&lt;p&gt;
The &lt;a href="https://github.com/nesterovsky-bros/group-combinator"&gt;sample project
on GitHub&lt;/a&gt; contains implementation and a tests of this algorithm.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d3a361e2-aecf-42ee-bc86-64872392d78f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d3a361e2-aecf-42ee-bc86-64872392d78f.aspx</comments>
      <category>Java</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=362e155c-8943-4212-86af-7eef166208ab</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,362e155c-8943-4212-86af-7eef166208ab.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,362e155c-8943-4212-86af-7eef166208ab.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=362e155c-8943-4212-86af-7eef166208ab</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's very old theme...
</p>
        <p>
Many years ago we have defined a .NET wrapper around Windows Uniscribe API.
</p>
        <p>
Uniscribe API is used to render bidirectional languages like Hebrew, so it's important
mainly here in Israel.
</p>
        <p>
Once in a while we get request from people to give that API, so we published it on
GitHub at <a href="https://github.com/nesterovsky-bros/BidiVisualConverter">https://github.com/nesterovsky-bros/BidiVisualConverter</a>.
</p>
        <p>
You're welcome to use it!
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=362e155c-8943-4212-86af-7eef166208ab" />
      </body>
      <title>BidiVisualConverter</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,362e155c-8943-4212-86af-7eef166208ab.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/01/14/BidiVisualConverter.aspx</link>
      <pubDate>Thu, 14 Jan 2016 14:19:54 GMT</pubDate>
      <description>&lt;p&gt;
It's very old theme...
&lt;/p&gt;
&lt;p&gt;
Many years ago we have defined a .NET wrapper around Windows Uniscribe API.
&lt;/p&gt;
&lt;p&gt;
Uniscribe API is used to render bidirectional languages like Hebrew, so it's important
mainly here in Israel.
&lt;/p&gt;
&lt;p&gt;
Once in a while we get request from people to give that API, so we published it on
GitHub at &lt;a href="https://github.com/nesterovsky-bros/BidiVisualConverter"&gt;https://github.com/nesterovsky-bros/BidiVisualConverter&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
You're welcome to use it!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=362e155c-8943-4212-86af-7eef166208ab" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,362e155c-8943-4212-86af-7eef166208ab.aspx</comments>
      <category>.NET</category>
      <category>Announce</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=f32e07e2-cda3-4dc6-99d7-6e435a6edbda</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f32e07e2-cda3-4dc6-99d7-6e435a6edbda.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=f32e07e2-cda3-4dc6-99d7-6e435a6edbda</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We have solved this problem years ago, but have run into it once again.
</p>
        <p>
So, we shall log the solution here.
</p>
        <p>
The problem: to minify payload of the JAXB serialized beans.
</p>
        <p>
Java beans have many properties most of them contains default values: zero ints, empty
strings, and so on.
</p>
        <p>
JAXB never tries to omit default value from marshalled xml, the only thing it can
remove from output is null values. So, our approach is to define xml adapter to map
default values to nulls.
</p>
        <p>
Here we refer to the StackOverflow question: <a href="http://stackoverflow.com/questions/28340772/prevent-writing-default-attribute-values-jaxb">Prevent
writing default attribute values JAXB</a>, and to <a href="http://stackoverflow.com/a/31863906/831007">our
answer</a>. 
</p>
        <p>
Though it's not as terse as one would wish, one can create XmlAdapters to avoid
marshalling the default values.
</p>
        <p>
The use case is like this:
</p>
        <blockquote>
          <pre>@XmlRootElement(name = "FIELD")
public class TestLayoutNode
{
  @XmlAttribute(name = "num")
  @XmlJavaTypeAdapter(value = IntegerZero.class, type = int.class)
  public int number;

  @XmlAttribute(name = "str")
  @XmlJavaTypeAdapter(StringDefault.class)
  public String str = "default";
}</pre>
        </blockquote>
        <p>
And here are adapters.
</p>
        <p>
IntegerZero:
</p>
        <blockquote>
          <pre>public class IntegerZero extends DefaultValue&lt;Integer&gt;
{
  public Integer defaultValue() { return 0; }
}</pre>
        </blockquote>
        <p>
StringDefault:
</p>
        <blockquote>
          <pre>public class StringDefault extends DefaultValue&lt;String&gt;
{
  public String defaultValue() { return "default"; }
}</pre>
        </blockquote>
        <p>
DefaultValueAdapter:
</p>
        <blockquote>
          <pre>public class DefaultValue&lt;T&gt; extends XmlAdapter&lt;T, T&gt;
{
  public T defaultValue() { return null; }

  public T marshal(T value) throws Exception
  {
    return (value == null) || value.equals(defaultValue()) ? null : value;
  }

  public T unmarshal(T value) throws Exception
  {
    return value;
  }
}</pre>
        </blockquote>
        <p>
With small number of different default values this approach works well.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f32e07e2-cda3-4dc6-99d7-6e435a6edbda" />
      </body>
      <title>Marshalling default value with JAXB</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f32e07e2-cda3-4dc6-99d7-6e435a6edbda.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/08/06/MarshallingDefaultValueWithJAXB.aspx</link>
      <pubDate>Thu, 06 Aug 2015 20:01:23 GMT</pubDate>
      <description>&lt;p&gt;
We have solved this problem years ago, but have run into it once again.
&lt;/p&gt;
&lt;p&gt;
So, we shall log the solution here.
&lt;/p&gt;
&lt;p&gt;
The problem: to minify payload of the JAXB serialized beans.
&lt;/p&gt;
&lt;p&gt;
Java beans have many properties most of them contains default values: zero ints, empty
strings, and so on.
&lt;/p&gt;
&lt;p&gt;
JAXB never tries to omit default value from marshalled xml, the only thing it can
remove from output is null values. So, our approach is to define xml adapter to map
default values to nulls.
&lt;/p&gt;
&lt;p &gt;
Here we refer to the StackOverflow question: &lt;a href="http://stackoverflow.com/questions/28340772/prevent-writing-default-attribute-values-jaxb"&gt;Prevent
writing default attribute values JAXB&lt;/a&gt;, and to &lt;a href="http://stackoverflow.com/a/31863906/831007"&gt;our
answer&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Though it&amp;#39;s not as terse as one would wish, one can create XmlAdapters to avoid
marshalling the default values.
&lt;/p&gt;
&lt;p&gt;
The use case is like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;@XmlRootElement(name = &amp;quot;FIELD&amp;quot;)
public class TestLayoutNode
{
  @XmlAttribute(name = &amp;quot;num&amp;quot;)
  @XmlJavaTypeAdapter(value = IntegerZero.class, type = int.class)
  public int number;

  @XmlAttribute(name = &amp;quot;str&amp;quot;)
  @XmlJavaTypeAdapter(StringDefault.class)
  public String str = &amp;quot;default&amp;quot;;
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And here are adapters.
&lt;/p&gt;
&lt;p&gt;
IntegerZero:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public class IntegerZero extends DefaultValue&amp;lt;Integer&amp;gt;
{
  public Integer defaultValue() { return 0; }
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
StringDefault:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public class StringDefault extends DefaultValue&amp;lt;String&amp;gt;
{
  public String defaultValue() { return &amp;quot;default&amp;quot;; }
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
DefaultValueAdapter:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public class DefaultValue&amp;lt;T&amp;gt; extends XmlAdapter&amp;lt;T, T&amp;gt;
{
  public T defaultValue() { return null; }

  public T marshal(T value) throws Exception
  {
    return (value == null) || value.equals(defaultValue()) ? null : value;
  }

  public T unmarshal(T value) throws Exception
  {
    return value;
  }
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
With small number of different default values this approach works well.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f32e07e2-cda3-4dc6-99d7-6e435a6edbda" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,f32e07e2-cda3-4dc6-99d7-6e435a6edbda.aspx</comments>
      <category>Java</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9ab00999-60e6-4106-ad73-9e5359ee93c5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ab00999-60e6-4106-ad73-9e5359ee93c5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Though <a href="https://msdn.microsoft.com/en-us/library/e80y5yhx(v=vs.110).aspx">ADO.NET</a> and
other ORM framworks like <a href="https://msdn.microsoft.com/en-us/data/ef.aspx">EntityFramework</a> and <a href="https://github.com/StackExchange/dapper-dot-net">Dapper</a> support
async pattern, you should remember that database drivers (at least all we know about)
do not support concurrent db commands running against a single connection.
</p>
        <p>
To see what we mean consider a bug we have recently identified. Consider a code:
</p>
        <blockquote>
          <pre>await Task.WhenAll(
  newImages.
    Select(
      async image =&gt;
      {
        // Load data from url.
        image.Content = await HttpUtils.ReadData(image.Url);

        // Insert image into the database.
        image.ImageID = await context.InsertImage(image);
      }));
</pre>
        </blockquote>
        <p>
The code runs multiple tasks to read images, and to write them into a database. 
</p>
        <p>
Framework decides to run all these tasks in parallel. <code>HttpUtils.ReadData()</code> has
no problem with parallel execution, while <code>context.InsertImage()</code> does
not run well in parallel, and is a subject of race conditions.
</p>
        <p>
To workaround the problem we had to use async variant of a critical section. So the
fixed code looks like this:
</p>
        <blockquote>
          <pre>
            <b>using(var semaphore = new SemaphoreSlim(1))</b> { await Task.WhenAll(
newImages. Select( async image =&gt; { // Load data from url. image.Content = await HttpUtils.ReadData(image.Url); <b>await
semaphore.WaitAsync();</b> try { // Insert image into the database. image.ImageID
= await context.InsertImage(image); } finally { <b>semaphore.Release();</b> } }));
} </pre>
        </blockquote>
        <p>
So, in the async world we still should care about race conditions.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ab00999-60e6-4106-ad73-9e5359ee93c5" />
      </body>
      <title>Database async trap</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/07/27/DatabaseAsyncTrap.aspx</link>
      <pubDate>Mon, 27 Jul 2015 06:44:45 GMT</pubDate>
      <description>  &lt;p&gt;
Though &lt;a href="https://msdn.microsoft.com/en-us/library/e80y5yhx(v=vs.110).aspx"&gt;ADO.NET&lt;/a&gt; and
other ORM framworks like &lt;a href="https://msdn.microsoft.com/en-us/data/ef.aspx"&gt;EntityFramework&lt;/a&gt; and &lt;a href="https://github.com/StackExchange/dapper-dot-net"&gt;Dapper&lt;/a&gt; support
async pattern, you should remember that database drivers (at least all we know about)
do not support concurrent db commands running against a single connection.
&lt;/p&gt;
&lt;p&gt;
To see what we mean consider a bug we have recently identified. Consider a code:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;await Task.WhenAll(
  newImages.
    Select(
      async image =&gt;
      {
        // Load data from url.
        image.Content = await HttpUtils.ReadData(image.Url);

        // Insert image into the database.
        image.ImageID = await context.InsertImage(image);
      }));
&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The code runs multiple tasks to read images, and to write them into a database. 
&lt;/p&gt;
&lt;p&gt;
Framework decides to run all these tasks in parallel. &lt;code&gt;HttpUtils.ReadData()&lt;/code&gt; has
no problem with parallel execution, while &lt;code&gt;context.InsertImage()&lt;/code&gt; does
not run well in parallel, and is a subject of race conditions.
&lt;/p&gt;
&lt;p&gt;
To workaround the problem we had to use async variant of a critical section. So the
fixed code looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;b&gt;using(var semaphore = new SemaphoreSlim(1))&lt;/b&gt; { await Task.WhenAll(
newImages. Select( async image =&gt; { // Load data from url. image.Content = await HttpUtils.ReadData(image.Url); &lt;b&gt;await
semaphore.WaitAsync();&lt;/b&gt; try { // Insert image into the database. image.ImageID
= await context.InsertImage(image); } finally { &lt;b&gt;semaphore.Release();&lt;/b&gt; } }));
} &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
So, in the async world we still should care about race conditions.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ab00999-60e6-4106-ad73-9e5359ee93c5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0150d335-2a50-40c9-ac37-07460ed21cbb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0150d335-2a50-40c9-ac37-07460ed21cbb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0150d335-2a50-40c9-ac37-07460ed21cbb.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0150d335-2a50-40c9-ac37-07460ed21cbb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In our angularjs projects we are often dealing with existing models that do not always
fit to angularjs expectations.
</p>
        <p>
Here is an example.
</p>
        <p>
There is a model consisting of two arrays: for data, and for associated data. How
to create an <a href="https://docs.angularjs.org/api/ng/directive/ngRepeat"><code>ng-repeat</code></a> that
displays data from both sources?
</p>
        <p>
Consider a test controller (see a <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/ui-eval.html">github</a> sources,
and a <a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/ui-eval.html">rawgit</a> working
sample):
</p>
        <pre style="padding-left: 1em">
model.controller(
  "Test",
  function()
  {
    this.records =
    [
      { name: "record 1", state: "Draft" },
      { name: "record 2", state: "Public" },
      { name: "record 3", state: "Disabled" },
      { name: "record 4", state: "Public" },
      { name: "record 5", state: "Public" }
    ];

    this.more =
    [
      { value: 1, selected: true, visible: true },
      { value: 2, selected: false, visible: true },
      { value: 3, selected: true, visible: true },
      { value: 4, selected: false, visible: false },
      { value: 5, selected: false, visible: true }
    ];

    this.delete = function(index)
    {
      this.records.splice(index, 1);
      this.more.splice(index, 1);
    };
  });</pre>
        <p>
Basically there are three approaches here:
</p>
        <ol>
          <li>
Change model.</li>
          <li>
Adapt model to a single collection.</li>
          <li>
            <a href="https://docs.angularjs.org/api/ng/directive/ngRepeat">
              <code>ng-repeat</code>
            </a> over
first array and access the second array using <code>$index</code> scope variable.</li>
        </ol>
        <p>
We argued like this:
</p>
        <ul>
          <li>
It is often not an option to change a model, as it's how business data are described.</li>
          <li>
A model adaptation when we build a single collection from original two collections,
and synchronize it back (if required) may unnecessary complicate things. 
</li>
          <li>
Thus let's get associated items by <code>$index</code> variable.</li>
        </ul>
        <p>
This is an example of <a href="https://docs.angularjs.org/api/ng/directive/ngRepeat"><code>ng-repeat</code></a> use:
</p>
        <pre style="padding-left: 1em">&lt;table border="1"&gt;
  &lt;tr&gt;
    &lt;th&gt;[x]&lt;/th&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Value&lt;/th&gt;
    &lt;th&gt;State&lt;/th&gt;
    &lt;th&gt;Actions&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr ng-repeat="item in test.records track by $index"
    ng-if="<b>test.more[$index].visible</b>"&gt;
&lt;td&gt; &lt;input type="checkbox" ng-model="<b>test.more[$index].selected</b>"/&gt; &lt;/td&gt;
&lt;td&gt;{{item.name}}&lt;/td&gt; &lt;td&gt;{{<b>test.more[$index].value</b>}}&lt;/td&gt; &lt;td&gt;{{item.state}}&lt;/td&gt;
&lt;td&gt; &lt;a href="#" ng-click="test.delete($index)"&gt;Delete&lt;/a&gt; &lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;</pre>
        <p>
Look at how associated data is accessed: <code><b>test.more[$index]...</b></code> Our
goal was to optimize that repeating parts, so we looked at <a href="https://docs.angularjs.org/api/ng/directive/ngInit"><code>ng-init</code></a> directive.
</p>
        <p>
Though docs warn about its use: "<i>the only appropriate use of ngInit is for
aliasing special properties of ngRepeat</i>", we thought that our use of ng-init
is rather close to what docs state, so we tried the following:
</p>
        <pre style="padding-left: 1em">...
&lt;tr ng-repeat="item in test.records track by $index" 
  ng-init="<b>more
= test.more[$index]</b>" ng-if="<b>more.visible</b>"&gt; &lt;td&gt; &lt;input type="checkbox"
ng-model="<b>more.selected</b>"/&gt; &lt;/td&gt; &lt;td&gt;{{item.name}}&lt;/td&gt; &lt;td&gt;{{<b>more.value</b>}}&lt;/td&gt;
&lt;td&gt;{{item.state}}&lt;/td&gt; &lt;td&gt; &lt;a href="#" ng-click="test.delete($index)"&gt;Delete&lt;/a&gt;
&lt;/td&gt; &lt;/tr&gt; ...</pre>
        <p>
This code just does not work, as it shows empty table, as if <code>ng-if</code> is
always evaluated to <code>false</code>. From docs we found the reason:
</p>
        <ul>
          <li>
the priority of the directive <code>ng-if</code> is higher than the prirority of the <code>ng-init</code>,
and besides <code>ng-if</code> is a <code>terminal</code> directive;</li>
          <li>
as result <code>ng-if</code> directive is bound, and <code>ng-init</code> is not;</li>
          <li>
when <code>ng-if</code> is evaluated no <code>$scope.more</code> is defined, so <code>more.visible</code> is
evaluated to <code>false</code>.</li>
        </ul>
        <p>
To workaround <code>ng-init</code>/<code>ng-if</code> problem we refactored <code>ng-if</code> as <code>ng-if-start</code>/<code>ng-if-end</code>:
</p>
        <pre style="padding-left: 1em">...
&lt;tr ng-repeat="item in test.records track by $index" 
  ng-init="<b>more
= test.more[$index]</b>"&gt; &lt;td ng-if-start="<b>more.visible</b>"&gt; &lt;input
type="checkbox" ng-model="<b>more.selected</b>"/&gt; &lt;/td&gt; &lt;td&gt;{{item.name}}&lt;/td&gt;
&lt;td&gt;{{<b>more.value</b>}}&lt;/td&gt; &lt;td&gt;{{item.state}}&lt;/td&gt; &lt;td ng-if-end&gt;
&lt;a href="#" ng-click="test.delete($index)"&gt;Delete&lt;/a&gt; &lt;/td&gt; &lt;/tr&gt; ...</pre>
        <p>
This code works much better and shows a correct content. But then click "Delete"
for a row with Name "record 2" and you will find that updated table is out
of sync for all data that come from <code>test.more</code> array.
</p>
        <p>
So, why the data goes out of sync? The reason is in the way how the <code>ng-init</code> is
implemented: its expression is evaluated just once at directive's pre-link phase.
So, the value of <code>$scope.more</code> will persist for the whole <code>ng-init</code>'s
life cycle, and it does not matter that <code>test.mode[$index]</code> may have changed
at some point.
</p>
        <p>
At this point we have decided to introduce a small directive named <code>ui-eval</code> that
will act in a way similar to <code>ng-init</code> but that:
</p>
        <ul>
          <li>
will run before <code>ng-if</code>;</li>
          <li>
will be re-evaluated when it's value is changed.</li>
        </ul>
        <p>
This is it:
</p>
        <pre style="padding-left: 1em">module.directive(
  "uiEval",
  function()
  {
    var directive =
    {
      restrict: 'A',
      priority: 700,
      link:
      {
        pre: function(scope, element, attr)
        {
          scope.$watch(attr["uiEval"]);
        }
      }
    };

    return directive;
  });</pre>
        <p>
The <code>ui-eval</code> version of the markup is:
</p>
        <pre style="padding-left: 1em">...
&lt;tr ng-repeat="item in test.records track by $index" 
  ui-eval="<b>more
= test.more[$index]</b>" ng-if="<b>more.visible</b>"&gt; &lt;td&gt; &lt;input type="checkbox"
ng-model="<b>more.selected</b>"/&gt; &lt;/td&gt; &lt;td&gt;{{item.name}}&lt;/td&gt; &lt;td&gt;{{<b>more.value</b>}}&lt;/td&gt;
&lt;td&gt;{{item.state}}&lt;/td&gt; &lt;td&gt; &lt;a href="#" ng-click="test.delete($index)"&gt;Delete&lt;/a&gt;
&lt;/td&gt; &lt;/tr&gt; ...</pre>
        <p>
It works as expected both during initial rendering and when model is updated.
</p>
        <p>
We consider <code>ui-eval</code> is a "better" <code>ng-init</code> as it
solves ng-init's silent limitations. On the other hand it should not try to evaluate
any complex logic, as it can be often re-evaluated, so its use case is to alias a
sub-expression. It can be used in any context and is not limited to items of <code>ng-repeat</code>.
</p>
        <p>
Source code can be found at <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/ui-eval.html">github</a>,
and a working sample at <a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/ui-eval.html">rawgit</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0150d335-2a50-40c9-ac37-07460ed21cbb" />
      </body>
      <title>ui-eval angularjs directive</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0150d335-2a50-40c9-ac37-07460ed21cbb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/06/07/uievalAngularjsDirective.aspx</link>
      <pubDate>Sun, 07 Jun 2015 11:46:11 GMT</pubDate>
      <description>  &lt;p&gt;
In our angularjs projects we are often dealing with existing models that do not always
fit to angularjs expectations.
&lt;/p&gt;
&lt;p&gt;
Here is an example.
&lt;/p&gt;
&lt;p&gt;
There is a model consisting of two arrays: for data, and for associated data. How
to create an &lt;a href="https://docs.angularjs.org/api/ng/directive/ngRepeat"&gt;&lt;code&gt;ng-repeat&lt;/code&gt;&lt;/a&gt; that
displays data from both sources?
&lt;/p&gt;
&lt;p&gt;
Consider a test controller (see a &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/ui-eval.html"&gt;github&lt;/a&gt; sources,
and a &lt;a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/ui-eval.html"&gt;rawgit&lt;/a&gt; working
sample):
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;
model.controller(
  "Test",
  function()
  {
    this.records =
    [
      { name: "record 1", state: "Draft" },
      { name: "record 2", state: "Public" },
      { name: "record 3", state: "Disabled" },
      { name: "record 4", state: "Public" },
      { name: "record 5", state: "Public" }
    ];

    this.more =
    [
      { value: 1, selected: true, visible: true },
      { value: 2, selected: false, visible: true },
      { value: 3, selected: true, visible: true },
      { value: 4, selected: false, visible: false },
      { value: 5, selected: false, visible: true }
    ];

    this.delete = function(index)
    {
      this.records.splice(index, 1);
      this.more.splice(index, 1);
    };
  });&lt;/pre&gt;
&lt;p&gt;
Basically there are three approaches here:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Change model.&lt;/li&gt;
&lt;li&gt;
Adapt model to a single collection.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.angularjs.org/api/ng/directive/ngRepeat"&gt;&lt;code&gt;ng-repeat&lt;/code&gt;&lt;/a&gt; over
first array and access the second array using &lt;code&gt;$index&lt;/code&gt; scope variable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We argued like this:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
It is often not an option to change a model, as it&amp;#39;s how business data are described.&lt;/li&gt;
&lt;li&gt;
A model adaptation when we build a single collection from original two collections,
and synchronize it back (if required) may unnecessary complicate things. 
&lt;/li&gt;
&lt;li&gt;
Thus let&amp;#39;s get associated items by &lt;code&gt;$index&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This is an example of &lt;a href="https://docs.angularjs.org/api/ng/directive/ngRepeat"&gt;&lt;code&gt;ng-repeat&lt;/code&gt;&lt;/a&gt; use:
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;&amp;lt;table border="1"&gt;
  &amp;lt;tr&gt;
    &amp;lt;th&gt;[x]&amp;lt;/th&gt;
    &amp;lt;th&gt;Name&amp;lt;/th&gt;
    &amp;lt;th&gt;Value&amp;lt;/th&gt;
    &amp;lt;th&gt;State&amp;lt;/th&gt;
    &amp;lt;th&gt;Actions&amp;lt;/th&gt;
  &amp;lt;/tr&gt;
  &amp;lt;tr ng-repeat="item in test.records track by $index"
    ng-if="&lt;b&gt;test.more[$index].visible&lt;/b&gt;"&gt;
&amp;lt;td&gt; &amp;lt;input type="checkbox" ng-model="&lt;b&gt;test.more[$index].selected&lt;/b&gt;"/&gt; &amp;lt;/td&gt;
&amp;lt;td&gt;{{item.name}}&amp;lt;/td&gt; &amp;lt;td&gt;{{&lt;b&gt;test.more[$index].value&lt;/b&gt;}}&amp;lt;/td&gt; &amp;lt;td&gt;{{item.state}}&amp;lt;/td&gt;
&amp;lt;td&gt; &amp;lt;a href="#" ng-click="test.delete($index)"&gt;Delete&amp;lt;/a&gt; &amp;lt;/td&gt; &amp;lt;/tr&gt;
&amp;lt;/table&gt;&lt;/pre&gt;
&lt;p&gt;
Look at how associated data is accessed: &lt;code&gt;&lt;b&gt;test.more[$index]...&lt;/b&gt;&lt;/code&gt; Our
goal was to optimize that repeating parts, so we looked at &lt;a href="https://docs.angularjs.org/api/ng/directive/ngInit"&gt;&lt;code&gt;ng-init&lt;/code&gt;&lt;/a&gt; directive.
&lt;/p&gt;
&lt;p&gt;
Though docs warn about its use: &amp;quot;&lt;i&gt;the only appropriate use of ngInit is for
aliasing special properties of ngRepeat&lt;/i&gt;&amp;quot;, we thought that our use of ng-init
is rather close to what docs state, so we tried the following:
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;...
&amp;lt;tr ng-repeat="item in test.records track by $index" 
  ng-init=&amp;quot;&lt;b&gt;more
= test.more[$index]&lt;/b&gt;&amp;quot; ng-if="&lt;b&gt;more.visible&lt;/b&gt;"&gt; &amp;lt;td&gt; &amp;lt;input type="checkbox"
ng-model="&lt;b&gt;more.selected&lt;/b&gt;"/&gt; &amp;lt;/td&gt; &amp;lt;td&gt;{{item.name}}&amp;lt;/td&gt; &amp;lt;td&gt;{{&lt;b&gt;more.value&lt;/b&gt;}}&amp;lt;/td&gt;
&amp;lt;td&gt;{{item.state}}&amp;lt;/td&gt; &amp;lt;td&gt; &amp;lt;a href="#" ng-click="test.delete($index)"&gt;Delete&amp;lt;/a&gt;
&amp;lt;/td&gt; &amp;lt;/tr&gt; ...&lt;/pre&gt;
&lt;p&gt;
This code just does not work, as it shows empty table, as if &lt;code&gt;ng-if&lt;/code&gt; is
always evaluated to &lt;code&gt;false&lt;/code&gt;. From docs we found the reason:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
the priority of the directive &lt;code&gt;ng-if&lt;/code&gt; is higher than the prirority of the &lt;code&gt;ng-init&lt;/code&gt;,
and besides &lt;code&gt;ng-if&lt;/code&gt; is a &lt;code&gt;terminal&lt;/code&gt; directive;&lt;/li&gt;
&lt;li&gt;
as result &lt;code&gt;ng-if&lt;/code&gt; directive is bound, and &lt;code&gt;ng-init&lt;/code&gt; is not;&lt;/li&gt;
&lt;li&gt;
when &lt;code&gt;ng-if&lt;/code&gt; is evaluated no &lt;code&gt;$scope.more&lt;/code&gt; is defined, so &lt;code&gt;more.visible&lt;/code&gt; is
evaluated to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To workaround &lt;code&gt;ng-init&lt;/code&gt;/&lt;code&gt;ng-if&lt;/code&gt; problem we refactored &lt;code&gt;ng-if&lt;/code&gt; as &lt;code&gt;ng-if-start&lt;/code&gt;/&lt;code&gt;ng-if-end&lt;/code&gt;:
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;...
&amp;lt;tr ng-repeat="item in test.records track by $index" 
  ng-init=&amp;quot;&lt;b&gt;more
= test.more[$index]&lt;/b&gt;&amp;quot;&gt; &amp;lt;td ng-if-start="&lt;b&gt;more.visible&lt;/b&gt;"&gt; &amp;lt;input
type="checkbox" ng-model="&lt;b&gt;more.selected&lt;/b&gt;"/&gt; &amp;lt;/td&gt; &amp;lt;td&gt;{{item.name}}&amp;lt;/td&gt;
&amp;lt;td&gt;{{&lt;b&gt;more.value&lt;/b&gt;}}&amp;lt;/td&gt; &amp;lt;td&gt;{{item.state}}&amp;lt;/td&gt; &amp;lt;td ng-if-end&gt;
&amp;lt;a href="#" ng-click="test.delete($index)"&gt;Delete&amp;lt;/a&gt; &amp;lt;/td&gt; &amp;lt;/tr&gt; ...&lt;/pre&gt;
&lt;p&gt;
This code works much better and shows a correct content. But then click &amp;quot;Delete&amp;quot;
for a row with Name &amp;quot;record 2&amp;quot; and you will find that updated table is out
of sync for all data that come from &lt;code&gt;test.more&lt;/code&gt; array.
&lt;/p&gt;
&lt;p&gt;
So, why the data goes out of sync? The reason is in the way how the &lt;code&gt;ng-init&lt;/code&gt; is
implemented: its expression is evaluated just once at directive&amp;#39;s pre-link phase.
So, the value of &lt;code&gt;$scope.more&lt;/code&gt; will persist for the whole &lt;code&gt;ng-init&lt;/code&gt;&amp;#39;s
life cycle, and it does not matter that &lt;code&gt;test.mode[$index]&lt;/code&gt; may have changed
at some point.
&lt;/p&gt;
&lt;p&gt;
At this point we have decided to introduce a small directive named &lt;code&gt;ui-eval&lt;/code&gt; that
will act in a way similar to &lt;code&gt;ng-init&lt;/code&gt; but that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
will run before &lt;code&gt;ng-if&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
will be re-evaluated when it&amp;#39;s value is changed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This is it:
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;module.directive(
  "uiEval",
  function()
  {
    var directive =
    {
      restrict: 'A',
      priority: 700,
      link:
      {
        pre: function(scope, element, attr)
        {
          scope.$watch(attr["uiEval"]);
        }
      }
    };

    return directive;
  });&lt;/pre&gt;
&lt;p&gt;
The &lt;code&gt;ui-eval&lt;/code&gt; version of the markup is:
&lt;/p&gt;
&lt;pre style="padding-left: 1em"&gt;...
&amp;lt;tr ng-repeat="item in test.records track by $index" 
  ui-eval=&amp;quot;&lt;b&gt;more
= test.more[$index]&lt;/b&gt;&amp;quot; ng-if="&lt;b&gt;more.visible&lt;/b&gt;"&gt; &amp;lt;td&gt; &amp;lt;input type="checkbox"
ng-model="&lt;b&gt;more.selected&lt;/b&gt;"/&gt; &amp;lt;/td&gt; &amp;lt;td&gt;{{item.name}}&amp;lt;/td&gt; &amp;lt;td&gt;{{&lt;b&gt;more.value&lt;/b&gt;}}&amp;lt;/td&gt;
&amp;lt;td&gt;{{item.state}}&amp;lt;/td&gt; &amp;lt;td&gt; &amp;lt;a href="#" ng-click="test.delete($index)"&gt;Delete&amp;lt;/a&gt;
&amp;lt;/td&gt; &amp;lt;/tr&gt; ...&lt;/pre&gt;
&lt;p&gt;
It works as expected both during initial rendering and when model is updated.
&lt;/p&gt;
&lt;p&gt;
We consider &lt;code&gt;ui-eval&lt;/code&gt; is a &amp;quot;better&amp;quot; &lt;code&gt;ng-init&lt;/code&gt; as it
solves ng-init&amp;#39;s silent limitations. On the other hand it should not try to evaluate
any complex logic, as it can be often re-evaluated, so its use case is to alias a
sub-expression. It can be used in any context and is not limited to items of &lt;code&gt;ng-repeat&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Source code can be found at &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/ui-eval.html"&gt;github&lt;/a&gt;,
and a working sample at &lt;a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/ui-eval.html"&gt;rawgit&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0150d335-2a50-40c9-ac37-07460ed21cbb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0150d335-2a50-40c9-ac37-07460ed21cbb.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a704749f-b93b-48be-bbb6-0ca70d79b1d5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a704749f-b93b-48be-bbb6-0ca70d79b1d5.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a704749f-b93b-48be-bbb6-0ca70d79b1d5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a704749f-b93b-48be-bbb6-0ca70d79b1d5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://stackoverflow.com/">Stackoverfow</a> shows that people are searching <a href="http://stackoverflow.com/questions/24082468/how-to-intercept-resource-requests">How
to intercept $resource requests</a>.
</p>
        <p>
Recently we have written about the way to cancel <a href="https://docs.angularjs.org/api/ngResource/service/$resource">angularjs
$resource</a> requests (see <a href="http://www.nesterovsky-bros.com/weblog/2015/02/02/CancelAngularjsResourceRequest.aspx" rel="bookmark">Cancel
angularjs resource request</a>). Here we apply the same technique to intercept resource
request.
</p>
        <p>
Consider a sample (<a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/transform-request.html">nesterovsky-bros/angularjs-api/master/angularjs/transform-request.html</a>):
</p>
        <blockquote>
          <code> &lt;!DOCTYPE html&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
  &lt;meta charset="utf-8" /&gt;<br />
  &lt;title&gt;Intercept resource request&lt;/title&gt;<br />
  &lt;style type="text/css"&gt;.ng-cloak { display: none; }&lt;/style&gt;<br />
  &lt;script src="angular.js"&gt;&lt;/script&gt;<br />
  &lt;script src="angular-resource.js"&gt;&lt;/script&gt;<br />
  &lt;script&gt;<br />
angular.module("app", ["ngResource"]).<br />
  factory(<br />
    "services",<br />
    ["$resource", function ($resource)<br />
    {<br />
      return $resource(<br />
        "<a href="http://md5.jsontest.com/">http://md5.jsontest.com/</a>",<br />
        {},<br />
        {<br />
          MD5:<br />
          {<br />
            method: "GET",<br />
            params: { text:
null },<br />
            then: function
(resolve)<br />
            {<br />
              this.params.text
= "***" + this.params.text + "***";<br />
              this.then
= null;<br />
              resolve(this);<br />
            }<br />
          },<br />
        });<br />
      }]).<br />
  controller(<br />
    "Test",<br />
    ["services", function (services)<br />
    {<br />
      this.value = "Sample text";<br /><br />
      this.call = function()<br />
      {<br />
        this.result = services.MD5({ text: this.value
});<br />
      }<br />
    }]);<br />
  &lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body ng-app="app" ng-controller="Test as test"&gt;<br />
  &lt;label&gt;Text: &lt;input type="text" ng-model="test.value" /&gt;&lt;/label&gt;<br />
  &lt;input type="button" value="call" ng-click="test.call()"/&gt;<br />
  &lt;div ng-bind="test.result.md5"&gt;&lt;/div&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt; </code>
        </blockquote>
        <h4>How it works.
</h4>
        <ol>
          <li>
            <code>$resource</code> merges action definition, request params and data to build
a <code>config</code> parameter for an <code>$http</code> request.</li>
          <li>
a <code>config</code> parameter passed into an <code>$http</code> request is treated
as a <code>promise</code> like object, so it may contain <code>then</code> function
to initialize <code>config</code>.</li>
          <li>
action's <code>then</code> function may transform request as it wishes.</li>
        </ol>
        <p>
The demo can be found at <a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/transform-request.html">transform-request.html</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a704749f-b93b-48be-bbb6-0ca70d79b1d5" />
      </body>
      <title>Intercept angularjs resource request</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a704749f-b93b-48be-bbb6-0ca70d79b1d5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/05/07/InterceptAngularjsResourceRequest.aspx</link>
      <pubDate>Thu, 07 May 2015 10:53:34 GMT</pubDate>
      <description>  &lt;p&gt;
&lt;a href="http://stackoverflow.com/"&gt;Stackoverfow&lt;/a&gt; shows that people are searching &lt;a href="http://stackoverflow.com/questions/24082468/how-to-intercept-resource-requests"&gt;How
to intercept $resource requests&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Recently we have written about the way to cancel &lt;a href="https://docs.angularjs.org/api/ngResource/service/$resource"&gt;angularjs
$resource&lt;/a&gt; requests (see &lt;a href="http://www.nesterovsky-bros.com/weblog/2015/02/02/CancelAngularjsResourceRequest.aspx" rel="bookmark"&gt;Cancel
angularjs resource request&lt;/a&gt;). Here we apply the same technique to intercept resource
request.
&lt;/p&gt;
&lt;p&gt;
Consider a sample (&lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/angularjs/transform-request.html"&gt;nesterovsky-bros/angularjs-api/master/angularjs/transform-request.html&lt;/a&gt;):
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; &amp;lt;!DOCTYPE html&gt;&lt;br /&gt;
&amp;lt;html&gt;&lt;br /&gt;
&amp;lt;head&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;meta charset="utf-8" /&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;title&gt;Intercept resource request&amp;lt;/title&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;style type="text/css"&gt;.ng-cloak { display: none; }&amp;lt;/style&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="angular.js"&gt;&amp;lt;/script&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="angular-resource.js"&gt;&amp;lt;/script&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;script&gt;&lt;br /&gt;
angular.module("app", ["ngResource"]).&lt;br /&gt;
&amp;nbsp; factory(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; "services",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ["$resource", function ($resource)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $resource(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&lt;a href="http://md5.jsontest.com/"&gt;http://md5.jsontest.com/&lt;/a&gt;",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {},&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MD5:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method: "GET",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; params: { text:
null },&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; then: function
(resolve)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.params.text
= "***" + this.params.text + "***";&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.then
= null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; resolve(this);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }]).&lt;br /&gt;
&amp;nbsp; controller(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; "Test",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ["services", function (services)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.value = "Sample text";&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.call = function()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.result = services.MD5({ text: this.value
});&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }]);&lt;br /&gt;
&amp;nbsp; &amp;lt;/script&gt;&lt;br /&gt;
&amp;lt;/head&gt;&lt;br /&gt;
&amp;lt;body ng-app="app" ng-controller="Test as test"&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;label&gt;Text: &amp;lt;input type="text" ng-model="test.value" /&gt;&amp;lt;/label&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;input type="button" value="call" ng-click="test.call()"/&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div ng-bind="test.result.md5"&gt;&amp;lt;/div&gt;&lt;br /&gt;
&amp;lt;/body&gt;&lt;br /&gt;
&amp;lt;/html&amp;gt; &lt;/code&gt;&lt;/blockquote&gt; 
&lt;h4&gt;How it works.
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;$resource&lt;/code&gt; merges action definition, request params and data to build
a &lt;code&gt;config&lt;/code&gt; parameter for an &lt;code&gt;$http&lt;/code&gt; request.&lt;/li&gt;
&lt;li&gt;
a &lt;code&gt;config&lt;/code&gt; parameter passed into an &lt;code&gt;$http&lt;/code&gt; request is treated
as a &lt;code&gt;promise&lt;/code&gt; like object, so it may contain &lt;code&gt;then&lt;/code&gt; function
to initialize &lt;code&gt;config&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
action&amp;#39;s &lt;code&gt;then&lt;/code&gt; function may transform request as it wishes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The demo can be found at &lt;a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/angularjs/transform-request.html"&gt;transform-request.html&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a704749f-b93b-48be-bbb6-0ca70d79b1d5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a704749f-b93b-48be-bbb6-0ca70d79b1d5.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ee0b78bd-1ea5-449d-96c0-459313ab78e2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ee0b78bd-1ea5-449d-96c0-459313ab78e2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ee0b78bd-1ea5-449d-96c0-459313ab78e2.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ee0b78bd-1ea5-449d-96c0-459313ab78e2</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Often we need to keep a client session state in our angularjs application.
</p>
        <p>
This state should survive page refresh and navigations within the application.
</p>
        <p>
Earlier we used <a href="https://github.com/gsklee/ngStorage">ngStorage</a> module
but lately have changed our opinion, as we think it's over-engineered and is too
heavy at runtime.
</p>
        <p>
We have replaced it with a simple service that synchronizes sessionStorage once during
initialization, and once before page unload.
</p>
        <p>
Look at an example (<a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/services/session.html">session.html</a>):
</p>
        <blockquote>
          <pre>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset="utf-8" /&gt;
  &lt;title&gt;Session&lt;/title&gt;
  &lt;style type="text/css"&gt;
    .ng-cloak { display: none; }
  &lt;/style&gt;
  &lt;script src="angular.js"&gt;&lt;/script&gt;
  &lt;script&gt;
angular.module("app", []).
<b>factory(
"session", ["$window", function($window) { var session = angular.fromJson($window.sessionStorage.getItem("app"))
|| {}; $window.addEventListener( "beforeunload", function() { $window.sessionStorage.setItem("app",
angular.toJson(session)); }) return session; }])</b>. controller( "Test", ["session",
function(session) { this.state = session; }]); &lt;/script&gt; &lt;/head&gt; &lt;body ng-app="app"
ng-controller="Test as test"&gt; &lt;input type="text" ng-model="test.state.value"/&gt;
&lt;a href="session.html?p=1"&gt;Page 1&lt;/a&gt; &lt;a href="session.html?p=2"&gt;Page 2&lt;/a&gt;
&lt;/body&gt; &lt;/html&gt; </pre>
        </blockquote>
        <p>
Source can be found at <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/services/session.html">nesterovsky-bros/angularjs-api/services/session.html</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ee0b78bd-1ea5-449d-96c0-459313ab78e2" />
      </body>
      <title>window.sessionStorage in AngularJS</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ee0b78bd-1ea5-449d-96c0-459313ab78e2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/01/26/windowsessionStorageInAngularJS.aspx</link>
      <pubDate>Mon, 26 Jan 2015 08:46:36 GMT</pubDate>
      <description>  &lt;p&gt;
Often we need to keep a client session state in our angularjs application.
&lt;/p&gt;
&lt;p&gt;
This state should survive page refresh and navigations within the application.
&lt;/p&gt;
&lt;p&gt;
Earlier we used &lt;a href="https://github.com/gsklee/ngStorage"&gt;ngStorage&lt;/a&gt; module
but lately have changed our opinion, as we think it&amp;#39;s over-engineered and is too
heavy at runtime.
&lt;/p&gt;
&lt;p&gt;
We have replaced it with a simple service that synchronizes sessionStorage once during
initialization, and once before page unload.
&lt;/p&gt;
&lt;p&gt;
Look at an example (&lt;a href="https://rawgit.com/nesterovsky-bros/angularjs-api/master/services/session.html"&gt;session.html&lt;/a&gt;):
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;
&amp;lt;!DOCTYPE html&gt;
&amp;lt;html&gt;
&amp;lt;head&gt;
  &amp;lt;meta charset="utf-8" /&gt;
  &amp;lt;title&gt;Session&amp;lt;/title&gt;
  &amp;lt;style type="text/css"&gt;
    .ng-cloak { display: none; }
  &amp;lt;/style&gt;
  &amp;lt;script src="angular.js"&gt;&amp;lt;/script&gt;
  &amp;lt;script&gt;
angular.module("app", []).
&lt;b&gt;factory(
"session", ["$window", function($window) { var session = angular.fromJson($window.sessionStorage.getItem("app"))
|| {}; $window.addEventListener( "beforeunload", function() { $window.sessionStorage.setItem("app",
angular.toJson(session)); }) return session; }])&lt;/b&gt;. controller( "Test", ["session",
function(session) { this.state = session; }]); &amp;lt;/script&gt; &amp;lt;/head&gt; &amp;lt;body ng-app="app"
ng-controller="Test as test"&gt; &amp;lt;input type="text" ng-model="test.state.value"/&gt;
&amp;lt;a href="session.html?p=1"&gt;Page 1&amp;lt;/a&gt; &amp;lt;a href="session.html?p=2"&gt;Page 2&amp;lt;/a&gt;
&amp;lt;/body&gt; &amp;lt;/html&gt; &lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Source can be found at &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/services/session.html"&gt;nesterovsky-bros/angularjs-api/services/session.html&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ee0b78bd-1ea5-449d-96c0-459313ab78e2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ee0b78bd-1ea5-449d-96c0-459313ab78e2.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b3fe14e3-9656-4ccc-bb03-16dc4a4e7374</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b3fe14e3-9656-4ccc-bb03-16dc4a4e7374.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b3fe14e3-9656-4ccc-bb03-16dc4a4e7374</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier this year <a href="http://www.asp.net/web-api/overview/advanced/dependency-injection#author-36870">Mike
Wasson</a> has published a post: "<a href="http://www.asp.net/web-api/overview/advanced/dependency-injection">Dependency
Injection in ASP.NET Web API 2</a>" that describes Web API's approach to
the <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection
design pattern</a>.
</p>
        <p>
In short it goes like this:
</p>
        <ul>
          <li>
Web API provides a primary integration point through <code>HttpConfiguration.DependencyResolver</code> property,
and tries to obtain many services through this resolver;</li>
          <li>
Web API suggests to use your favorite Dependecy Injection library through the integration
point. Author lists following libraries: <span><a href="http://msdn.microsoft.com/en-us/library/ff647202.aspx">Unity</a> (by
Microsoft), <a href="http://www.castleproject.org/">Castle Windsor</a>, <a href="http://www.springframework.net/">Spring.Net</a>, <a href="http://code.google.com/p/autofac/">Autofac</a>, <a href="http://www.ninject.org/">Ninject</a>,
and <a href="http://docs.structuremap.net/">StructureMap</a>.</span></li>
        </ul>
        <p>
The Unity Container (Unity) is a lightweight, extensible dependency injection container.
There are Nugets both for Unity library and for Web API integration.
</p>
        <p>
Now to the point of this post.
</p>
        <p>
Unity defines a hierarchy of injection scopes. In Web API they are usually mapped
to application and request scopes. This way a developer can inject application singletons,
create request level, or transient objects.
</p>
        <p>
Everything looks reasonable. The only problem we have found is that there is no way
you to inject Web API objects like <code>HttpConfiguration</code>, <code>HttpControllerContext</code> or
request's <code>CancellationToken</code>, as they are never registered for injection.
</p>
        <p>
To workaround this we have created a small class called <code>UnityControllerActivator</code> that
perfroms required registration:
</p>
        <blockquote>
          <code> using System;<br />
using System.Net.Http;<br />
using System.Threading;<br />
using System.Threading.Tasks;<br />
using System.Web.Http.Controllers;<br />
using System.Web.Http.Dispatcher;<br /><br />
using Microsoft.Practices.Unity;<br /><br />
/// &lt;summary&gt;<br />
/// Unity controller activator.<br />
/// &lt;/summary&gt;<br />
public class UnityControllerActivator: IHttpControllerActivator<br />
{<br />
  /// &lt;summary&gt;<br />
  /// Creates an UnityControllerActivator instance.<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="activator"&gt;Base activator.&lt;/param&gt;<br />
  public UnityControllerActivator(IHttpControllerActivator activator)<br />
  {<br />
    if (activator == null)<br />
    {<br />
      throw new ArgumentException("activator");<br />
    }<br /><br />
    this.activator = activator;<br />
  }<br /><br />
  /// &lt;summary&gt;<br />
  /// Creates a controller wrapper.<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="request"&gt;A http request.&lt;/param&gt;<br />
  /// &lt;param name="controllerDescriptor"&gt;Controller descriptor.&lt;/param&gt;<br />
  /// &lt;param name="controllerType"&gt;Controller type.&lt;/param&gt;<br />
  /// &lt;returns&gt;A controller wrapper.&lt;/returns&gt;<br />
  public IHttpController Create(<br />
    HttpRequestMessage request, 
<br />
    HttpControllerDescriptor controllerDescriptor, 
<br />
    Type controllerType)<br />
  {<br />
    return new Controller 
<br />
    { 
<br />
      activator = activator,<br />
      controllerType = controllerType 
<br />
    };<br />
  }<br /><br />
  /// &lt;summary&gt;<br />
  /// Base controller activator.<br />
  /// &lt;/summary&gt;<br />
  private readonly IHttpControllerActivator activator;<br /><br />
  /// &lt;summary&gt;<br />
  /// A controller wrapper.<br />
  /// &lt;/summary&gt;<br />
  private class Controller: IHttpController, IDisposable<br />
  {<br />
    /// &lt;summary&gt;<br />
    /// Base controller activator.<br />
    /// &lt;/summary&gt;<br />
    public IHttpControllerActivator activator;<br /><br />
    /// &lt;summary&gt;<br />
    /// Controller type.<br />
    /// &lt;/summary&gt;<br />
    public Type controllerType;<br /><br />
    /// &lt;summary&gt;<br />
    /// A controller instance.<br />
    /// &lt;/summary&gt;<br />
    public IHttpController controller;<br /><br />
    /// &lt;summary&gt;<br />
    /// Disposes controller.<br />
    /// &lt;/summary&gt;<br />
    public void Dispose()<br />
    {<br />
      var disposable = controller as IDisposable;<br /><br />
      if (disposable != null)<br />
      {<br />
        disposable.Dispose();<br />
      }<br />
    }<br /><br />
    /// &lt;summary&gt;<br />
    /// Executes an action.<br />
    /// &lt;/summary&gt;<br />
    /// &lt;param name="controllerContext"&gt;Controller context.&lt;/param&gt;<br />
    /// &lt;param name="cancellationToken"&gt;Cancellation token.&lt;/param&gt;<br />
    /// &lt;returns&gt;Response message.&lt;/returns&gt;<br />
    public Task&lt;HttpResponseMessage&gt; ExecuteAsync(<br />
      HttpControllerContext controllerContext, 
<br />
      CancellationToken cancellationToken)<br />
    {<br />
      if (controller == null)<br />
      {<br />
        var request = controllerContext.Request;<br />
        <b>var container = request.GetDependencyScope().<br />
          GetService(typeof(IUnityContainer))
as IUnityContainer;<br /><br />
        if (container != null)<br />
        {<br />
          container.RegisterInstance&lt;HttpControllerContext&gt;(controllerContext);<br />
          container.RegisterInstance&lt;HttpRequestMessage&gt;(request);<br />
          container.RegisterInstance&lt;CancellationToken&gt;(cancellationToken);<br />
        }<br /></b><br />
        controller = activator.Create(<br />
          request, 
<br />
          controllerContext.ControllerDescriptor, 
<br />
          controllerType);<br />
      }<br /><br />
      controllerContext.Controller = controller;<br /><br />
      return controller.ExecuteAsync(controllerContext, cancellationToken);<br />
    }<br />
  }<br />
} </code>
        </blockquote>
        <p>
          <b>Note on how it works.</b>
        </p>
        <blockquote>
          <ul>
            <li>
              <code>IHttpControllerActivator</code> is a controller factory, which Web API uses
to create new controller instances using <code>IHttpControllerActivator.Create()</code>.
Later controller's <code>IHttpController.ExecuteAsync()</code> is called to run the
logic.</li>
            <li>
              <code>UnityControllerActivator</code> replaces original controller activator with
a wrapper that delays creation (injection) of real controller untill request objects
are registered in the scope</li>
          </ul>
        </blockquote>
        <p>
To register this class one need to update code in the <code>UnityWebApiActivator.cs</code> (file
added with nuget <code>Unity.AspNet.WebApi</code>)
</p>
        <blockquote>
          <code> public static class UnityWebApiActivator<br />
{<br />
  /// &lt;summary&gt;Integrates Unity when the application starts.&lt;summary&gt;<br />
  public static void Start() 
<br />
  {<br />
    var config = GlobalConfiguration.Configuration;<br />
    var container = UnityConfig.GetConfiguredContainer();<br /><br />
    container.RegisterInstance&lt;HttpConfiguration&gt;(config);<br />
    container.RegisterInstance&lt;IHttpControllerActivator&gt;(<br />
      new UnityControllerActivator(config.Services.GetHttpControllerActivator()));<br /><br />
    config.DependencyResolver = UnityHierarchicalDependencyResolver(container);<br />
  }<br />
  ...<br />
} </code>
        </blockquote>
        <p>
With this addition we have simplified the boring problem with passing of <code>CancellationToken</code> all
around the code, as controller (and other classes) just declared a property to inject:
</p>
        <blockquote>
          <code> public class MyController: ApiController<br />
{<br />
  [Dependency]<br />
  public CancellationToken CancellationToken { get; set; }<br /><br />
  [Dependency]<br />
  public IModelContext Model { get; set; }<br /><br />
  public async Task&lt;IEnumerable&lt;Products&gt;&gt; GetProducts(...)<br />
  {<br />
    ...<br />
  }<br /><br />
  public async Task&lt;IEnumerable&lt;Customer&gt;&gt; GetCustomer(...)<br />
  {<br />
    ...<br />
  }<br /><br />
  ...<br />
}<br /><br />
...<br /><br />
public class ModelContext: IModelContext<br />
{<br />
  [Dependency]<br />
  public CancellationToken CancellationToken { get; set; }<br />
  ...<br />
} </code>
        </blockquote>
        <p>
And finally to perform unit tests for controllers with Depenency Injection you can
use a code like this:
</p>
        <blockquote>
          <code> using System.Threading;<br />
using System.Threading.Tasks;<br />
using System.Web.Http;<br />
using System.Web.Http.Controllers;<br />
using System.Web.Http.Dependencies;<br />
using System.Net.Http;<br /><br />
using Microsoft.Practices.Unity;<br />
using Microsoft.Practices.Unity.WebApi;<br /><br />
using Microsoft.VisualStudio.TestTools.UnitTesting;<br /><br />
[TestClass]<br />
public class MyControllerTest<br />
{<br />
  [ClassInitialize]<br />
  public static void Initialize(TestContext context)<br />
  {<br />
    config = new HttpConfiguration();<br /><br />
    Register(config);<br />
  }<br /><br />
  [ClassCleanup]<br />
  public static void Cleanup()<br />
  {<br />
    config.Dispose();<br />
  }<br /><br />
  [TestMethod]<br />
  public async Task GetProducts()<br />
  {<br />
    var controller = CreateController&lt;MyController&gt;();<br /><br />
    //...<br />
  }<br /><br />
  public static T CreateController&lt;T&gt;(HttpRequestMessage request = null)<br />
    where T: ApiController<br />
  {<br />
    if (request == null)<br />
    {<br />
      request = new HttpRequestMessage();<br />
    }<br /><br />
    request.SetConfiguration(config);<br /><br />
    var controllerContext = new HttpControllerContext()<br />
    {<br />
      Configuration = config,<br />
      Request = request<br />
    };<br /><br />
    var scope = request.GetDependencyScope();<br />
    var container = scope.GetService(typeof(IUnityContainer)) 
<br />
      as IUnityContainer;<br /><br />
    if (container != null)<br />
    {<br />
      container.RegisterInstance&lt;HttpControllerContext&gt;(controllerContext);<br />
      container.RegisterInstance&lt;HttpRequestMessage&gt;(request);<br />
      container.RegisterInstance&lt;CancellationToken&gt;(CancellationToken.None);<br />
    }<br /><br />
    T controller = scope.GetService(typeof(T)) as T;<br /><br />
    controller.Configuration = config;<br />
    controller.Request = request;<br />
    controller.ControllerContext = controllerContext;<br /><br />
    return controller;<br />
  }<br /><br />
  public static void Register(HttpConfiguration config)<br />
  {<br />
    config.DependencyResolver = CreateDependencyResolver(config);<br />
  }<br /><br />
  public static IDependencyResolver CreateDependencyResolver(HttpConfiguration
config)<br />
  {<br />
    var container = new UnityContainer();<br /><br />
    container.RegisterInstance&lt;HttpConfiguration&gt;(config);<br /><br />
    // TODO: configure Unity contaiener.<br /><br />
    return new UnityHierarchicalDependencyResolver(container);<br />
  }<br /><br />
  public static HttpConfiguration config;<br />
} </code>
        </blockquote>
        <p>
P.S. To those who think Dependency Injection is an universal tool, please read the
article: <a href="http://www.tonymarston.net/php-mysql/dependency-injection-is-evil.html">Dependency
Injection is Evil</a>. <img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif" /></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b3fe14e3-9656-4ccc-bb03-16dc4a4e7374" />
      </body>
      <title>Dependency Injection in ASP.NET Web API 2</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b3fe14e3-9656-4ccc-bb03-16dc4a4e7374.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/12/15/DependencyInjectionInASPNETWebAPI2.aspx</link>
      <pubDate>Mon, 15 Dec 2014 20:24:49 GMT</pubDate>
      <description>  &lt;p&gt;
Earlier this year &lt;a href="http://www.asp.net/web-api/overview/advanced/dependency-injection#author-36870" &gt;Mike
Wasson&lt;/a&gt; has published a post: "&lt;a href="http://www.asp.net/web-api/overview/advanced/dependency-injection"&gt;Dependency
Injection in ASP.NET Web API 2&lt;/a&gt;&amp;quot; that describes Web API&amp;#39;s approach to
the &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection
design pattern&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
In short it goes like this:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Web API provides a primary integration point through &lt;code&gt;HttpConfiguration.DependencyResolver&lt;/code&gt; property,
and tries to obtain many services through this resolver;&lt;/li&gt;
&lt;li&gt;
Web API suggests to use your favorite Dependecy Injection library through the integration
point. Author lists following libraries: &lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ff647202.aspx"&gt;Unity&lt;/a&gt; (by
Microsoft), &lt;a href="http://www.castleproject.org/"&gt;Castle Windsor&lt;/a&gt;, &lt;a href="http://www.springframework.net/"&gt;Spring.Net&lt;/a&gt;, &lt;a href="http://code.google.com/p/autofac/"&gt;Autofac&lt;/a&gt;, &lt;a href="http://www.ninject.org/"&gt;Ninject&lt;/a&gt;,
and &lt;a href="http://docs.structuremap.net/"&gt;StructureMap&lt;/a&gt;.&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The Unity Container (Unity) is a lightweight, extensible dependency injection container.
There are Nugets both for Unity library and for Web API integration.
&lt;/p&gt;
&lt;p&gt;
Now to the point of this post.
&lt;/p&gt;
&lt;p&gt;
Unity defines a hierarchy of injection scopes. In Web API they are usually mapped
to application and request scopes. This way a developer can inject application singletons,
create request level, or transient objects.
&lt;/p&gt;
&lt;p&gt;
Everything looks reasonable. The only problem we have found is that there is no way
you to inject Web API objects like &lt;code&gt;HttpConfiguration&lt;/code&gt;, &lt;code&gt;HttpControllerContext&lt;/code&gt; or
request's &lt;code&gt;CancellationToken&lt;/code&gt;, as they are never registered for injection.
&lt;/p&gt;
&lt;p&gt;
To workaround this we have created a small class called &lt;code&gt;UnityControllerActivator&lt;/code&gt; that
perfroms required registration:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; using System;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Web.Http.Controllers;&lt;br /&gt;
using System.Web.Http.Dispatcher;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.Practices.Unity;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Unity controller activator.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public class UnityControllerActivator: IHttpControllerActivator&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Creates an UnityControllerActivator instance.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="activator"&gt;Base activator.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; public UnityControllerActivator(IHttpControllerActivator activator)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (activator == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("activator");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this.activator = activator;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Creates a controller wrapper.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="request"&gt;A http request.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="controllerDescriptor"&gt;Controller descriptor.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="controllerType"&gt;Controller type.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A controller wrapper.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp; public IHttpController Create(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpRequestMessage request, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpControllerDescriptor controllerDescriptor, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Type controllerType)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Controller 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; activator = activator,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerType = controllerType 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Base controller activator.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; private readonly IHttpControllerActivator activator;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// A controller wrapper.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; private class Controller: IHttpController, IDisposable&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Base controller activator.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public IHttpControllerActivator activator;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Controller type.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Type controllerType;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A controller instance.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public IHttpController controller;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Disposes controller.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Dispose()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var disposable = controller as IDisposable;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (disposable != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disposable.Dispose();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Executes an action.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="controllerContext"&gt;Controller context.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="cancellationToken"&gt;Cancellation token.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;Response message.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Task&amp;lt;HttpResponseMessage&gt; ExecuteAsync(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpControllerContext controllerContext, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancellationToken cancellationToken)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (controller == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var request = controllerContext.Request;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;var container = request.GetDependencyScope().&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetService(typeof(IUnityContainer))
as IUnityContainer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (container != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpControllerContext&gt;(controllerContext);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpRequestMessage&gt;(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;CancellationToken&gt;(cancellationToken);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;/b&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller = activator.Create(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerContext.ControllerDescriptor, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerType);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerContext.Controller = controller;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return controller.ExecuteAsync(controllerContext, cancellationToken);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
} &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;b&gt;Note on how it works.&lt;/b&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IHttpControllerActivator&lt;/code&gt; is a controller factory, which Web API uses
to create new controller instances using &lt;code&gt;IHttpControllerActivator.Create()&lt;/code&gt;.
Later controller's &lt;code&gt;IHttpController.ExecuteAsync()&lt;/code&gt; is called to run the
logic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UnityControllerActivator&lt;/code&gt; replaces original controller activator with
a wrapper that delays creation (injection) of real controller untill request objects
are registered in the scope&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To register this class one need to update code in the &lt;code&gt;UnityWebApiActivator.cs&lt;/code&gt; (file
added with nuget &lt;code&gt;Unity.AspNet.WebApi&lt;/code&gt;)
&lt;/p&gt;
&lt;blockquote&gt; &lt;code&gt; public static class UnityWebApiActivator&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;Integrates Unity when the application starts.&amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; public static void Start() 
&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var config = GlobalConfiguration.Configuration;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = UnityConfig.GetConfiguredContainer();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpConfiguration&gt;(config);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;IHttpControllerActivator&gt;(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new UnityControllerActivator(config.Services.GetHttpControllerActivator()));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.DependencyResolver = UnityHierarchicalDependencyResolver(container);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
} &lt;/code&gt; &lt;/blockquote&gt; 
&lt;p&gt;
With this addition we have simplified the boring problem with passing of &lt;code&gt;CancellationToken&lt;/code&gt; all
around the code, as controller (and other classes) just declared a property to inject:
&lt;/p&gt;
&lt;blockquote&gt; &lt;code&gt; public class MyController: ApiController&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public CancellationToken CancellationToken { get; set; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public IModelContext Model { get; set; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;IEnumerable&amp;lt;Products&gt;&gt; GetProducts(...)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;IEnumerable&amp;lt;Customer&gt;&gt; GetCustomer(...)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
public class ModelContext: IModelContext&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public CancellationToken CancellationToken { get; set; }&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
} &lt;/code&gt; &lt;/blockquote&gt; 
&lt;p&gt;
And finally to perform unit tests for controllers with Depenency Injection you can
use a code like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Web.Http;&lt;br /&gt;
using System.Web.Http.Controllers;&lt;br /&gt;
using System.Web.Http.Dependencies;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.Practices.Unity;&lt;br /&gt;
using Microsoft.Practices.Unity.WebApi;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.VisualStudio.TestTools.UnitTesting;&lt;br /&gt;
&lt;br /&gt;
[TestClass]&lt;br /&gt;
public class MyControllerTest&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [ClassInitialize]&lt;br /&gt;
&amp;nbsp; public static void Initialize(TestContext context)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config = new HttpConfiguration();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Register(config);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [ClassCleanup]&lt;br /&gt;
&amp;nbsp; public static void Cleanup()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.Dispose();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [TestMethod]&lt;br /&gt;
&amp;nbsp; public async Task GetProducts()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var controller = CreateController&amp;lt;MyController&gt;();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static T CreateController&amp;lt;T&gt;(HttpRequestMessage request = null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; where T: ApiController&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (request == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request = new HttpRequestMessage();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; request.SetConfiguration(config);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var controllerContext = new HttpControllerContext()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Configuration = config,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Request = request&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var scope = request.GetDependencyScope();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = scope.GetService(typeof(IUnityContainer)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; as IUnityContainer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (container != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpControllerContext&gt;(controllerContext);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpRequestMessage&gt;(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;CancellationToken&gt;(CancellationToken.None);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; T controller = scope.GetService(typeof(T)) as T;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Configuration = config;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Request = request;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.ControllerContext = controllerContext;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return controller;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static void Register(HttpConfiguration config)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.DependencyResolver = CreateDependencyResolver(config);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static IDependencyResolver CreateDependencyResolver(HttpConfiguration
config)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = new UnityContainer();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpConfiguration&gt;(config);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO: configure Unity contaiener.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return new UnityHierarchicalDependencyResolver(container);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static HttpConfiguration config;&lt;br /&gt;
} &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
P.S. To those who think Dependency Injection is an universal tool, please read the
article: &lt;a href="http://www.tonymarston.net/php-mysql/dependency-injection-is-evil.html"&gt;Dependency
Injection is Evil&lt;/a&gt;. &lt;img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif"&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b3fe14e3-9656-4ccc-bb03-16dc4a4e7374" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b3fe14e3-9656-4ccc-bb03-16dc4a4e7374.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ccf080fd-f850-442a-afc3-f15e4cdd2e4b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ccf080fd-f850-442a-afc3-f15e4cdd2e4b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ccf080fd-f850-442a-afc3-f15e4cdd2e4b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier this year <a href="http://www.asp.net/web-api/overview/advanced/dependency-injection#author-36870">Mike
Wasson</a> has published a post: "<a href="http://www.asp.net/web-api/overview/advanced/dependency-injection">Dependency
Injection in ASP.NET Web API 2</a>" that describes Web API's approach to
the <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection
design pattern</a>.
</p>
        <p>
In short it goes like this:
</p>
        <ul>
          <li>
Web API provides a primary integration point through <code>HttpConfiguration.DependencyResolver</code> property,
and tries to obtain many services through this resolver;</li>
          <li>
Web API suggests to use your favorite Dependecy Injection library through the integration
point. Author lists following libraries: <span><a href="http://msdn.microsoft.com/en-us/library/ff647202.aspx">Unity</a> (by
Microsoft), <a href="http://www.castleproject.org/">Castle Windsor</a>, <a href="http://www.springframework.net/">Spring.Net</a>, <a href="http://code.google.com/p/autofac/">Autofac</a>, <a href="http://www.ninject.org/">Ninject</a>,
and <a href="http://docs.structuremap.net/">StructureMap</a>.</span></li>
        </ul>
        <p>
The Unity Container (Unity) is a lightweight, extensible dependency injection container.
There are Nugets both for Unity library and for Web API integration.
</p>
        <p>
Now to the point of this post.
</p>
        <p>
Unity defines a hierarchy of injection scopes. In Web API they are usually mapped
to application and request scopes. This way a developer can inject application singletons,
create request level, or transient objects.
</p>
        <p>
Everything looks reasonable. The only problem we have found is that there is no way
you to inject Web API objects like <code>HttpConfiguration</code>, <code>HttpControllerContext</code> or
request's <code>CancellationToken</code>, as they are never registered for injection.
</p>
        <p>
To workaround this we have created a small class called <code>UnityControllerActivator</code> that
perfroms required registration:
</p>
        <blockquote>
          <code> using System;<br />
using System.Net.Http;<br />
using System.Threading;<br />
using System.Threading.Tasks;<br />
using System.Web.Http.Controllers;<br />
using System.Web.Http.Dispatcher;<br /><br />
using Microsoft.Practices.Unity;<br /><br />
/// &lt;summary&gt;<br />
/// Unity controller activator.<br />
/// &lt;/summary&gt;<br />
public class UnityControllerActivator: IHttpControllerActivator<br />
{<br />
  /// &lt;summary&gt;<br />
  /// Creates an UnityControllerActivator instance.<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="activator"&gt;Base activator.&lt;/param&gt;<br />
  public UnityControllerActivator(IHttpControllerActivator activator)<br />
  {<br />
    if (activator == null)<br />
    {<br />
      throw new ArgumentException("activator");<br />
    }<br /><br />
    this.activator = activator;<br />
  }<br /><br />
  /// &lt;summary&gt;<br />
  /// Creates a controller wrapper.<br />
  /// &lt;/summary&gt;<br />
  /// &lt;param name="request"&gt;A http request.&lt;/param&gt;<br />
  /// &lt;param name="controllerDescriptor"&gt;Controller descriptor.&lt;/param&gt;<br />
  /// &lt;param name="controllerType"&gt;Controller type.&lt;/param&gt;<br />
  /// &lt;returns&gt;A controller wrapper.&lt;/returns&gt;<br />
  public IHttpController Create(<br />
    HttpRequestMessage request, 
<br />
    HttpControllerDescriptor controllerDescriptor, 
<br />
    Type controllerType)<br />
  {<br />
    return new Controller 
<br />
    { 
<br />
      activator = activator,<br />
      controllerType = controllerType 
<br />
    };<br />
  }<br /><br />
  /// &lt;summary&gt;<br />
  /// Base controller activator.<br />
  /// &lt;/summary&gt;<br />
  private readonly IHttpControllerActivator activator;<br /><br />
  /// &lt;summary&gt;<br />
  /// A controller wrapper.<br />
  /// &lt;/summary&gt;<br />
  private class Controller: IHttpController, IDisposable<br />
  {<br />
    /// &lt;summary&gt;<br />
    /// Base controller activator.<br />
    /// &lt;/summary&gt;<br />
    public IHttpControllerActivator activator;<br /><br />
    /// &lt;summary&gt;<br />
    /// Controller type.<br />
    /// &lt;/summary&gt;<br />
    public Type controllerType;<br /><br />
    /// &lt;summary&gt;<br />
    /// A controller instance.<br />
    /// &lt;/summary&gt;<br />
    public IHttpController controller;<br /><br />
    /// &lt;summary&gt;<br />
    /// Disposes controller.<br />
    /// &lt;/summary&gt;<br />
    public void Dispose()<br />
    {<br />
      var disposable = controller as IDisposable;<br /><br />
      if (disposable != null)<br />
      {<br />
        disposable.Dispose();<br />
      }<br />
    }<br /><br />
    /// &lt;summary&gt;<br />
    /// Executes an action.<br />
    /// &lt;/summary&gt;<br />
    /// &lt;param name="controllerContext"&gt;Controller context.&lt;/param&gt;<br />
    /// &lt;param name="cancellationToken"&gt;Cancellation token.&lt;/param&gt;<br />
    /// &lt;returns&gt;Response message.&lt;/returns&gt;<br />
    public Task&lt;HttpResponseMessage&gt; ExecuteAsync(<br />
      HttpControllerContext controllerContext, 
<br />
      CancellationToken cancellationToken)<br />
    {<br />
      if (controller == null)<br />
      {<br />
        var request = controllerContext.Request;<br />
        <b>var container = request.GetDependencyScope().<br />
          GetServices(typeof(IUnityContainer))
as IUnityContainer;<br /><br />
        if (container != null)<br />
        {<br />
          container.RegisterInstance&lt;HttpControllerContext&gt;(controllerContext);<br />
          container.RegisterInstance&lt;HttpRequestMessage&gt;(request);<br />
          container.RegisterInstance&lt;CancellationToken&gt;(cancellationToken);<br />
        }<br /></b><br />
        controller = activator.Create(<br />
          request, 
<br />
          controllerContext.ControllerDescriptor, 
<br />
          controllerType);<br />
      }<br /><br />
      controllerContext.Controller = controller;<br /><br />
      return controller.ExecuteAsync(controllerContext, cancellationToken);<br />
    }<br />
  }<br />
} </code>
        </blockquote>
        <p>
          <b>Note on how it works.</b>
        </p>
        <blockquote>
          <ul>
            <li>
              <code>IHttpControllerActivator</code> is a controller factory, which Web API uses
to create new controller instances using <code>IHttpControllerActivator.Create()</code>.
Later controller's <code>IHttpController.ExecuteAsync()</code> is called to run the
logic.</li>
            <li>
              <code>UnityControllerActivator</code> replaces original controller activator with
a wrapper that delays creation (injection) of real controller untill request objects
are registered in the scope</li>
          </ul>
        </blockquote>
        <p>
To register this class one need to update code in the <code>UnityWebApiActivator.cs</code> (file
added with nuget <code>Unity.AspNet.WebApi</code>)
</p>
        <blockquote>
          <code> public static class UnityWebApiActivator<br />
{<br />
  /// &lt;summary&gt;Integrates Unity when the application starts.&lt;summary&gt;<br />
  public static void Start() 
<br />
  {<br />
    var config = GlobalConfiguration.Configuration;<br />
    var container = UnityConfig.GetConfiguredContainer();<br /><br />
    container.RegisterInstance&lt;HttpConfiguration&gt;(config);<br />
    container.RegisterInstance&lt;IHttpControllerActivator&gt;(<br />
      new UnityControllerActivator(config.Services.GetHttpControllerActivator()));<br /><br />
    config.DependencyResolver = UnityHierarchicalDependencyResolver(container);<br />
  }<br />
  ...<br />
} </code>
        </blockquote>
        <p>
With this addition we have simplified the boring problem with passing of <code>CancellationToken</code> all
around the code, as controller (and other classes) just declared a property to inject:
</p>
        <blockquote>
          <code> public class MyController: ApiController<br />
{<br />
  [Dependency]<br />
  public CancellationToken CancellationToken { get; set; }<br /><br />
  [Dependency]<br />
  public IModelContext Model { get; set; }<br /><br />
  public async Task&lt;IEnumerable&lt;Products&gt;&gt; GetProducts(...)<br />
  {<br />
    ...<br />
  }<br /><br />
  public async Task&lt;IEnumerable&lt;Customer&gt;&gt; GetCustomer(...)<br />
  {<br />
    ...<br />
  }<br /><br />
  ...<br />
}<br /><br />
...<br /><br />
public class ModelContext: IModelContext<br />
{<br />
  [Dependency]<br />
  public CancellationToken CancellationToken { get; set; }<br />
  ...<br />
} </code>
        </blockquote>
        <p>
And finally to perform unit tests for controllers with Depenency Injection you can
use a code like this:
</p>
        <blockquote>
          <code> using System.Threading;<br />
using System.Threading.Tasks;<br />
using System.Web.Http;<br />
using System.Web.Http.Controllers;<br />
using System.Web.Http.Dependencies;<br />
using System.Net.Http;<br /><br />
using Microsoft.Practices.Unity;<br />
using Microsoft.Practices.Unity.WebApi;<br /><br />
using Microsoft.VisualStudio.TestTools.UnitTesting;<br /><br />
[TestClass]<br />
public class MyControllerTest<br />
{<br />
  [ClassInitialize]<br />
  public static void Initialize(TestContext context)<br />
  {<br />
    config = new HttpConfiguration();<br /><br />
    Register(config);<br />
  }<br /><br />
  [ClassCleanup]<br />
  public static void Cleanup()<br />
  {<br />
    config.Dispose();<br />
  }<br /><br />
  [TestMethod]<br />
  public async Task GetProducts()<br />
  {<br />
    var controller = CreateController&lt;MyController&gt;();<br /><br />
    //...<br />
  }<br /><br />
  public static T CreateController&lt;T&gt;(HttpRequestMessage request = null)<br />
    where T: ApiController<br />
  {<br />
    if (request == null)<br />
    {<br />
      request = new HttpRequestMessage();<br />
    }<br /><br />
    request.SetConfiguration(config);<br /><br />
    var controllerContext = new HttpControllerContext()<br />
    {<br />
      Configuration = config,<br />
      Request = request<br />
    };<br /><br />
    var scope = request.GetDependencyScope();<br />
    var container = scope.GetService(typeof(IUnityContainer)) 
<br />
      as IUnityContainer;<br /><br />
    if (container != null)<br />
    {<br />
      container.RegisterInstance&lt;HttpControllerContext&gt;(controllerContext);<br />
      container.RegisterInstance&lt;HttpRequestMessage&gt;(request);<br />
      container.RegisterInstance&lt;CancellationToken&gt;(CancellationToken.None);<br />
    }<br /><br />
    T controller = scope.GetService(typeof(T)) as T;<br /><br />
    controller.Configuration = config;<br />
    controller.Request = request;<br />
    controller.ControllerContext = controllerContext;<br /><br />
    return controller;<br />
  }<br /><br />
  public static void Register(HttpConfiguration config)<br />
  {<br />
    config.DependencyResolver = CreateDependencyResolver(config);<br />
  }<br /><br />
  public static IDependencyResolver CreateDependencyResolver(HttpConfiguration
config)<br />
  {<br />
    var container = new UnityContainer();<br /><br />
    container.RegisterInstance&lt;HttpConfiguration&gt;(config);<br /><br />
    // TODO: configure Unity contaiener.<br /><br />
    return new UnityHierarchicalDependencyResolver(container);<br />
  }<br /><br />
  public static HttpConfiguration config;<br />
} </code>
        </blockquote>
        <p>
P.S. To those who think Dependency Injection is an universal tool, please read the
article: <a href="http://www.tonymarston.net/php-mysql/dependency-injection-is-evil.html">Dependency
Injection is Evil</a>. <img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif" /></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ccf080fd-f850-442a-afc3-f15e4cdd2e4b" />
      </body>
      <title>Single Page Apps with AngularJS and base url error</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ccf080fd-f850-442a-afc3-f15e4cdd2e4b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/12/02/SinglePageAppsWithAngularJSAndBaseUrlError.aspx</link>
      <pubDate>Tue, 02 Dec 2014 11:56:09 GMT</pubDate>
      <description>  &lt;p&gt;
Earlier this year &lt;a href="http://www.asp.net/web-api/overview/advanced/dependency-injection#author-36870" &gt;Mike
Wasson&lt;/a&gt; has published a post: "&lt;a href="http://www.asp.net/web-api/overview/advanced/dependency-injection"&gt;Dependency
Injection in ASP.NET Web API 2&lt;/a&gt;&amp;quot; that describes Web API&amp;#39;s approach to
the &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection
design pattern&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
In short it goes like this:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Web API provides a primary integration point through &lt;code&gt;HttpConfiguration.DependencyResolver&lt;/code&gt; property,
and tries to obtain many services through this resolver;&lt;/li&gt;
&lt;li&gt;
Web API suggests to use your favorite Dependecy Injection library through the integration
point. Author lists following libraries: &lt;span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ff647202.aspx"&gt;Unity&lt;/a&gt; (by
Microsoft), &lt;a href="http://www.castleproject.org/"&gt;Castle Windsor&lt;/a&gt;, &lt;a href="http://www.springframework.net/"&gt;Spring.Net&lt;/a&gt;, &lt;a href="http://code.google.com/p/autofac/"&gt;Autofac&lt;/a&gt;, &lt;a href="http://www.ninject.org/"&gt;Ninject&lt;/a&gt;,
and &lt;a href="http://docs.structuremap.net/"&gt;StructureMap&lt;/a&gt;.&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The Unity Container (Unity) is a lightweight, extensible dependency injection container.
There are Nugets both for Unity library and for Web API integration.
&lt;/p&gt;
&lt;p&gt;
Now to the point of this post.
&lt;/p&gt;
&lt;p&gt;
Unity defines a hierarchy of injection scopes. In Web API they are usually mapped
to application and request scopes. This way a developer can inject application singletons,
create request level, or transient objects.
&lt;/p&gt;
&lt;p&gt;
Everything looks reasonable. The only problem we have found is that there is no way
you to inject Web API objects like &lt;code&gt;HttpConfiguration&lt;/code&gt;, &lt;code&gt;HttpControllerContext&lt;/code&gt; or
request's &lt;code&gt;CancellationToken&lt;/code&gt;, as they are never registered for injection.
&lt;/p&gt;
&lt;p&gt;
To workaround this we have created a small class called &lt;code&gt;UnityControllerActivator&lt;/code&gt; that
perfroms required registration:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; using System;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Web.Http.Controllers;&lt;br /&gt;
using System.Web.Http.Dispatcher;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.Practices.Unity;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Unity controller activator.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public class UnityControllerActivator: IHttpControllerActivator&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Creates an UnityControllerActivator instance.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="activator"&gt;Base activator.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; public UnityControllerActivator(IHttpControllerActivator activator)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (activator == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("activator");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this.activator = activator;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Creates a controller wrapper.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="request"&gt;A http request.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="controllerDescriptor"&gt;Controller descriptor.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="controllerType"&gt;Controller type.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A controller wrapper.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp; public IHttpController Create(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpRequestMessage request, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpControllerDescriptor controllerDescriptor, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Type controllerType)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Controller 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; activator = activator,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerType = controllerType 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Base controller activator.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; private readonly IHttpControllerActivator activator;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// A controller wrapper.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; private class Controller: IHttpController, IDisposable&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Base controller activator.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public IHttpControllerActivator activator;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Controller type.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Type controllerType;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A controller instance.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public IHttpController controller;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Disposes controller.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Dispose()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var disposable = controller as IDisposable;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (disposable != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disposable.Dispose();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Executes an action.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="controllerContext"&gt;Controller context.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="cancellationToken"&gt;Cancellation token.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;Response message.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Task&amp;lt;HttpResponseMessage&gt; ExecuteAsync(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpControllerContext controllerContext, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CancellationToken cancellationToken)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (controller == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var request = controllerContext.Request;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;var container = request.GetDependencyScope().&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetServices(typeof(IUnityContainer))
as IUnityContainer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (container != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpControllerContext&gt;(controllerContext);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpRequestMessage&gt;(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;CancellationToken&gt;(cancellationToken);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;/b&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controller = activator.Create(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerContext.ControllerDescriptor, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerType);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; controllerContext.Controller = controller;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return controller.ExecuteAsync(controllerContext, cancellationToken);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
} &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;b&gt;Note on how it works.&lt;/b&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IHttpControllerActivator&lt;/code&gt; is a controller factory, which Web API uses
to create new controller instances using &lt;code&gt;IHttpControllerActivator.Create()&lt;/code&gt;.
Later controller's &lt;code&gt;IHttpController.ExecuteAsync()&lt;/code&gt; is called to run the
logic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UnityControllerActivator&lt;/code&gt; replaces original controller activator with
a wrapper that delays creation (injection) of real controller untill request objects
are registered in the scope&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To register this class one need to update code in the &lt;code&gt;UnityWebApiActivator.cs&lt;/code&gt; (file
added with nuget &lt;code&gt;Unity.AspNet.WebApi&lt;/code&gt;)
&lt;/p&gt;
&lt;blockquote&gt; &lt;code&gt; public static class UnityWebApiActivator&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;Integrates Unity when the application starts.&amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; public static void Start() 
&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var config = GlobalConfiguration.Configuration;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = UnityConfig.GetConfiguredContainer();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpConfiguration&gt;(config);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;IHttpControllerActivator&gt;(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new UnityControllerActivator(config.Services.GetHttpControllerActivator()));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.DependencyResolver = UnityHierarchicalDependencyResolver(container);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
} &lt;/code&gt; &lt;/blockquote&gt; 
&lt;p&gt;
With this addition we have simplified the boring problem with passing of &lt;code&gt;CancellationToken&lt;/code&gt; all
around the code, as controller (and other classes) just declared a property to inject:
&lt;/p&gt;
&lt;blockquote&gt; &lt;code&gt; public class MyController: ApiController&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public CancellationToken CancellationToken { get; set; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public IModelContext Model { get; set; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;IEnumerable&amp;lt;Products&gt;&gt; GetProducts(...)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;IEnumerable&amp;lt;Customer&gt;&gt; GetCustomer(...)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
public class ModelContext: IModelContext&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [Dependency]&lt;br /&gt;
&amp;nbsp; public CancellationToken CancellationToken { get; set; }&lt;br /&gt;
&amp;nbsp; ...&lt;br /&gt;
} &lt;/code&gt; &lt;/blockquote&gt; 
&lt;p&gt;
And finally to perform unit tests for controllers with Depenency Injection you can
use a code like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Web.Http;&lt;br /&gt;
using System.Web.Http.Controllers;&lt;br /&gt;
using System.Web.Http.Dependencies;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.Practices.Unity;&lt;br /&gt;
using Microsoft.Practices.Unity.WebApi;&lt;br /&gt;
&lt;br /&gt;
using Microsoft.VisualStudio.TestTools.UnitTesting;&lt;br /&gt;
&lt;br /&gt;
[TestClass]&lt;br /&gt;
public class MyControllerTest&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; [ClassInitialize]&lt;br /&gt;
&amp;nbsp; public static void Initialize(TestContext context)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config = new HttpConfiguration();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Register(config);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [ClassCleanup]&lt;br /&gt;
&amp;nbsp; public static void Cleanup()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.Dispose();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; [TestMethod]&lt;br /&gt;
&amp;nbsp; public async Task GetProducts()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var controller = CreateController&amp;lt;MyController&gt;();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //...&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static T CreateController&amp;lt;T&gt;(HttpRequestMessage request = null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; where T: ApiController&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (request == null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request = new HttpRequestMessage();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; request.SetConfiguration(config);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var controllerContext = new HttpControllerContext()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Configuration = config,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Request = request&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var scope = request.GetDependencyScope();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = scope.GetService(typeof(IUnityContainer)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; as IUnityContainer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (container != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpControllerContext&gt;(controllerContext);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpRequestMessage&gt;(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;CancellationToken&gt;(CancellationToken.None);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; T controller = scope.GetService(typeof(T)) as T;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Configuration = config;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.Request = request;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; controller.ControllerContext = controllerContext;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return controller;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static void Register(HttpConfiguration config)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; config.DependencyResolver = CreateDependencyResolver(config);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static IDependencyResolver CreateDependencyResolver(HttpConfiguration
config)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = new UnityContainer();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; container.RegisterInstance&amp;lt;HttpConfiguration&gt;(config);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO: configure Unity contaiener.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return new UnityHierarchicalDependencyResolver(container);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static HttpConfiguration config;&lt;br /&gt;
} &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
P.S. To those who think Dependency Injection is an universal tool, please read the
article: &lt;a href="http://www.tonymarston.net/php-mysql/dependency-injection-is-evil.html"&gt;Dependency
Injection is Evil&lt;/a&gt;. &lt;img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif"&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ccf080fd-f850-442a-afc3-f15e4cdd2e4b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ccf080fd-f850-442a-afc3-f15e4cdd2e4b.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6</wfw:commentRss>
      <title>.NET Cache API</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/07/28/NETCacheAPI.aspx</link>
      <pubDate>Mon, 28 Jul 2014 05:36:06 GMT</pubDate>
      <description>  &lt;p&gt;
Looking at &lt;a href="http://code.google.com/p/guava-libraries/wiki/CachesExplained"&gt;Guava
Cache&lt;/a&gt; we think its API is more convenient than &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx"&gt;.NET&amp;#39;s
Cache API&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Just consider: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
.NET has getters, and setters of &lt;code&gt;object&lt;/code&gt;s by &lt;code&gt;string&lt;/code&gt; keys. 
&lt;br /&gt;
You should provide caching policy with each setter. 
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Guava cache operates with typed storage of &lt;code&gt;Key&lt;/code&gt; to &lt;code&gt;Value.&lt;/code&gt;
&lt;br /&gt;
Provides a value factory and a caching policy in advance at cache construction. 
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Guava&amp;#39;s advantange is based on an idea that homogenous storage assumes a uniform
way of creation of values, and uniform caching policy. Thus a great part of logic
is factored out into a cache initialization. 
&lt;/p&gt;
&lt;p&gt;
We have decided to create a simple adapter of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx"&gt;MemoryCache&lt;/a&gt; to
achieve the same goal. Here is a result of such an experiment: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public class Cache&amp;lt;K, V&gt; 
&lt;br /&gt;
&amp;nbsp; where V: class 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// A cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; public struct Builder 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A memory cache. If not specified then MemoryCache.Default is
used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public MemoryCache MemoryCache; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// An expiration value. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively CachePolicyFunc can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public TimeSpan Expiration; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Indicates whether to use sliding (true), or absolute (false) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// expiration. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively CachePolicyFunc can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool Sliding; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Optional function to get caching policy. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively Expiration and Sliding property can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;V, CacheItemPolicy&gt; CachePolicyFunc; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Optional value validator. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;V, bool&gt; Validator; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A value factory. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively FactoryAsync can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, V&gt; Factory; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Async value factory. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively Factory can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, Task&amp;lt;V&gt;&gt; FactoryAsync; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A key to string converter. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, string&gt; KeyFunc; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Converts builder to a Cache&amp;lt;K, V&gt; instance. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="builder"&gt;A builder to convert.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;A Cache&amp;lt;K, V&gt; instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static implicit operator Cache&amp;lt;K, V&gt;(Builder builder) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Cache&amp;lt;K, V&gt;(builder); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a cache from a cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="builder"&gt;A cache builder instance.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; public Cache(Builder builder) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((builder.Factory == null) &amp;&amp; (builder.FactoryAsync == null)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("builder.Factory"); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (builder.MemoryCache == null) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache = MemoryCache.Default; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this.builder = builder; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Cached value by key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A cached value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public V this[K key] 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return Get(key); } 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; set { Set(key, value); } 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Sets a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; public void Set(K key, V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(GetKey(key), IsValid(value) ? value : null); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to get value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public V Get(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var keyValue = GetKey(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var value = builder.MemoryCache.Get(keyValue) as V; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!IsValid(value)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = CreateValue(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(keyValue, value); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets a task to return an async value. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A cached value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;V&gt; GetAsync(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var keyValue = GetKey(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var value = builder.MemoryCache.Get(keyValue) as V; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!IsValid(value)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = await CreateValueAsync(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(keyValue, value); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets string key value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A string key value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected string GetKey(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.KeyFunc != null ? builder.KeyFunc(key) : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key == null ? null : key.ToString(); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to create value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected V CreateValue(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.Factory != null ? builder.Factory(key) : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.FactoryAsync(key).Result; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a task for value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to create value for.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A task for a value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected Task&amp;lt;V&gt; CreateValueAsync(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.FactoryAsync != null ? builder.FactoryAsync(key)
: 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Task.FromResult(builder.Factory(key)); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Validates the value. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to validate.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt; 
&lt;br /&gt;
&amp;nbsp; /// true if value is valid for a cache, and false otherise. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected bool IsValid(V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return (value != null) &amp;&amp; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((builder.Validator == null) || builder.Validator(value)); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Set implementation. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to set value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A set value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; private V SetImpl(string key, V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (value == null) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache.Remove(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache.Set( 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.CachePolicyFunc != null ? builder.CachePolicyFunc(value)
: 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.Sliding ? 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CacheItemPolicy { SlidingExpiration
= builder.Expiration } : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CacheItemPolicy 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AbsoluteExpiration
= DateTime.Now + builder.Expiration 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; private Builder builder; 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The use consists of initialization:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; Cache&amp;lt;MyKey, MyValue&gt; MyValues = new Cache&amp;lt;MyKey, MyValue&gt;.Builder 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;nbsp; KeyFunc = key =&gt; ...key to string value..., 
&lt;br /&gt;
&amp;nbsp; Factory = key =&gt; ...create a value for a key..., 
&lt;br /&gt;
&amp;nbsp; Expiration = new TimeSpan(0, 3, 0), 
&lt;br /&gt;
&amp;nbsp; Sliding = true 
&lt;br /&gt;
}; &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
and a trivial cache access:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;var value = MyValues[key];&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This contrasts with MemoryCache coding pattern:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; MemoryCache cache = MemoryCache.Default;&lt;br /&gt;
... &lt;/code&gt; 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var keyAsString = ...key to string value...&lt;br /&gt;
var value = cache.Get(keyAsString) as MyValue;&lt;br /&gt;
&lt;br /&gt;
if (value == null)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; value = ...create a value for a key...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; cache.Set(keyAsString, value, ...caching policy...);&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=be57df20-9025-4f1b-849e-5b982df91f7a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,be57df20-9025-4f1b-849e-5b982df91f7a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=be57df20-9025-4f1b-849e-5b982df91f7a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the article <a href="http://www.nesterovsky-bros.com/weblog/2013/05/13/ErrorHandlingInWCFBasedWebApplications.aspx">"Error
handling in WCF based web applications"</a> we've shown a custom error handler
for RESTful service based on WCF. This time we shall do the same for Web API 2.1 service. 
</p>
        <p>
Web API 2.1 provides an elegant way to implementat custom error handlers/loggers,
see <a href="http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling">the
following article.</a> Web API permits many error loggers followed by a single error
handler for all uncaught exceptions. A default error handler knows to output an error
both in XML and JSON formats depending on requested MIME type. 
</p>
        <p>
In our projects we use unique error reference IDs. This feature allows to an end-user
to refer to any error that has happened during the application life time and pass
such error ID to the technical support for further investigations. Thus, error details
passed to the client-side contain an ErrorID field. An error logger generates ErrorID
and passes it over to an error handler for serialization. 
</p>
        <p>
Let's look at our error handling implementation for a Web API application. 
</p>
        <p>
The first part is an implementation of <code>IExceptionLogger</code> interface. It
assigns ErrorID and logs all errors: 
</p>
        <p style="padding-left: 1em">
          <code> /// Defines a global logger for unhandled exceptions.<br />
public class GlobalExceptionLogger : ExceptionLogger<br />
{<br />
/// Writes log record to the database synchronously.<br />
public override void Log(ExceptionLoggerContext context)<br />
{<br />
try<br />
{<br />
var request = context.Request;<br />
var exception = context.Exception;<br /><br />
var id = LogError(<br />
request.RequestUri.ToString(),<br />
context.RequestContext == null ?<br />
null : context.RequestContext.Principal.Identity.Name,<br />
request.ToString(),<br />
exception.Message,<br />
exception.StackTrace);<br /><br />
// associates retrieved error ID with the current exception<br />
exception.Data["NesterovskyBros:id"] = id;<br />
}<br />
catch<br />
{<br />
// logger shouldn't throw an exception!!!<br />
}<br />
}<br /><br />
// in the real life this method may store all relevant info into a database.<br />
private long LogError(<br />
string address,<br />
string userid,<br />
string request,<br />
string message,<br />
string stackTrace)<br />
{<br />
...<br />
}<br />
} </code>
        </p>
        <p>
The second part is the implementation of <code>IExceptionHandler</code>:
</p>
        <p style="padding-left: 1em">
          <code> /// Defines a global handler for unhandled exceptions.<br />
public class GlobalExceptionHandler : ExceptionHandler<br />
{<br />
/// This core method should implement custom error handling, if any.<br />
/// It determines how an exception will be serialized for client-side processing.<br />
public override void Handle(ExceptionHandlerContext context)<br />
{<br />
var requestContext = context.RequestContext;<br />
var config = requestContext.Configuration;<br /><br />
context.Result = new ErrorResult(<br />
context.Exception,<br />
requestContext == null ? false : requestContext.IncludeErrorDetail,<br />
config.Services.GetContentNegotiator(),<br />
context.Request,<br />
config.Formatters);<br />
}<br /><br />
/// An implementation of IHttpActionResult interface.<br />
private class ErrorResult : ExceptionResult<br />
{<br />
public ErrorResult(<br />
Exception exception,<br />
bool includeErrorDetail,<br />
IContentNegotiator negotiator,<br />
HttpRequestMessage request,<br />
IEnumerable&lt;MediaTypeFormatter&gt; formatters) :<br />
base(exception, includeErrorDetail, negotiator, request, formatters)<br />
{<br />
}<br /><br />
/// Creates an HttpResponseMessage instance asynchronously.<br />
/// This method determines how a HttpResponseMessage content will look like.<br />
public override Task&lt;HttpResponseMessage&gt; ExecuteAsync(CancellationToken cancellationToken)<br />
{<br />
var content = new HttpError(Exception, IncludeErrorDetail);<br /><br />
// define an additional content field with name "ErrorID"<br />
content.Add("ErrorID", Exception.Data["NesterovskyBros:id"] as long?);<br /><br />
var result =<br />
ContentNegotiator.Negotiate(typeof(HttpError), Request, Formatters);<br /><br />
var message = new HttpResponseMessage<br />
{<br />
RequestMessage = Request,<br />
StatusCode = result == null ?<br />
HttpStatusCode.NotAcceptable : HttpStatusCode.InternalServerError<br />
};<br /><br />
if (result != null)<br />
{<br />
try<br />
{<br />
// serializes the HttpError instance either to JSON or to XML<br />
// depend on requested by the client MIME type.<br />
message.Content = new ObjectContent&lt;HttpError&gt;(<br />
content,<br />
result.Formatter,<br />
result.MediaType);<br />
}<br />
catch<br />
{<br />
message.Dispose();<br /><br />
throw;<br />
}<br />
}<br /><br />
return Task.FromResult(message);<br />
}<br />
}<br />
} </code>
        </p>
        <p>
Last, but not least part of this solution is registration and configuration of the
error logger/handler: 
</p>
        <p style="padding-left: 1em">
          <code> /// WebApi congiguation.<br />
public static class WebApiConfig<br />
{<br />
public static void Register(HttpConfiguration config)<br />
{<br />
...<br /><br />
// register the exception logger and handler<br />
config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());<br />
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());<br /><br />
// set error detail policy according with value from Web.config<br />
var customErrors =<br />
(CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors");<br /><br />
if (customErrors != null)<br />
{<br />
switch (customErrors.Mode)<br />
{<br />
case CustomErrorsMode.RemoteOnly:<br />
{<br />
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;<br /><br />
break;<br />
}<br />
case CustomErrorsMode.On:<br />
{<br />
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;<br /><br />
break;<br />
}<br />
case CustomErrorsMode.Off:<br />
{<br />
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;<br /><br />
break;<br />
}<br />
default:<br />
{<br />
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Default;<br /><br />
break;<br />
}<br />
}<br />
}<br />
}<br />
} </code>
        </p>
        <p>
The client-side error handler remain almost untouched. The implementation details
you may find in <code>/Scripts/api/api.js</code> and <code>Scripts/controls/error.js</code> files. 
</p>
        <p>
You may <a href="http://www.nesterovsky-bros.com/download/GlobalErrorHandler.zip">download
the demo project here</a>. Feel free to use this solution in your .NET projects. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=be57df20-9025-4f1b-849e-5b982df91f7a" />
      </body>
      <title>Custom error handling with Web API</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,be57df20-9025-4f1b-849e-5b982df91f7a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/03/10/CustomErrorHandlingWithWebAPI.aspx</link>
      <pubDate>Mon, 10 Mar 2014 10:56:24 GMT</pubDate>
      <description>    &lt;p&gt;
In the article &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/05/13/ErrorHandlingInWCFBasedWebApplications.aspx"&gt;&amp;quot;Error
handling in WCF based web applications&amp;quot;&lt;/a&gt; we've shown a custom error handler
for RESTful service based on WCF. This time we shall do the same for Web API 2.1 service. 
&lt;/p&gt;
&lt;p&gt;
Web API 2.1 provides an elegant way to implementat custom error handlers/loggers,
see &lt;a href="http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling"&gt;the
following article.&lt;/a&gt; Web API permits many error loggers followed by a single error
handler for all uncaught exceptions. A default error handler knows to output an error
both in XML and JSON formats depending on requested MIME type. 
&lt;/p&gt;
&lt;p&gt;
In our projects we use unique error reference IDs. This feature allows to an end-user
to refer to any error that has happened during the application life time and pass
such error ID to the technical support for further investigations. Thus, error details
passed to the client-side contain an ErrorID field. An error logger generates ErrorID
and passes it over to an error handler for serialization. 
&lt;/p&gt;
&lt;p&gt;
Let's look at our error handling implementation for a Web API application. 
&lt;/p&gt;
&lt;p&gt;
The first part is an implementation of &lt;code&gt;IExceptionLogger&lt;/code&gt; interface. It
assigns ErrorID and logs all errors: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// Defines a global logger for unhandled exceptions.&lt;br /&gt;
public class GlobalExceptionLogger : ExceptionLogger&lt;br /&gt;
{&lt;br /&gt;
/// Writes log record to the database synchronously.&lt;br /&gt;
public override void Log(ExceptionLoggerContext context)&lt;br /&gt;
{&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
var request = context.Request;&lt;br /&gt;
var exception = context.Exception;&lt;br /&gt;
&lt;br /&gt;
var id = LogError(&lt;br /&gt;
request.RequestUri.ToString(),&lt;br /&gt;
context.RequestContext == null ?&lt;br /&gt;
null : context.RequestContext.Principal.Identity.Name,&lt;br /&gt;
request.ToString(),&lt;br /&gt;
exception.Message,&lt;br /&gt;
exception.StackTrace);&lt;br /&gt;
&lt;br /&gt;
// associates retrieved error ID with the current exception&lt;br /&gt;
exception.Data["NesterovskyBros:id"] = id;&lt;br /&gt;
}&lt;br /&gt;
catch&lt;br /&gt;
{&lt;br /&gt;
// logger shouldn't throw an exception!!!&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// in the real life this method may store all relevant info into a database.&lt;br /&gt;
private long LogError(&lt;br /&gt;
string address,&lt;br /&gt;
string userid,&lt;br /&gt;
string request,&lt;br /&gt;
string message,&lt;br /&gt;
string stackTrace)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
The second part is the implementation of &lt;code&gt;IExceptionHandler&lt;/code&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// Defines a global handler for unhandled exceptions.&lt;br /&gt;
public class GlobalExceptionHandler : ExceptionHandler&lt;br /&gt;
{&lt;br /&gt;
/// This core method should implement custom error handling, if any.&lt;br /&gt;
/// It determines how an exception will be serialized for client-side processing.&lt;br /&gt;
public override void Handle(ExceptionHandlerContext context)&lt;br /&gt;
{&lt;br /&gt;
var requestContext = context.RequestContext;&lt;br /&gt;
var config = requestContext.Configuration;&lt;br /&gt;
&lt;br /&gt;
context.Result = new ErrorResult(&lt;br /&gt;
context.Exception,&lt;br /&gt;
requestContext == null ? false : requestContext.IncludeErrorDetail,&lt;br /&gt;
config.Services.GetContentNegotiator(),&lt;br /&gt;
context.Request,&lt;br /&gt;
config.Formatters);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// An implementation of IHttpActionResult interface.&lt;br /&gt;
private class ErrorResult : ExceptionResult&lt;br /&gt;
{&lt;br /&gt;
public ErrorResult(&lt;br /&gt;
Exception exception,&lt;br /&gt;
bool includeErrorDetail,&lt;br /&gt;
IContentNegotiator negotiator,&lt;br /&gt;
HttpRequestMessage request,&lt;br /&gt;
IEnumerable&amp;lt;MediaTypeFormatter&gt; formatters) :&lt;br /&gt;
base(exception, includeErrorDetail, negotiator, request, formatters)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// Creates an HttpResponseMessage instance asynchronously.&lt;br /&gt;
/// This method determines how a HttpResponseMessage content will look like.&lt;br /&gt;
public override Task&amp;lt;HttpResponseMessage&gt; ExecuteAsync(CancellationToken cancellationToken)&lt;br /&gt;
{&lt;br /&gt;
var content = new HttpError(Exception, IncludeErrorDetail);&lt;br /&gt;
&lt;br /&gt;
// define an additional content field with name "ErrorID"&lt;br /&gt;
content.Add("ErrorID", Exception.Data["NesterovskyBros:id"] as long?);&lt;br /&gt;
&lt;br /&gt;
var result =&lt;br /&gt;
ContentNegotiator.Negotiate(typeof(HttpError), Request, Formatters);&lt;br /&gt;
&lt;br /&gt;
var message = new HttpResponseMessage&lt;br /&gt;
{&lt;br /&gt;
RequestMessage = Request,&lt;br /&gt;
StatusCode = result == null ?&lt;br /&gt;
HttpStatusCode.NotAcceptable : HttpStatusCode.InternalServerError&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
if (result != null)&lt;br /&gt;
{&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
// serializes the HttpError instance either to JSON or to XML&lt;br /&gt;
// depend on requested by the client MIME type.&lt;br /&gt;
message.Content = new ObjectContent&amp;lt;HttpError&gt;(&lt;br /&gt;
content,&lt;br /&gt;
result.Formatter,&lt;br /&gt;
result.MediaType);&lt;br /&gt;
}&lt;br /&gt;
catch&lt;br /&gt;
{&lt;br /&gt;
message.Dispose();&lt;br /&gt;
&lt;br /&gt;
throw;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return Task.FromResult(message);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Last, but not least part of this solution is registration and configuration of the
error logger/handler: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// WebApi congiguation.&lt;br /&gt;
public static class WebApiConfig&lt;br /&gt;
{&lt;br /&gt;
public static void Register(HttpConfiguration config)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
// register the exception logger and handler&lt;br /&gt;
config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());&lt;br /&gt;
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());&lt;br /&gt;
&lt;br /&gt;
// set error detail policy according with value from Web.config&lt;br /&gt;
var customErrors =&lt;br /&gt;
(CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors");&lt;br /&gt;
&lt;br /&gt;
if (customErrors != null)&lt;br /&gt;
{&lt;br /&gt;
switch (customErrors.Mode)&lt;br /&gt;
{&lt;br /&gt;
case CustomErrorsMode.RemoteOnly:&lt;br /&gt;
{&lt;br /&gt;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
case CustomErrorsMode.On:&lt;br /&gt;
{&lt;br /&gt;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
case CustomErrorsMode.Off:&lt;br /&gt;
{&lt;br /&gt;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
default:&lt;br /&gt;
{&lt;br /&gt;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Default;&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
The client-side error handler remain almost untouched. The implementation details
you may find in &lt;code&gt;/Scripts/api/api.js&lt;/code&gt; and &lt;code&gt;Scripts/controls/error.js&lt;/code&gt; files. 
&lt;/p&gt;
&lt;p&gt;
You may &lt;a href="http://www.nesterovsky-bros.com/download/GlobalErrorHandler.zip"&gt;download
the demo project here&lt;/a&gt;. Feel free to use this solution in your .NET projects. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=be57df20-9025-4f1b-849e-5b982df91f7a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,be57df20-9025-4f1b-849e-5b982df91f7a.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9d90a7c4-6361-41fd-bd71-dab52eedcad0</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9d90a7c4-6361-41fd-bd71-dab52eedcad0.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9d90a7c4-6361-41fd-bd71-dab52eedcad0.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9d90a7c4-6361-41fd-bd71-dab52eedcad0</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
From time to time we run into tasks that we would like to solve in LINQ style but
unfortunately it either cannot be done or a solution is not efficient.
</p>
        <p>
Note that by LINQ style we do not mean C# query expressions (we have a strong distaste
for that syntax) but extension methods defined in <code>System.Linq.Enumerable</code> and
other classes.
</p>
        <p>
Here we quote several extension methods that are good for a general use:
</p>
        <p>
1. Select with predicate. This is shorthand of <code>items.Where(...).Select(...)</code>:
</p>
        <p style="padding-left: 1em">
          <code> /// &lt;summary&gt;<br />
/// Projects each element of a sequence into a new form.<br />
/// &lt;/summary&gt;<br />
/// &lt;typeparam name="T"&gt;A type of elements of source sequence.&lt;/typeparam&gt;<br />
/// &lt;typeparam name="R"&gt;A type of elements of target sequence.&lt;/typeparam&gt;<br />
/// &lt;param name="source"&gt;A source sequence.&lt;/param&gt;<br />
/// &lt;param name="where"&gt;A predicate to filter elements.&lt;/param&gt;<br />
/// &lt;param name="selector"&gt;A result element selector.&lt;/param&gt;<br />
/// &lt;returns&gt;A target sequence.&lt;/returns&gt;<br />
public static IEnumerable&lt;R&gt; Select&lt;T, R&gt;(<br />
this IEnumerable&lt;T&gt; source, 
<br />
Func&lt;T, bool&gt; where, 
<br />
Func&lt;T, R&gt; selector)<br />
{<br />
return source.Where(where).Select(selector);<br />
} </code>
        </p>
        <p>
2. Select with predicate with source element index passed both into the predicate
and into the selector. This one you cannot trivially implement in LINQ:
</p>
        <p style="padding-left: 1em">
          <code> /// &lt;summary&gt;<br />
/// Projects each element of a sequence into a new form.<br />
/// &lt;/summary&gt;<br />
/// &lt;typeparam name="T"&gt;A type of elements of source sequence.&lt;/typeparam&gt;<br />
/// &lt;typeparam name="R"&gt;A type of elements of target sequence.&lt;/typeparam&gt;<br />
/// &lt;param name="source"&gt;A source sequence.&lt;/param&gt;<br />
/// &lt;param name="where"&gt;A predicate to filter elements.&lt;/param&gt;<br />
/// &lt;param name="selector"&gt;A result element selector.&lt;/param&gt;<br />
/// &lt;returns&gt;A target sequence.&lt;/returns&gt;<br />
public static IEnumerable&lt;R&gt; Select&lt;T, R&gt;(<br />
this IEnumerable&lt;T&gt; source,<br />
Func&lt;T, int, bool&gt; where,<br />
Func&lt;T, int, R&gt; selector)<br />
{<br />
var index = 0;<br /><br />
foreach(var value in source)<br />
{<br />
if (where(value, index))<br />
{<br />
yield return selector(value, index);<br />
}<br /><br />
++index;<br />
}<br />
} </code>
        </p>
        <p>
3. A function with output element as projection of a window of input elements. Such
function can be used to get finite difference (operation opposite to a cumulative
sum).
</p>
        <p style="padding-left: 1em">
          <code> /// &lt;summary&gt;<br />
/// Projects a window of source elements in a source sequence into target sequence.<br />
/// Thus<br />
/// target[i] = 
<br />
/// selector(source[i], source[i - 1], ... source[i - window + 1])<br />
/// &lt;/summary&gt;<br />
/// &lt;typeparam name="T"&gt;A type of elements of source sequence.&lt;/typeparam&gt;<br />
/// &lt;typeparam name="R"&gt;A type of elements of target sequence.&lt;/typeparam&gt;<br />
/// &lt;param name="source"&gt;A source sequence.&lt;/param&gt;<br />
/// &lt;param name="window"&gt;A size of window.&lt;/param&gt;<br />
/// &lt;param name="lookbehind"&gt;<br />
/// Indicate whether to produce target if the number of source elements 
<br />
/// preceeding the current is less than the window size.<br />
/// &lt;/param&gt;<br />
/// &lt;param name="lookahead"&gt;<br />
/// Indicate whether to produce target if the number of source elements 
<br />
/// following current is less than the window size.<br />
/// &lt;/param&gt;<br />
/// &lt;param name="selector"&gt;<br />
/// A selector that derives target element.<br />
/// On input it receives:<br />
/// an array of source elements stored in round-robing fashon;<br />
/// an index of the first element;<br />
/// a number of elements in the array to count.<br />
/// &lt;/param&gt;<br />
/// &lt;returns&gt;Returns a sequence of target elements.&lt;/returns&gt;<br />
public static IEnumerable&lt;R&gt; Window&lt;T, R&gt;(<br />
this IEnumerable&lt;T&gt; source,<br />
int window,<br />
bool lookbehind,<br />
bool lookahead,<br />
Func&lt;T[], int, int, R&gt; selector)<br />
{<br />
var buffer = new T[window];<br />
var index = 0;<br />
var count = 0;<br /><br />
foreach(var value in source)<br />
{<br />
if (count &lt; window)<br />
{<br />
buffer[count++] = value;<br /><br />
if (lookbehind || (count == window))<br />
{<br />
yield return selector(buffer, 0, count);<br />
}<br />
}<br />
else<br />
{<br />
buffer[index] = value;<br />
index = index + 1 == window ? 0 : index + 1;<br /><br />
yield return selector(buffer, index, count);<br />
}<br />
}<br /><br />
if (lookahead)<br />
{<br />
while(--count &gt; 0)<br />
{<br />
index = index + 1 == window ? 0 : index + 1;<br /><br />
yield return selector(buffer, index, count);<br />
}<br />
}<br />
} </code>
        </p>
        <p>
This way a finite difference looks like this:
</p>
        <p style="padding-left: 1em">
          <code> var diff = input.Window(<br />
2,<br />
false,<br />
false,<br />
(buffer, index, count) =&gt; buffer[index ^ 1] - buffer[index]); </code>
        </p>
        <p>
4. A specialization of <code>Window</code> method that returns a enumeration of windows:
</p>
        <p style="padding-left: 1em">
          <code> /// &lt;summary&gt;<br />
/// Projects a window of source elements in a source sequence into a<br />
/// sequence of window arrays.<br />
/// &lt;/summary&gt;<br />
/// &lt;typeparam name="T"&gt;A type of elements of source sequence.&lt;/typeparam&gt;<br />
/// &lt;typeparam name="R"&gt;A type of elements of target sequence.&lt;/typeparam&gt;<br />
/// &lt;param name="source"&gt;A source sequence.&lt;/param&gt;<br />
/// &lt;param name="window"&gt;A size of window.&lt;/param&gt;<br />
/// &lt;param name="lookbehind"&gt;<br />
/// Indicate whether to produce target if the number of source elements 
<br />
/// preceeding the current is less than the window size.<br />
/// &lt;/param&gt;<br />
/// &lt;param name="lookahead"&gt;<br />
/// Indicate whether to produce target if the number of source elements 
<br />
/// following current is less than the window size.<br />
/// &lt;/param&gt;<br />
/// &lt;returns&gt;Returns a sequence of windows.&lt;/returns&gt;<br />
public static IEnumerable&lt;T[]&gt; Window&lt;T&gt;(<br />
this IEnumerable&lt;T&gt; source,<br />
int window,<br />
bool lookbehind,<br />
bool lookahead)<br />
{<br />
return source.Window(<br />
window,<br />
lookbehind,<br />
lookahead,<br />
(buffer, index, count) =&gt;<br />
{<br />
var result = new T[count];<br /><br />
for(var i = 0; i &lt; count; ++i)<br />
{<br />
result[i] = buffer[index];<br />
index = index + 1 == buffer.Length ? 0 : index + 1;<br />
}<br /><br />
return result;<br />
});<br />
}</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9d90a7c4-6361-41fd-bd71-dab52eedcad0" />
      </body>
      <title>LINQ extensions</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9d90a7c4-6361-41fd-bd71-dab52eedcad0.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/03/07/LINQExtensions.aspx</link>
      <pubDate>Fri, 07 Mar 2014 14:11:46 GMT</pubDate>
      <description>    &lt;p&gt;
From time to time we run into tasks that we would like to solve in LINQ style but
unfortunately it either cannot be done or a solution is not efficient.
&lt;/p&gt;
&lt;p&gt;
Note that by LINQ style we do not mean C# query expressions (we have a strong distaste
for that syntax) but extension methods defined in &lt;code&gt;System.Linq.Enumerable&lt;/code&gt; and
other classes.
&lt;/p&gt;
&lt;p&gt;
Here we quote several extension methods that are good for a general use:
&lt;/p&gt;
&lt;p&gt;
1. Select with predicate. This is shorthand of &lt;code&gt;items.Where(...).Select(...)&lt;/code&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Projects each element of a sequence into a new form.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="T"&gt;A type of elements of source sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="R"&gt;A type of elements of target sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;param name="source"&gt;A source sequence.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="where"&gt;A predicate to filter elements.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="selector"&gt;A result element selector.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;A target sequence.&amp;lt;/returns&gt;&lt;br /&gt;
public static IEnumerable&amp;lt;R&gt; Select&amp;lt;T, R&gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&gt; source, 
&lt;br /&gt;
Func&amp;lt;T, bool&gt; where, 
&lt;br /&gt;
Func&amp;lt;T, R&gt; selector)&lt;br /&gt;
{&lt;br /&gt;
return source.Where(where).Select(selector);&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
2. Select with predicate with source element index passed both into the predicate
and into the selector. This one you cannot trivially implement in LINQ:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Projects each element of a sequence into a new form.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="T"&gt;A type of elements of source sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="R"&gt;A type of elements of target sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;param name="source"&gt;A source sequence.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="where"&gt;A predicate to filter elements.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="selector"&gt;A result element selector.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;A target sequence.&amp;lt;/returns&gt;&lt;br /&gt;
public static IEnumerable&amp;lt;R&gt; Select&amp;lt;T, R&gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&gt; source,&lt;br /&gt;
Func&amp;lt;T, int, bool&gt; where,&lt;br /&gt;
Func&amp;lt;T, int, R&gt; selector)&lt;br /&gt;
{&lt;br /&gt;
var index = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var value in source)&lt;br /&gt;
{&lt;br /&gt;
if (where(value, index))&lt;br /&gt;
{&lt;br /&gt;
yield return selector(value, index);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
++index;&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
3. A function with output element as projection of a window of input elements. Such
function can be used to get finite difference (operation opposite to a cumulative
sum).
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Projects a window of source elements in a source sequence into target sequence.&lt;br /&gt;
/// Thus&lt;br /&gt;
/// target[i] = 
&lt;br /&gt;
/// selector(source[i], source[i - 1], ... source[i - window + 1])&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="T"&gt;A type of elements of source sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="R"&gt;A type of elements of target sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;param name="source"&gt;A source sequence.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="window"&gt;A size of window.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="lookbehind"&gt;&lt;br /&gt;
/// Indicate whether to produce target if the number of source elements 
&lt;br /&gt;
/// preceeding the current is less than the window size.&lt;br /&gt;
/// &amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="lookahead"&gt;&lt;br /&gt;
/// Indicate whether to produce target if the number of source elements 
&lt;br /&gt;
/// following current is less than the window size.&lt;br /&gt;
/// &amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="selector"&gt;&lt;br /&gt;
/// A selector that derives target element.&lt;br /&gt;
/// On input it receives:&lt;br /&gt;
/// an array of source elements stored in round-robing fashon;&lt;br /&gt;
/// an index of the first element;&lt;br /&gt;
/// a number of elements in the array to count.&lt;br /&gt;
/// &amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;Returns a sequence of target elements.&amp;lt;/returns&gt;&lt;br /&gt;
public static IEnumerable&amp;lt;R&gt; Window&amp;lt;T, R&gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&gt; source,&lt;br /&gt;
int window,&lt;br /&gt;
bool lookbehind,&lt;br /&gt;
bool lookahead,&lt;br /&gt;
Func&amp;lt;T[], int, int, R&gt; selector)&lt;br /&gt;
{&lt;br /&gt;
var buffer = new T[window];&lt;br /&gt;
var index = 0;&lt;br /&gt;
var count = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var value in source)&lt;br /&gt;
{&lt;br /&gt;
if (count &amp;lt; window)&lt;br /&gt;
{&lt;br /&gt;
buffer[count++] = value;&lt;br /&gt;
&lt;br /&gt;
if (lookbehind || (count == window))&lt;br /&gt;
{&lt;br /&gt;
yield return selector(buffer, 0, count);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
buffer[index] = value;&lt;br /&gt;
index = index + 1 == window ? 0 : index + 1;&lt;br /&gt;
&lt;br /&gt;
yield return selector(buffer, index, count);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (lookahead)&lt;br /&gt;
{&lt;br /&gt;
while(--count &gt; 0)&lt;br /&gt;
{&lt;br /&gt;
index = index + 1 == window ? 0 : index + 1;&lt;br /&gt;
&lt;br /&gt;
yield return selector(buffer, index, count);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This way a finite difference looks like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var diff = input.Window(&lt;br /&gt;
2,&lt;br /&gt;
false,&lt;br /&gt;
false,&lt;br /&gt;
(buffer, index, count) =&gt; buffer[index ^ 1] - buffer[index]); &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
4. A specialization of &lt;code&gt;Window&lt;/code&gt; method that returns a enumeration of windows:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Projects a window of source elements in a source sequence into a&lt;br /&gt;
/// sequence of window arrays.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="T"&gt;A type of elements of source sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;typeparam name="R"&gt;A type of elements of target sequence.&amp;lt;/typeparam&gt;&lt;br /&gt;
/// &amp;lt;param name="source"&gt;A source sequence.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="window"&gt;A size of window.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="lookbehind"&gt;&lt;br /&gt;
/// Indicate whether to produce target if the number of source elements 
&lt;br /&gt;
/// preceeding the current is less than the window size.&lt;br /&gt;
/// &amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;param name="lookahead"&gt;&lt;br /&gt;
/// Indicate whether to produce target if the number of source elements 
&lt;br /&gt;
/// following current is less than the window size.&lt;br /&gt;
/// &amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;Returns a sequence of windows.&amp;lt;/returns&gt;&lt;br /&gt;
public static IEnumerable&amp;lt;T[]&gt; Window&amp;lt;T&gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&gt; source,&lt;br /&gt;
int window,&lt;br /&gt;
bool lookbehind,&lt;br /&gt;
bool lookahead)&lt;br /&gt;
{&lt;br /&gt;
return source.Window(&lt;br /&gt;
window,&lt;br /&gt;
lookbehind,&lt;br /&gt;
lookahead,&lt;br /&gt;
(buffer, index, count) =&gt;&lt;br /&gt;
{&lt;br /&gt;
var result = new T[count];&lt;br /&gt;
&lt;br /&gt;
for(var i = 0; i &amp;lt; count; ++i)&lt;br /&gt;
{&lt;br /&gt;
result[i] = buffer[index];&lt;br /&gt;
index = index + 1 == buffer.Length ? 0 : index + 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
});&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9d90a7c4-6361-41fd-bd71-dab52eedcad0" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9d90a7c4-6361-41fd-bd71-dab52eedcad0.aspx</comments>
      <category>.NET</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8cac7e9a-f811-488b-844b-85d983ba534b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8cac7e9a-f811-488b-844b-85d983ba534b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
These are initial positions for this writing: 
</p>
        <ul>
          <li>
SQL Server allows to execute dynamic SQL.</li>
          <li>
Dynamic SQL is useful and often unavoidable, e.g. when you have to filter or order
data in a way that you cannot code efficiently in advance.</li>
          <li>
Dynamic SQL has proven to be a dangerous area, as with improper use it can open hole
in a security.</li>
        </ul>
        <p>
In general nothing stops you from building and then excuting of SQL string. Our goal,
however, is to define rules that make work with dynamic SQL is more managable and
verifiable. 
</p>
        <p>
Here we outline these rules, and then give some examples and tips. 
</p>
        <p>
          <strong>Rule #1. Isolate dynamic SQL</strong>
        </p>
        <p>
Put all logic related to building of dynamic SQL into a separate function.<br />
We usually define a separate scheme <code>Dynamic</code>, and define functions like <code>Dynamic.GetSQL_XXX(params)</code>.<br />
This makes it simple to perform code review. 
</p>
        <p>
          <strong>Rule #2. Xml as parameters</strong>
        </p>
        <p>
Use <code>xml</code> type to pass parameters to a function that builds dynamic SQL.<br />
In many cases dynamic SQL depends on variable number of parameters (like a list of
values to check against). 
<br />
Xml fits here to represent structured information.<br />
On a client (e.g. in C# or java) you can define a class with all parameters, populate
an instance and serialize it to an xml. 
</p>
        <p>
          <strong>Rule #3. XQuery as template language</strong>
        </p>
        <p>
Use XQuery to define SQL template and to generate SQL tree from the input parameters.<br />
Here is an example of such XQuery:
</p>
        <p style="padding-left: 1em">
          <code>@data.query('<br />
&lt;sql&gt;<br />
select<br />
T.*<br />
from<br />
Data.Ticket T<br />
where<br />
{<br />
for $ticketID in data/ticketID return<br />
&lt;sql&gt;(T.TicketID = &lt;int&gt;{$ticketID}&lt;/int&gt;) and &lt;/sql&gt;<br />
}<br />
(1 = 1)<br />
&lt;/sql&gt;')</code>
        </p>
        <p>
You can see that output is an xml with <code>sql</code> element to represent literal
SQL, and <code>int</code> element to represent integer literal. 
</p>
        <p>
In fact whole output schema can be defined like this:
</p>
        <p>
          <code>&lt;xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br />
&lt;xs:element name="sql"/&gt;<br />
&lt;xs:element name="name"/&gt;<br />
&lt;xs:element name="string" nillable="true"/&gt;<br />
&lt;xs:element name="int" nillable="true"/&gt;<br />
&lt;xs:element name="decimal" nillable="true"/&gt;<br />
&lt;xs:element name="date" nillable="true"/&gt;<br />
&lt;xs:element name="time" nillable="true"/&gt;<br />
&lt;xs:element name="datetime" nillable="true"/&gt;<br />
&lt;/xs:schema&gt; </code>
        </p>
        <p>
where <code>sql</code> is to represent literal content, <code>name</code> to represent
a name, and other elements to represent different literal values.
</p>
        <p>
          <strong>Rule #4. Escape literals</strong>
        </p>
        <p>
Use function <code>Dynamic.ToSQL(@template)</code> to build final SQL text.<br />
Here we quote the definition:
</p>
        <p style="padding-left: 1em">
          <code>-- Builds a text of SQL function for an sql template.<br />
create function Dynamic.ToSQL 
<br />
( 
<br />
-- SQL template. 
<br />
@template xml 
<br />
) 
<br />
returns nvarchar(max) 
<br />
with returns null on null input 
<br />
as 
<br />
begin 
<br />
return 
<br />
( 
<br />
select<br />
case 
<br />
when N.Node.exist('*[xs:boolean(@xsi:nil)]') = 1 then 
<br />
'null' 
<br /><br />
when N.Node.exist('self::int') = 1 then 
<br />
isnull(N.Node.value('xs:int(.)', 'nvarchar(max)'), '# int #') 
<br /><br />
when N.Node.exist('self::string') = 1 then 
<br />
'N''' + 
<br />
replace 
<br />
( 
<br />
N.Node.value('.', 'nvarchar(max)'),<br />
'''', 
<br />
'''''' 
<br />
) + 
<br />
'''' 
<br /><br />
when N.Node.exist('self::name') = 1 then 
<br />
isnull 
<br />
( 
<br />
quotename(N.Node.value('.', 'nvarchar(128)'), '['), 
<br />
'# name #' 
<br />
) 
<br /><br />
when N.Node.exist('self::datetime') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(datetime2, ''' + 
<br />
N.Node.value('xs:dateTime(.)', 'nvarchar(128)') + 
<br />
''', 126)', 
<br />
'# datetime #' 
<br />
) 
<br /><br />
when N.Node.exist('self::date') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(date, ''' + 
<br />
N.Node.value('xs:date(.)', 'nvarchar(128)') + 
<br />
''', 126)', 
<br />
'# date #' 
<br />
) 
<br /><br />
when N.Node.exist('self::time') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(time, ''' + 
<br />
N.Node.value('xs:time(.)', 'nvarchar(128)') + 
<br />
''', 114)', 
<br />
'# time #' 
<br />
) 
<br /><br />
when N.Node.exist('self::decimal') = 1 then 
<br />
isnull 
<br />
( 
<br />
N.Node.value('xs:decimal(.)', 'nvarchar(128)'), 
<br />
'# decimal #' 
<br />
) 
<br /><br />
when N.Node.exist('self::*') = 1 then 
<br />
'# invalid template #' 
<br /><br />
else 
<br />
N.Node.value('.', 'nvarchar(max)') 
<br />
end 
<br />
from 
<br />
@template.nodes('//sql/node()[not(self::sql)]') N(Node) 
<br />
for xml path(''), type<br />
).value('.', 'nvarchar(max)'); 
<br />
end; </code>
        </p>
        <p>
Now, we want to stress that this function plays an important role in prevention of
the SQL injection, as it escapes literals from the SQL tree.
</p>
        <p>
          <strong>Rule #5 (optional). Collect data</strong>
        </p>
        <p>
Use SQL to collect additional data required to build dynamic SQL. Here is an example
of how we get a <code>Ticket</code> by <code>StatusID</code>, while on input we receive
a <code>StatusName</code>:
</p>
        <p style="padding-left: 1em">
          <code>create function Dynamic.GetSQL_GetTicketByStatus(@data xml)<br />
returns nvarchar(max)<br />
as<br />
begin<br /><span style="color: red"> set @data = 
<br />
(<br />
select 
<br />
@data, 
<br />
(<br />
select<br />
T.StatusID<br />
from<br />
@data.nodes('/data/status') N(Node)<br />
inner join<br />
Metadata.Status T<br />
on<br />
T.StatusName = Node.value('.', 'nvarchar(128)')<br />
for xml auto, type, elements<br />
) 
<br />
for xml path('')<br />
);<br /></span><br />
return Dynamic.ToSQL<br />
(<br />
@data.query<br />
('<br />
&lt;sql&gt;<br />
select<br />
T.*<br />
from<br />
Data.Ticket T<br />
where<br />
T.Status in ({ for $status in /T/StatusID return &lt;sql&gt;&lt;int&gt;{$status}&lt;/int&gt;,&lt;/sql&gt;
} null)<br />
&lt;/sql&gt;<br />
')<br />
);<br />
end; </code>
        </p>
        <p>
Notice code in red that collects some more data before calling XQuery.
</p>
        <p>
          <strong>Rule #6. Execute</strong>
        </p>
        <p>
The final step is to call dynamic SQL.<br />
This is done like this:
</p>
        <p style="padding-left: 1em">
          <code>-- build<br />
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTicket(@data);<br /><br />
-- execute<br />
execute sp_executesql 
<br />
@sql<br />
-- {, N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' } 
<br />
-- { , [ @param1 = ] 'value1' [ ,...n ] }<br />
with result sets<br />
( 
<br />
(<br />
TicketID int not null,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(256) null,<br />
Status int,<br />
Severity int,<br />
DeadLineAt datetime2 null<br />
)<br />
);</code>
        </p>
        <p>
Notice that the use of dynamic SQL does not prevent static parameters.<br />
Notice also that <code>with result sets</code> clause is used to specify output.
</p>
        <p>
          <strong>Example. Tickets system</strong>
        </p>
        <p>
Let's assume you're dealing with a tickets system (like Bugzilla), and you
have a table <code>Data.Ticket</code> to describe tickets. Assume that DDL for this
table is like this:
</p>
        <p style="padding-left: 1em">
          <code>create table Data.Ticket<br />
(<br />
TicketID bigint not null primary key,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(128) null,<br />
Status int not null,<br />
UpdatedAt datetime2(7) not null<br />
) </code>
        </p>
        <p>
Suppose you have to build C# code to search different tickets, where Entity Framework
is used to access the database.<br />
Search should be done by a range of <code>CreatedAt</code>, a range of <code>UpdatedAt</code>, <code>Summary</code>,
or by different <code>Status</code> values. It should be possible to order results
in different ways.
</p>
        <p>
We start out solution from the C# and define classes for a request:
</p>
        <p style="padding-left: 1em">
          <code> public enum Direction<br />
{<br />
Asc,<br />
Desc<br />
}<br /><br />
public struct Order 
<br />
{<br />
public string Field { get; set; }<br />
public Direction Direction {get; set; }<br />
}<br /><br />
public class DateRange<br />
{<br />
public DateTime? From { get; set; }<br /><br />
// This property is to omit From element if value is null.<br />
// See rules for xml serialization.<br />
public bool FromSpecified { get { return From != null; } }<br /><br />
public DateTime? To { get; set; }<br />
public bool ToSpecified { get { return To != null; } }<br />
}<br /><br />
public class TicketsRequest<br />
{<br />
public DateRange CreatedAt { get; set; }<br />
public string Summary { get; set; }<br />
public DateRange UpdatedAt { get; set; }<br />
[XmlElement]<br />
public Order[] Order { get; set; }<br />
[XmlElement]<br />
public int[] Status { get; set; }<br />
} </code>
        </p>
        <p>
Notice that we're going to use <code>XmlSerializer</code> to convert request to
xml and then to pass parameter into EF's model. Here is utility method to perform
such conversion:
</p>
        <p style="padding-left: 1em">
          <code> public static string ToXmlString&lt;T&gt;(T value)<br />
{<br />
if (value == null)<br />
{<br />
return null;<br />
}<br /><br />
var serializer = new XmlSerializer(typeof(T));<br />
var builder = new StringBuilder();<br /><br />
var writer = XmlWriter.Create(<br />
builder,<br />
new XmlWriterSettings<br />
{<br />
OmitXmlDeclaration = true,<br />
Indent = false<br />
});<br /><br />
serializer.Serialize(writer, value);<br />
writer.Flush();<br /><br />
return builder.ToString();<br />
} </code>
        </p>
        <p>
Now we proceed to the database and define a procedure that runs the search:
</p>
        <p style="padding-left: 1em">
          <code>-- Gets tickets.<br />
create procedure Data.GetTickets<br />
(<br />
-- A query parameters.<br />
@params xml<br />
)<br />
as<br />
begin<br />
set nocount on;<br /><br />
-- This is for EF to guess type of result.<br />
if (1 = 0)<br />
begin<br />
select<br />
TicketID,<br />
CreatedAt,<br />
Summary,<br />
Status,<br />
UpdatedAt<br />
from<br />
Data.Ticket;<br />
end;<br /><br />
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTickets(@params);<br /><br />
execute sp_executesql @sql<br />
with result sets<br />
( 
<br />
(<br />
TicketID int not null,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(256) null,<br />
Status int,<br />
UpdatedAt datetime2 null<br />
)<br />
);<br />
end; </code>
        </p>
        <p>
Switch back to C#, import the <code>Data.GetTickets</code> into the EF model, and
create a search method:
</p>
        <p style="padding-left: 1em">
          <code> public IEnumerable&lt;Ticket&gt; GetTickets(TicketsRequest request)<br />
{ 
<br />
var model = new Model();<br /><br />
return model.GetTickets(ToXmlString(request));<br />
} </code>
        </p>
        <p>
The last ingredient is <code>Dynamic.GetSQL_GetTickets()</code> function.
</p>
        <p style="padding-left: 1em">
          <code>create function Dynamic.GetSQL_GetTickets(@data xml)<br />
returns nvarchar(max)<br />
as<br />
begin<br />
return Dynamic.ToSQL<br />
(<br />
@data.query('<br />
&lt;sql&gt;<br />
select<br />
T.TicketID,<br />
T.CreatedAt,<br />
T.Summary,<br />
T.Status,<br />
T.UpdatedAt<br />
from<br />
Data.Ticket T<br />
where<br />
{<br />
for $range in */CreatedAt return<br />
(<br />
for $date in $range/From return<br />
&lt;sql&gt;<br />
(T.CreatedAt &gt;= &lt;datetime&gt;{$date}&lt;/datetime&gt;) and<br />
&lt;/sql&gt;,<br /><br />
for $date in $range/To return<br />
&lt;sql&gt;<br />
(&lt;datetime&gt;{$date}&lt;/datetime&gt; &gt; T.CreatedAt) and<br />
&lt;/sql&gt;<br />
),<br /><br />
for $range in */UpdatedAt return<br />
(<br />
for $date in $range/From return<br />
&lt;sql&gt;<br />
(T.UpdatedAt &gt;= &lt;datetime&gt;{$date}&lt;/datetime&gt;) and<br />
&lt;/sql&gt;,<br /><br />
for $date in $range/To return<br />
&lt;sql&gt;<br />
(&lt;datetime&gt;{$date}&lt;/datetime&gt; &gt; T.UpdatedAt) and<br />
&lt;/sql&gt;<br />
),<br /><br />
for $summary in */Summary return<br />
&lt;sql&gt;<br />
(T.Summary like &lt;string&gt;{$summary}&lt;/string&gt;) and<br />
&lt;/sql&gt;,<br /><br />
if (*/Status) then<br />
&lt;sql&gt;<br />
T.Status in 
<br />
({<br />
for $status in */Status return<br />
&lt;sql&gt;&lt;int&gt;{$status}&lt;/int&gt;, &lt;/sql&gt;<br />
} null) and<br />
&lt;/sql&gt;<br />
else ()<br />
}<br />
(1 = 1)<br />
order by<br />
{<br />
for $order in 
<br />
*/Order 
<br />
[<br />
Field = ("TicketID", "CreatedAt", "Summary", "UpdatedAt", "Status")<br />
]<br />
return<br />
&lt;sql&gt;<br />
&lt;name&gt;{$order/Field}&lt;/name&gt;<br />
{" desc"[$order[Direction = "Desc"]]},<br />
&lt;/sql&gt;<br />
}<br />
(select null)<br />
&lt;/sql&gt;<br />
') 
<br />
);<br />
end;</code>
        </p>
        <p>
          <strong>SQL text from Dynamic.GetSQL_GetTickets()</strong>
        </p>
        <p>
Consider now SQL text produced by this function. For an input:
</p>
        <p style="padding-left: 1em">
          <code>&lt;TicketsRequest&gt;<br />
&lt;CreatedAt&gt;<br />
&lt;From&gt;2014-01-01T00:00:00&lt;/From&gt;<br />
&lt;/CreatedAt&gt;<br />
&lt;Summary&gt;hello%&lt;/Summary&gt;<br />
&lt;Order&gt;<br />
&lt;Field&gt;Status&lt;/Field&gt;<br />
&lt;Direction&gt;Desc&lt;/Direction&gt;<br />
&lt;/Order&gt;<br />
&lt;Status&gt;1&lt;/Status&gt;<br />
&lt;Status&gt;3&lt;/Status&gt;<br />
&lt;/TicketsRequest&gt;</code>
        </p>
        <p>
the output is:
</p>
        <p style="padding-left: 1em">
          <code> select<br />
T.TicketID,<br />
T.CreatedAt,<br />
T.Summary,<br />
T.Status,<br />
T.UpdatedAt<br />
from<br />
Data.Ticket T<br />
where<br /><br />
(T.CreatedAt &gt;= convert(datetime2, '2014-01-01T00:00:00', 126)) and<br /><br />
(T.Summary like N'hello%') and<br /><br />
T.Status in 
<br />
(1, 3, null) and<br /><br />
(1 = 1)<br />
order by<br />
[Status] desc,<br /><br />
(select null)<br /></code>
        </p>
        <p>
Though the text is not formatted as we would like, it's perfectly valid SQL.
</p>
        <p>
          <strong>Tips for building XQuery templates</strong>
        </p>
        <p>
What is called XQuery in SQL Server is in fact a very limited subset of XQuery 1.0.
Microsoft clearly states this fact. What is trivial in XQuery is often impossible
or ugly in XQuery of SQL Server. 
</p>
        <p>
Nevertheless XQuery in SQL Server works rather well as SQL template language. To make
it most efficient, however, you should learn several tips. 
</p>
        <p>
          <strong>Tip #1. Where clause</strong>
        </p>
        <p>
In template you might want to build a <code>where</code> clause: 
</p>
        <p style="padding-left: 1em">
          <code>&lt;sql&gt;<br />
select 
<br />
... 
<br />
where 
<br />
{<br />
if (...) then<br />
&lt;sql&gt;...&lt;/sql&gt;<br />
else ()<br />
}<br />
&lt;/sql&gt;</code>
        </p>
        <p>
and it might happen that for a certain input a condition under <code>where</code> might
collapse, and you will be left with <code>where</code> keyword without a real condition,
which is wrong. A simple work around is to always add some true condition under ther <code>where</code> like
this:
</p>
        <p style="padding-left: 1em">
          <code>&lt;sql&gt;<br />
select 
<br />
... 
<br />
where 
<br />
{<br />
if (...) then<br />
&lt;sql&gt;... <span style="color: red">and</span> &lt;/sql&gt;<br />
else ()<br />
} <span style="color: red">(1 = 1)</span><br />
&lt;/sql&gt;</code>
        </p>
        <p>
          <strong>Tip #2. "in" expression</strong>
        </p>
        <p>
If you want to generate "in" expression like this:
</p>
        <p style="padding-left: 1em">
          <code>value in (item1, item2,...)</code>
        </p>
        <p>
then you might find that it's much easier generate equivalent a code like this: 
</p>
        <p style="padding-left: 1em">
          <code>value in (item1, item2,..., null)</code>.
</p>
        <p>
Here is a XQuery to generate such template:
</p>
        <p style="padding-left: 1em">
          <code>value in 
<br />
({<br />
for $item in ... return<br />
&lt;sql&gt;&lt;int&gt;{$item}&lt;/int&gt;, &lt;/sql&gt;<br />
} null) and</code>
        </p>
        <p>
          <strong>Tip #3. Order by</strong>
        </p>
        <p>
You can conclude an <code>order by</code> clause built from a data with a dummy expression
like this:
</p>
        <p style="padding-left: 1em">
          <code>order by<br />
{<br />
for $item in ... return<br />
&lt;sql&gt;<br />
&lt;name&gt;{$item/Field}&lt;/name&gt;<br />
{" desc"[$item/Direction = "Desc"]},<br />
&lt;/sql&gt;<br />
} <span style="color: red">(select null)</span></code>
        </p>
        <p>
Alternatively you can use first column from a clustered index.
</p>
        <p>
          <strong>Tip #4. Group by</strong>
        </p>
        <p>
In a <code>group by</code> clause we cannot introduce terminator expression as it
was with <code>order by</code>, so a code is a less trivial:
</p>
        <p style="padding-left: 1em">
          <code>{<br />
let $items := ... return<br /><br />
if ($items) then<br />
&lt;sql&gt;<br />
group by &lt;name&gt;{$items[1]}&lt;/name&gt;<br />
{<br />
for $item in $items[position() &gt; 1] return<br />
&lt;sql&gt;, &lt;name&gt;{$item}&lt;/name&gt;&lt;/sql&gt;<br />
      }<br />
&lt;/sql&gt;<br />
else ()<br />
}</code>
        </p>
        <p>
In fact similar logic may work with <code>order by</code>.
</p>
        <p>
          <strong>Tip #5. Escape literals</strong>
        </p>
        <p>
It's crusial not to introduce SQL injection while building SQL. Thus use:
</p>
        <p style="padding-left: 1em">
          <code>&lt;int&gt;{...}&lt;/int&gt;</code> - for literal int;<br /><code>&lt;decimal&gt;{...}&lt;/decimal&gt;</code> - for literal decimal;<br /><code>&lt;string&gt;{...}&lt;/string&gt;</code> - for literal string;<br /><code>&lt;datetime&gt;{...}&lt;/datetime&gt;</code> - for literal datetime2;<br /><code>&lt;date&gt;{...}&lt;/date&gt;</code> - for literal date;<br /><code>&lt;time&gt;{...}&lt;/time&gt;</code> - for literal time;<br /><code>&lt;name&gt;{...}&lt;/name&gt;</code> - for a name to quote.
</p>
        <p>
Note that you can use <code>xsi:nil</code>, so <code>&lt;int xsi:nil="true"/&gt;</code> means <code>null</code>.
</p>
        <p>
If you generate a field name from an input data then it worth to validate it against
a list of available names.
</p>
        <p>
          <strong>Tip #6. Validate input.</strong>
        </p>
        <p>
It worth to define xml schema for an input xml, and to validate parameters against
it.<br />
This makes code more secure, and also adds a documentation.
</p>
        <p>
          <strong>Tip #7. Don't abuse dynamic SQL</strong>
        </p>
        <p>
There are not too many cases when you need a dynamic SQL. Usually SQL engine knows
how to build a good execution plan. If your query contains optional conditions then
you can write it a way that SQL Server can optimize, e.g.:
</p>
        <p style="padding-left: 1em">
          <code> select<br />
*<br />
from<br />
T<br />
where<br />
((@name is null) or (Name = @name)) and<br />
((@date is null) or (Date = @date))<br />
option(recompile)</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8cac7e9a-f811-488b-844b-85d983ba534b" />
      </body>
      <title>Dealing with dynamic SQL in SQL Server</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/02/11/DealingWithDynamicSQLInSQLServer.aspx</link>
      <pubDate>Tue, 11 Feb 2014 09:48:07 GMT</pubDate>
      <description>  &lt;p&gt;
These are initial positions for this writing: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
SQL Server allows to execute dynamic SQL.&lt;/li&gt;
&lt;li&gt;
Dynamic SQL is useful and often unavoidable, e.g. when you have to filter or order
data in a way that you cannot code efficiently in advance.&lt;/li&gt;
&lt;li&gt;
Dynamic SQL has proven to be a dangerous area, as with improper use it can open hole
in a security.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In general nothing stops you from building and then excuting of SQL string. Our goal,
however, is to define rules that make work with dynamic SQL is more managable and
verifiable. 
&lt;/p&gt;
&lt;p&gt;
Here we outline these rules, and then give some examples and tips. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #1. Isolate dynamic SQL&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Put all logic related to building of dynamic SQL into a separate function.&lt;br /&gt;
We usually define a separate scheme &lt;code&gt;Dynamic&lt;/code&gt;, and define functions like &lt;code&gt;Dynamic.GetSQL_XXX(params)&lt;/code&gt;.&lt;br /&gt;
This makes it simple to perform code review. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #2. Xml as parameters&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use &lt;code&gt;xml&lt;/code&gt; type to pass parameters to a function that builds dynamic SQL.&lt;br /&gt;
In many cases dynamic SQL depends on variable number of parameters (like a list of
values to check against). 
&lt;br /&gt;
Xml fits here to represent structured information.&lt;br /&gt;
On a client (e.g. in C# or java) you can define a class with all parameters, populate
an instance and serialize it to an xml. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #3. XQuery as template language&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use XQuery to define SQL template and to generate SQL tree from the input parameters.&lt;br /&gt;
Here is an example of such XQuery:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;@data.query('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.*&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
{&lt;br /&gt;
for $ticketID in data/ticketID return&lt;br /&gt;
&amp;lt;sql&amp;gt;(T.TicketID = &amp;lt;int&amp;gt;{$ticketID}&amp;lt;/int&amp;gt;) and &amp;lt;/sql&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
(1 = 1)&lt;br /&gt;
&amp;lt;/sql&amp;gt;')&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
You can see that output is an xml with &lt;code&gt;sql&lt;/code&gt; element to represent literal
SQL, and &lt;code&gt;int&lt;/code&gt; element to represent integer literal. 
&lt;/p&gt;
&lt;p&gt;
In fact whole output schema can be defined like this:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;lt;xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="sql"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="name"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="string" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="int" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="decimal" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="date" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="time" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="datetime" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;/xs:schema&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;sql&lt;/code&gt; is to represent literal content, &lt;code&gt;name&lt;/code&gt; to represent
a name, and other elements to represent different literal values.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #4. Escape literals&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use function &lt;code&gt;Dynamic.ToSQL(@template)&lt;/code&gt; to build final SQL text.&lt;br /&gt;
Here we quote the definition:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- Builds a text of SQL function for an sql template.&lt;br /&gt;
create function Dynamic.ToSQL 
&lt;br /&gt;
( 
&lt;br /&gt;
-- SQL template. 
&lt;br /&gt;
@template xml 
&lt;br /&gt;
) 
&lt;br /&gt;
returns nvarchar(max) 
&lt;br /&gt;
with returns null on null input 
&lt;br /&gt;
as 
&lt;br /&gt;
begin 
&lt;br /&gt;
return 
&lt;br /&gt;
( 
&lt;br /&gt;
select&lt;br /&gt;
case 
&lt;br /&gt;
when N.Node.exist('*[xs:boolean(@xsi:nil)]') = 1 then 
&lt;br /&gt;
'null' 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::int') = 1 then 
&lt;br /&gt;
isnull(N.Node.value('xs:int(.)', 'nvarchar(max)'), '# int #') 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::string') = 1 then 
&lt;br /&gt;
'N''' + 
&lt;br /&gt;
replace 
&lt;br /&gt;
( 
&lt;br /&gt;
N.Node.value('.', 'nvarchar(max)'),&lt;br /&gt;
'''', 
&lt;br /&gt;
'''''' 
&lt;br /&gt;
) + 
&lt;br /&gt;
'''' 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::name') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
quotename(N.Node.value('.', 'nvarchar(128)'), '['), 
&lt;br /&gt;
'# name #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::datetime') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(datetime2, ''' + 
&lt;br /&gt;
N.Node.value('xs:dateTime(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 126)', 
&lt;br /&gt;
'# datetime #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::date') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(date, ''' + 
&lt;br /&gt;
N.Node.value('xs:date(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 126)', 
&lt;br /&gt;
'# date #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::time') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(time, ''' + 
&lt;br /&gt;
N.Node.value('xs:time(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 114)', 
&lt;br /&gt;
'# time #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::decimal') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
N.Node.value('xs:decimal(.)', 'nvarchar(128)'), 
&lt;br /&gt;
'# decimal #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::*') = 1 then 
&lt;br /&gt;
'# invalid template #' 
&lt;br /&gt;
&lt;br /&gt;
else 
&lt;br /&gt;
N.Node.value('.', 'nvarchar(max)') 
&lt;br /&gt;
end 
&lt;br /&gt;
from 
&lt;br /&gt;
@template.nodes('//sql/node()[not(self::sql)]') N(Node) 
&lt;br /&gt;
for xml path(''), type&lt;br /&gt;
).value('.', 'nvarchar(max)'); 
&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Now, we want to stress that this function plays an important role in prevention of
the SQL injection, as it escapes literals from the SQL tree.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #5 (optional). Collect data&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use SQL to collect additional data required to build dynamic SQL. Here is an example
of how we get a &lt;code&gt;Ticket&lt;/code&gt; by &lt;code&gt;StatusID&lt;/code&gt;, while on input we receive
a &lt;code&gt;StatusName&lt;/code&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create function Dynamic.GetSQL_GetTicketByStatus(@data xml)&lt;br /&gt;
returns nvarchar(max)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
&lt;span style="color: red"&gt; set @data = 
&lt;br /&gt;
(&lt;br /&gt;
select 
&lt;br /&gt;
@data, 
&lt;br /&gt;
(&lt;br /&gt;
select&lt;br /&gt;
T.StatusID&lt;br /&gt;
from&lt;br /&gt;
@data.nodes('/data/status') N(Node)&lt;br /&gt;
inner join&lt;br /&gt;
Metadata.Status T&lt;br /&gt;
on&lt;br /&gt;
T.StatusName = Node.value('.', 'nvarchar(128)')&lt;br /&gt;
for xml auto, type, elements&lt;br /&gt;
) 
&lt;br /&gt;
for xml path('')&lt;br /&gt;
);&lt;br /&gt;
&lt;/span&gt; 
&lt;br /&gt;
return Dynamic.ToSQL&lt;br /&gt;
(&lt;br /&gt;
@data.query&lt;br /&gt;
('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.*&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
T.Status in ({ for $status in /T/StatusID return &amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$status}&amp;lt;/int&amp;gt;,&amp;lt;/sql&amp;gt;
} null)&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
')&lt;br /&gt;
);&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice code in red that collects some more data before calling XQuery.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #6. Execute&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The final step is to call dynamic SQL.&lt;br /&gt;
This is done like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- build&lt;br /&gt;
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTicket(@data);&lt;br /&gt;
&lt;br /&gt;
-- execute&lt;br /&gt;
execute sp_executesql 
&lt;br /&gt;
@sql&lt;br /&gt;
-- {, N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' } 
&lt;br /&gt;
-- { , [ @param1 = ] 'value1' [ ,...n ] }&lt;br /&gt;
with result sets&lt;br /&gt;
( 
&lt;br /&gt;
(&lt;br /&gt;
TicketID int not null,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(256) null,&lt;br /&gt;
Status int,&lt;br /&gt;
Severity int,&lt;br /&gt;
DeadLineAt datetime2 null&lt;br /&gt;
)&lt;br /&gt;
);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice that the use of dynamic SQL does not prevent static parameters.&lt;br /&gt;
Notice also that &lt;code&gt;with result sets&lt;/code&gt; clause is used to specify output.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Example. Tickets system&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Let&amp;#39;s assume you&amp;#39;re dealing with a tickets system (like Bugzilla), and you
have a table &lt;code&gt;Data.Ticket&lt;/code&gt; to describe tickets. Assume that DDL for this
table is like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create table Data.Ticket&lt;br /&gt;
(&lt;br /&gt;
TicketID bigint not null primary key,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(128) null,&lt;br /&gt;
Status int not null,&lt;br /&gt;
UpdatedAt datetime2(7) not null&lt;br /&gt;
) &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Suppose you have to build C# code to search different tickets, where Entity Framework
is used to access the database.&lt;br /&gt;
Search should be done by a range of &lt;code&gt;CreatedAt&lt;/code&gt;, a range of &lt;code&gt;UpdatedAt&lt;/code&gt;, &lt;code&gt;Summary&lt;/code&gt;,
or by different &lt;code&gt;Status&lt;/code&gt; values. It should be possible to order results
in different ways.
&lt;/p&gt;
&lt;p&gt;
We start out solution from the C# and define classes for a request:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public enum Direction&lt;br /&gt;
{&lt;br /&gt;
Asc,&lt;br /&gt;
Desc&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public struct Order 
&lt;br /&gt;
{&lt;br /&gt;
public string Field { get; set; }&lt;br /&gt;
public Direction Direction {get; set; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class DateRange&lt;br /&gt;
{&lt;br /&gt;
public DateTime? From { get; set; }&lt;br /&gt;
&lt;br /&gt;
// This property is to omit From element if value is null.&lt;br /&gt;
// See rules for xml serialization.&lt;br /&gt;
public bool FromSpecified { get { return From != null; } }&lt;br /&gt;
&lt;br /&gt;
public DateTime? To { get; set; }&lt;br /&gt;
public bool ToSpecified { get { return To != null; } }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class TicketsRequest&lt;br /&gt;
{&lt;br /&gt;
public DateRange CreatedAt { get; set; }&lt;br /&gt;
public string Summary { get; set; }&lt;br /&gt;
public DateRange UpdatedAt { get; set; }&lt;br /&gt;
[XmlElement]&lt;br /&gt;
public Order[] Order { get; set; }&lt;br /&gt;
[XmlElement]&lt;br /&gt;
public int[] Status { get; set; }&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice that we&amp;#39;re going to use &lt;code&gt;XmlSerializer&lt;/code&gt; to convert request to
xml and then to pass parameter into EF&amp;#39;s model. Here is utility method to perform
such conversion:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public static string ToXmlString&amp;lt;T&amp;gt;(T value)&lt;br /&gt;
{&lt;br /&gt;
if (value == null)&lt;br /&gt;
{&lt;br /&gt;
return null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var serializer = new XmlSerializer(typeof(T));&lt;br /&gt;
var builder = new StringBuilder();&lt;br /&gt;
&lt;br /&gt;
var writer = XmlWriter.Create(&lt;br /&gt;
builder,&lt;br /&gt;
new XmlWriterSettings&lt;br /&gt;
{&lt;br /&gt;
OmitXmlDeclaration = true,&lt;br /&gt;
Indent = false&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
serializer.Serialize(writer, value);&lt;br /&gt;
writer.Flush();&lt;br /&gt;
&lt;br /&gt;
return builder.ToString();&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Now we proceed to the database and define a procedure that runs the search:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- Gets tickets.&lt;br /&gt;
create procedure Data.GetTickets&lt;br /&gt;
(&lt;br /&gt;
-- A query parameters.&lt;br /&gt;
@params xml&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
set nocount on;&lt;br /&gt;
&lt;br /&gt;
-- This is for EF to guess type of result.&lt;br /&gt;
if (1 = 0)&lt;br /&gt;
begin&lt;br /&gt;
select&lt;br /&gt;
TicketID,&lt;br /&gt;
CreatedAt,&lt;br /&gt;
Summary,&lt;br /&gt;
Status,&lt;br /&gt;
UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTickets(@params);&lt;br /&gt;
&lt;br /&gt;
execute sp_executesql @sql&lt;br /&gt;
with result sets&lt;br /&gt;
( 
&lt;br /&gt;
(&lt;br /&gt;
TicketID int not null,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(256) null,&lt;br /&gt;
Status int,&lt;br /&gt;
UpdatedAt datetime2 null&lt;br /&gt;
)&lt;br /&gt;
);&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Switch back to C#, import the &lt;code&gt;Data.GetTickets&lt;/code&gt; into the EF model, and
create a search method:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public IEnumerable&amp;lt;Ticket&amp;gt; GetTickets(TicketsRequest request)&lt;br /&gt;
{ 
&lt;br /&gt;
var model = new Model();&lt;br /&gt;
&lt;br /&gt;
return model.GetTickets(ToXmlString(request));&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The last ingredient is &lt;code&gt;Dynamic.GetSQL_GetTickets()&lt;/code&gt; function.
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create function Dynamic.GetSQL_GetTickets(@data xml)&lt;br /&gt;
returns nvarchar(max)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
return Dynamic.ToSQL&lt;br /&gt;
(&lt;br /&gt;
@data.query('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.TicketID,&lt;br /&gt;
T.CreatedAt,&lt;br /&gt;
T.Summary,&lt;br /&gt;
T.Status,&lt;br /&gt;
T.UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
{&lt;br /&gt;
for $range in */CreatedAt return&lt;br /&gt;
(&lt;br /&gt;
for $date in $range/From return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.CreatedAt &amp;gt;= &amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
for $date in $range/To return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(&amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt; &amp;gt; T.CreatedAt) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
),&lt;br /&gt;
&lt;br /&gt;
for $range in */UpdatedAt return&lt;br /&gt;
(&lt;br /&gt;
for $date in $range/From return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.UpdatedAt &amp;gt;= &amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
for $date in $range/To return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(&amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt; &amp;gt; T.UpdatedAt) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
),&lt;br /&gt;
&lt;br /&gt;
for $summary in */Summary return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.Summary like &amp;lt;string&amp;gt;{$summary}&amp;lt;/string&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
if (*/Status) then&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
T.Status in 
&lt;br /&gt;
({&lt;br /&gt;
for $status in */Status return&lt;br /&gt;
&amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$status}&amp;lt;/int&amp;gt;, &amp;lt;/sql&amp;gt;&lt;br /&gt;
} null) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;br /&gt;
(1 = 1)&lt;br /&gt;
order by&lt;br /&gt;
{&lt;br /&gt;
for $order in 
&lt;br /&gt;
*/Order 
&lt;br /&gt;
[&lt;br /&gt;
Field = ("TicketID", "CreatedAt", "Summary", "UpdatedAt", "Status")&lt;br /&gt;
]&lt;br /&gt;
return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;{$order/Field}&amp;lt;/name&amp;gt;&lt;br /&gt;
{" desc"[$order[Direction = "Desc"]]},&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
(select null)&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
') 
&lt;br /&gt;
);&lt;br /&gt;
end;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;SQL text from Dynamic.GetSQL_GetTickets()&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Consider now SQL text produced by this function. For an input:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;TicketsRequest&amp;gt;&lt;br /&gt;
&amp;lt;CreatedAt&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;2014-01-01T00:00:00&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;/CreatedAt&amp;gt;&lt;br /&gt;
&amp;lt;Summary&amp;gt;hello%&amp;lt;/Summary&amp;gt;&lt;br /&gt;
&amp;lt;Order&amp;gt;&lt;br /&gt;
&amp;lt;Field&amp;gt;Status&amp;lt;/Field&amp;gt;&lt;br /&gt;
&amp;lt;Direction&amp;gt;Desc&amp;lt;/Direction&amp;gt;&lt;br /&gt;
&amp;lt;/Order&amp;gt;&lt;br /&gt;
&amp;lt;Status&amp;gt;1&amp;lt;/Status&amp;gt;&lt;br /&gt;
&amp;lt;Status&amp;gt;3&amp;lt;/Status&amp;gt;&lt;br /&gt;
&amp;lt;/TicketsRequest&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
the output is:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select&lt;br /&gt;
T.TicketID,&lt;br /&gt;
T.CreatedAt,&lt;br /&gt;
T.Summary,&lt;br /&gt;
T.Status,&lt;br /&gt;
T.UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
(T.CreatedAt &amp;gt;= convert(datetime2, '2014-01-01T00:00:00', 126)) and&lt;br /&gt;
&lt;br /&gt;
(T.Summary like N'hello%') and&lt;br /&gt;
&lt;br /&gt;
T.Status in 
&lt;br /&gt;
(1, 3, null) and&lt;br /&gt;
&lt;br /&gt;
(1 = 1)&lt;br /&gt;
order by&lt;br /&gt;
[Status] desc,&lt;br /&gt;
&lt;br /&gt;
(select null)&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Though the text is not formatted as we would like, it&amp;#39;s perfectly valid SQL.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tips for building XQuery templates&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
What is called XQuery in SQL Server is in fact a very limited subset of XQuery 1.0.
Microsoft clearly states this fact. What is trivial in XQuery is often impossible
or ugly in XQuery of SQL Server. 
&lt;/p&gt;
&lt;p&gt;
Nevertheless XQuery in SQL Server works rather well as SQL template language. To make
it most efficient, however, you should learn several tips. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #1. Where clause&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In template you might want to build a &lt;code&gt;where&lt;/code&gt; clause: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;sql&amp;gt;&lt;br /&gt;
select 
&lt;br /&gt;
... 
&lt;br /&gt;
where 
&lt;br /&gt;
{&lt;br /&gt;
if (...) then&lt;br /&gt;
&amp;lt;sql&amp;gt;...&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
and it might happen that for a certain input a condition under &lt;code&gt;where&lt;/code&gt; might
collapse, and you will be left with &lt;code&gt;where&lt;/code&gt; keyword without a real condition,
which is wrong. A simple work around is to always add some true condition under ther &lt;code&gt;where&lt;/code&gt; like
this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;sql&amp;gt;&lt;br /&gt;
select 
&lt;br /&gt;
... 
&lt;br /&gt;
where 
&lt;br /&gt;
{&lt;br /&gt;
if (...) then&lt;br /&gt;
&amp;lt;sql&amp;gt;... &lt;span style="color: red"&gt;and&lt;/span&gt; &amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
} &lt;span style="color: red"&gt;(1 = 1)&lt;/span&gt;
&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #2. &amp;quot;in&amp;quot; expression&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
If you want to generate &amp;quot;in&amp;quot; expression like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in (item1, item2,...)&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
then you might find that it&amp;#39;s much easier generate equivalent a code like this: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in (item1, item2,..., null)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Here is a XQuery to generate such template:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in 
&lt;br /&gt;
({&lt;br /&gt;
for $item in ... return&lt;br /&gt;
&amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$item}&amp;lt;/int&amp;gt;, &amp;lt;/sql&amp;gt;&lt;br /&gt;
} null) and&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #3. Order by&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
You can conclude an &lt;code&gt;order by&lt;/code&gt; clause built from a data with a dummy expression
like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;order by&lt;br /&gt;
{&lt;br /&gt;
for $item in ... return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;{$item/Field}&amp;lt;/name&amp;gt;&lt;br /&gt;
{&amp;quot; desc&amp;quot;[$item/Direction = &amp;quot;Desc&amp;quot;]},&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
} &lt;span style="color: red"&gt;(select null)&lt;/span&gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Alternatively you can use first column from a clustered index.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #4. Group by&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In a &lt;code&gt;group by&lt;/code&gt; clause we cannot introduce terminator expression as it
was with &lt;code&gt;order by&lt;/code&gt;, so a code is a less trivial:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;{&lt;br /&gt;
let $items := ... return&lt;br /&gt;
&lt;br /&gt;
if ($items) then&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
group by &amp;lt;name&amp;gt;{$items[1]}&amp;lt;/name&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
for $item in $items[position() &amp;gt; 1] return&lt;br /&gt;
&amp;lt;sql&amp;gt;, &amp;lt;name&amp;gt;{$item}&amp;lt;/name&amp;gt;&amp;lt;/sql&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In fact similar logic may work with &lt;code&gt;order by&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #5. Escape literals&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s crusial not to introduce SQL injection while building SQL. Thus use:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;int&amp;gt;{...}&amp;lt;/int&amp;gt;&lt;/code&gt; - for literal int;&lt;br /&gt;
&lt;code&gt;&amp;lt;decimal&amp;gt;{...}&amp;lt;/decimal&amp;gt;&lt;/code&gt; - for literal decimal;&lt;br /&gt;
&lt;code&gt;&amp;lt;string&amp;gt;{...}&amp;lt;/string&amp;gt;&lt;/code&gt; - for literal string;&lt;br /&gt;
&lt;code&gt;&amp;lt;datetime&amp;gt;{...}&amp;lt;/datetime&amp;gt;&lt;/code&gt; - for literal datetime2;&lt;br /&gt;
&lt;code&gt;&amp;lt;date&amp;gt;{...}&amp;lt;/date&amp;gt;&lt;/code&gt; - for literal date;&lt;br /&gt;
&lt;code&gt;&amp;lt;time&amp;gt;{...}&amp;lt;/time&amp;gt;&lt;/code&gt; - for literal time;&lt;br /&gt;
&lt;code&gt;&amp;lt;name&amp;gt;{...}&amp;lt;/name&amp;gt;&lt;/code&gt; - for a name to quote.
&lt;/p&gt;
&lt;p&gt;
Note that you can use &lt;code&gt;xsi:nil&lt;/code&gt;, so &lt;code&gt;&amp;lt;int xsi:nil="true"/&gt;&lt;/code&gt; means &lt;code&gt;null&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
If you generate a field name from an input data then it worth to validate it against
a list of available names.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #6. Validate input.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
It worth to define xml schema for an input xml, and to validate parameters against
it.&lt;br /&gt;
This makes code more secure, and also adds a documentation.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #7. Don&amp;#39;t abuse dynamic SQL&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
There are not too many cases when you need a dynamic SQL. Usually SQL engine knows
how to build a good execution plan. If your query contains optional conditions then
you can write it a way that SQL Server can optimize, e.g.:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select&lt;br /&gt;
*&lt;br /&gt;
from&lt;br /&gt;
T&lt;br /&gt;
where&lt;br /&gt;
((@name is null) or (Name = @name)) and&lt;br /&gt;
((@date is null) or (Date = @date))&lt;br /&gt;
option(recompile)&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8cac7e9a-f811-488b-844b-85d983ba534b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ab2110fa-c136-4b6b-bfdc-aa0dce059a97</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ab2110fa-c136-4b6b-bfdc-aa0dce059a97</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Consider how would you implement Style object in the HTML DOM?
</p>
        <p>
These are some characteristics of that object:
</p>
        <ul>
          <li>
It has a long list of properties, e.g. in IE 11 there are more than 300 properties
over a style object.</li>
          <li>
Any specific instance usually have only several properties assigned.</li>
          <li>
Reads of properties are much more frequent than writes. In fact style often stays
unchanged after initialization.</li>
          <li>
DOM contains many style instances (often thousands).</li>
          <li>
The number of distinct instances in terms of values of properties is moderate (usually
dozens).</li>
        </ul>
        <p>
Here is how would we approached to such an object.
</p>
        <p>
1. Styles are sparse objects, thus there is no point to implement plain class with
all those properties, as it's wasteful.
</p>
        <p>
We would rather use two techniques to keep style's state:
</p>
        <ul>
          <li>
A dictionary of properties with their values;</li>
          <li>
An aggregation of objects, where all properies are grouped into families, each group
is defined by a separate type, and a style's state is an aggregation of that groups.</li>
        </ul>
        <p>
A current style of an element is an aggregation of styles of ancestor element. It
can either by dynamic or be fused into a single style instance.
</p>
        <p>
2. Make style's state immutable, and share all these states among all style instances.
</p>
        <p>
In this implementation property write turns into a state transition operation: <code>state
= set(state, property, value)</code>. Thus no state is modified but replaced with
other state that corresponds to a required change.
</p>
        <p>
If state is seen as a dictionary then API may look like this :
</p>
        <p style="padding-left: 1em">
          <code> public class State&lt;K, V&gt;<br />
{<br />
// Gets shared dictionary for an input dictionary.<br />
public IDictionary&lt;K, V&gt; Get(IDictionary&lt;K, V&gt; dictionary);<br /><br />
// Gets a shared dictionary for an input dictionary with key set to a value. 
<br />
public IDictionary&lt;K, V&gt; Set(IDictionary&lt;K, V&gt; dictionary, K key, V value);<br /><br />
// Gets a shared dictionary for an input dictionary.<br />
public IDictionary&lt;K, V&gt; Remove(IDictionary&lt;K, V&gt; dictionary, K key);<br /><br />
// Gets typed value.<br />
public T Get&lt;T&gt;(IDictionary&lt;K, V&gt; dictionary, K key)<br />
where T: V<br />
{<br />
V value;<br /><br />
if ((dictionary == null) || !dictionary.TryGetValue(key, out value))<br />
{<br />
return default(T);<br />
}<br /><br />
return (T)value;<br />
}<br /><br />
// Sets or removes a typed value.<br />
// dictionary can be null.<br />
// null returned if output dictionary would be empty. 
<br />
public IDictionary&lt;K, V&gt; Set&lt;T&gt;(IDictionary&lt;K, V&gt; dictionary, K key, T value)<br />
where T : V<br />
{<br />
return value == null ? Remove(dictionary, key) : 
<br />
Set(dictionary, key, (V)value);<br />
}<br />
}</code>
        </p>
        <p>
States can be cached. Provided the cache keeps states in a weak way, no unsued state
will be stored for a long time. We may use weak table of dictionary to dictionary <code>WeakTable&lt;Dictionary&lt;K,
V&gt;, Dictionary&lt;K, V&gt;&gt;</code> as a storage for such a cache. All required
API is described in the <a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx">WeakTable</a> and <a href="http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx">Hash
Code of Dictionary</a> posts.
</p>
        <p>
3. Style can be implemented as a structure with shared state as a storage. Here is
a scetch:
</p>
        <p style="padding-left: 1em">
          <code>[Serializable]<br />
public struct Style<br />
{<br />
// All properties.<br />
public enum Property<br />
{<br />
Background,<br />
BorderColor,<br />
BorderStyle,<br />
Color,<br />
FontFamily,<br />
FontSize,<br />
// ...<br />
}<br /><br />
public int? Background<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.Background); }<br />
set { state = states.Set(state, Property.Background, value); }<br />
}<br /><br />
public int? BorderColor<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.BorderColor); }<br />
set { state = states.Set(state, Property.BorderColor, value); }<br />
}<br /><br />
public string BorderStyle<br />
{<br />
get { return states.Get&lt;string&gt;(state, Property.BorderStyle); }<br />
set { state = states.Set(state, Property.BorderStyle, value); }<br />
}<br /><br />
public int? Color<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.Color); }<br />
set { state = states.Set(state, Property.Color, value); }<br />
}<br /><br />
public string FontFamily<br />
{<br />
get { return states.Get&lt;string&gt;(state, Property.FontFamily); }<br />
set { state = states.Set(state, Property.FontFamily, value); }<br />
}<br /><br />
public double? FontSize<br />
{<br />
get { return states.Get&lt;double?&gt;(state, Property.FontSize); }<br />
set { state = states.Set(state, Property.FontSize, value); }<br />
}<br /><br />
// ...<br /><br />
[OnDeserialized]<br />
private void OnDeserialized(StreamingContext context)<br />
{<br />
state = states.Get(state);<br />
}<br /><br />
// A state.<br />
private IDictionary&lt;Property, object&gt; state;<br /><br />
// A states cache.<br />
private static readonly State&lt;Property, object&gt; states =<br />
new State&lt;Property, object&gt;();<br />
} </code>
        </p>
        <p>
Note that:
</p>
        <ul>
          <li>
default state is a <code>null</code> dictionary;</li>
          <li>
states are application wide shared.</li>
        </ul>
        <p>
The following link is our implementation of <code><a href="http://www.nesterovsky-bros.com/download/State.cs.txt">State&lt;K,
V&gt;</a></code> class: <a href="http://www.nesterovsky-bros.com/download/State.cs.txt">State.cs</a>.
</p>
        <p>
        </p>
        <p>
Here we have outlined the idea of shared state object, and how it can be applied to
sparse mostly immutable objects. We used HTML style as an example of such an object.
Shared state object may work in many other areas, but for it to shine its use case
should fit to the task.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ab2110fa-c136-4b6b-bfdc-aa0dce059a97" />
      </body>
      <title>Shared state</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/22/SharedState.aspx</link>
      <pubDate>Wed, 22 Jan 2014 19:43:25 GMT</pubDate>
      <description>    &lt;p&gt;
Consider how would you implement Style object in the HTML DOM?
&lt;/p&gt;
&lt;p&gt;
These are some characteristics of that object:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
It has a long list of properties, e.g. in IE 11 there are more than 300 properties
over a style object.&lt;/li&gt;
&lt;li&gt;
Any specific instance usually have only several properties assigned.&lt;/li&gt;
&lt;li&gt;
Reads of properties are much more frequent than writes. In fact style often stays
unchanged after initialization.&lt;/li&gt;
&lt;li&gt;
DOM contains many style instances (often thousands).&lt;/li&gt;
&lt;li&gt;
The number of distinct instances in terms of values of properties is moderate (usually
dozens).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Here is how would we approached to such an object.
&lt;/p&gt;
&lt;p&gt;
1. Styles are sparse objects, thus there is no point to implement plain class with
all those properties, as it&amp;#39;s wasteful.
&lt;/p&gt;
&lt;p&gt;
We would rather use two techniques to keep style&amp;#39;s state:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A dictionary of properties with their values;&lt;/li&gt;
&lt;li&gt;
An aggregation of objects, where all properies are grouped into families, each group
is defined by a separate type, and a style&amp;#39;s state is an aggregation of that groups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A current style of an element is an aggregation of styles of ancestor element. It
can either by dynamic or be fused into a single style instance.
&lt;/p&gt;
&lt;p&gt;
2. Make style&amp;#39;s state immutable, and share all these states among all style instances.
&lt;/p&gt;
&lt;p&gt;
In this implementation property write turns into a state transition operation: &lt;code&gt;state
= set(state, property, value)&lt;/code&gt;. Thus no state is modified but replaced with
other state that corresponds to a required change.
&lt;/p&gt;
&lt;p&gt;
If state is seen as a dictionary then API may look like this :
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public class State&amp;lt;K, V&gt;&lt;br /&gt;
{&lt;br /&gt;
// Gets shared dictionary for an input dictionary.&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Get(IDictionary&amp;lt;K, V&gt; dictionary);&lt;br /&gt;
&lt;br /&gt;
// Gets a shared dictionary for an input dictionary with key set to a value. 
&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Set(IDictionary&amp;lt;K, V&gt; dictionary, K key, V value);&lt;br /&gt;
&lt;br /&gt;
// Gets a shared dictionary for an input dictionary.&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Remove(IDictionary&amp;lt;K, V&gt; dictionary, K key);&lt;br /&gt;
&lt;br /&gt;
// Gets typed value.&lt;br /&gt;
public T Get&amp;lt;T&gt;(IDictionary&amp;lt;K, V&gt; dictionary, K key)&lt;br /&gt;
where T: V&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if ((dictionary == null) || !dictionary.TryGetValue(key, out value))&lt;br /&gt;
{&lt;br /&gt;
return default(T);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return (T)value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets or removes a typed value.&lt;br /&gt;
// dictionary can be null.&lt;br /&gt;
// null returned if output dictionary would be empty. 
&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Set&amp;lt;T&gt;(IDictionary&amp;lt;K, V&gt; dictionary, K key, T value)&lt;br /&gt;
where T : V&lt;br /&gt;
{&lt;br /&gt;
return value == null ? Remove(dictionary, key) : 
&lt;br /&gt;
Set(dictionary, key, (V)value);&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
States can be cached. Provided the cache keeps states in a weak way, no unsued state
will be stored for a long time. We may use weak table of dictionary to dictionary &lt;code&gt;WeakTable&amp;lt;Dictionary&amp;lt;K,
V&amp;gt;, Dictionary&amp;lt;K, V&amp;gt;&amp;gt;&lt;/code&gt; as a storage for such a cache. All required
API is described in the &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx"&gt;WeakTable&lt;/a&gt; and &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx"&gt;Hash
Code of Dictionary&lt;/a&gt; posts.
&lt;/p&gt;
&lt;p&gt;
3. Style can be implemented as a structure with shared state as a storage. Here is
a scetch:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;[Serializable]&lt;br /&gt;
public struct Style&lt;br /&gt;
{&lt;br /&gt;
// All properties.&lt;br /&gt;
public enum Property&lt;br /&gt;
{&lt;br /&gt;
Background,&lt;br /&gt;
BorderColor,&lt;br /&gt;
BorderStyle,&lt;br /&gt;
Color,&lt;br /&gt;
FontFamily,&lt;br /&gt;
FontSize,&lt;br /&gt;
// ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? Background&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.Background); }&lt;br /&gt;
set { state = states.Set(state, Property.Background, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? BorderColor&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.BorderColor); }&lt;br /&gt;
set { state = states.Set(state, Property.BorderColor, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public string BorderStyle&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;string&gt;(state, Property.BorderStyle); }&lt;br /&gt;
set { state = states.Set(state, Property.BorderStyle, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? Color&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.Color); }&lt;br /&gt;
set { state = states.Set(state, Property.Color, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public string FontFamily&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;string&gt;(state, Property.FontFamily); }&lt;br /&gt;
set { state = states.Set(state, Property.FontFamily, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public double? FontSize&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;double?&gt;(state, Property.FontSize); }&lt;br /&gt;
set { state = states.Set(state, Property.FontSize, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
[OnDeserialized]&lt;br /&gt;
private void OnDeserialized(StreamingContext context)&lt;br /&gt;
{&lt;br /&gt;
state = states.Get(state);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A state.&lt;br /&gt;
private IDictionary&amp;lt;Property, object&gt; state;&lt;br /&gt;
&lt;br /&gt;
// A states cache.&lt;br /&gt;
private static readonly State&amp;lt;Property, object&gt; states =&lt;br /&gt;
new State&amp;lt;Property, object&gt;();&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Note that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
default state is a &lt;code&gt;null&lt;/code&gt; dictionary;&lt;/li&gt;
&lt;li&gt;
states are application wide shared.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The following link is our implementation of &lt;code&gt;&lt;a href="http://www.nesterovsky-bros.com/download/State.cs.txt"&gt;State&amp;lt;K,
V&amp;gt;&lt;/a&gt;&lt;/code&gt; class: &lt;a href="http://www.nesterovsky-bros.com/download/State.cs.txt"&gt;State.cs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Here we have outlined the idea of shared state object, and how it can be applied to
sparse mostly immutable objects. We used HTML style as an example of such an object.
Shared state object may work in many other areas, but for it to shine its use case
should fit to the task.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ab2110fa-c136-4b6b-bfdc-aa0dce059a97" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=bc06427b-87e2-4e14-9ebb-1a186f875e3a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=bc06427b-87e2-4e14-9ebb-1a186f875e3a</wfw:commentRss>
      <title>Hash Code of Dictionary</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx</link>
      <pubDate>Mon, 13 Jan 2014 20:33:31 GMT</pubDate>
      <description>    &lt;p&gt;
Dealing recently with some task (the same that inspired us to implement &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx"&gt;WeakTable&lt;/a&gt;),
we were in a position to use a dictionary as a key in another dictionary.
&lt;/p&gt;
&lt;p&gt;
What are the rules for the class to be used as key:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
key should be immutable;&lt;/li&gt;
&lt;li&gt;
key should implement a &lt;code&gt;GetHashCode()&lt;/code&gt; method;&lt;/li&gt;
&lt;li&gt;
key should implement a &lt;code&gt;Equals()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The first requirement is usually implemented as a documentation contract like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
As long as an object is used as a key in the &lt;code&gt;Dictionary&amp;lt;TKey, TValue&gt;&lt;/code&gt;,
it must not change in any way that affects its hash value.
&lt;/p&gt;
&lt;p&gt;
The third requirement about equals is trivially implemented as a method:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; public bool Equals(IDictionary&amp;lt;K, V&gt; x, IDictionary&amp;lt;K, V&gt; y)&lt;br /&gt;
{&lt;br /&gt;
if (x == y)&lt;br /&gt;
{&lt;br /&gt;
return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ((x == null) || (y == null) || (x.Count != y.Count))&lt;br /&gt;
{&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in x)&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if (!y.TryGetValue(entry.Key, out value) ||&lt;br /&gt;
!valueComparer.Equals(entry.Value, value))&lt;br /&gt;
{&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return true;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
But how would you implement hash code?
&lt;/p&gt;
&lt;p&gt;
We argued like this.
&lt;/p&gt;
&lt;p&gt;
1. Let&amp;#39;s consider the dictionary as a sparse array of values with only populated
items that correspond to key hash codes.
&lt;/p&gt;
&lt;p&gt;
2. Hash code is constructed using some fair algorithm. E.g like that used in java
to calculate &lt;a href="http://en.wikipedia.org/wiki/Java_hashCode()"&gt;string&amp;#39;s hash
code&lt;/a&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; n-1&lt;br /&gt;
h(s) = SUM (s[i]*p^(n-1-i)) mod m, where m = 2^31&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In our case:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; can be arbitrary large &lt;code&gt;int&lt;/code&gt; value, so in fact it&amp;#39;s &lt;code&gt;2^32&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
items are enumerated in unknown order;&lt;/li&gt;
&lt;li&gt;
there is only limited set of items, so most &lt;code&gt;s[i]&lt;/code&gt; are zeros.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As result we cannot use recurrent function to calculate a power &lt;code&gt;p^k mod m.&lt;/code&gt; Fortunately
one can build fast exponentiation arguing like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; 32/s - 1&lt;br /&gt;
p^k = p^ SUM 2^((s*i)*k[i]) mod m, where s some int: 1, 2, 4, 8, 16, or 32.&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Thus
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; 32/s - 1&lt;br /&gt;
p^k = PRODUCT (p^(2^(s*i)))^k[i] mod m&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
If &lt;code&gt;s = 1&lt;/code&gt; then &lt;code&gt;k[i]&lt;/code&gt; is either &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt; (a
bit), and there is &lt;code&gt;32&lt;/code&gt; different &lt;code&gt;p^(2^i) mod m&lt;/code&gt; values, which
can be precalculated.
&lt;/p&gt;
&lt;p&gt;
On the other hand, if we select &lt;code&gt;s = 8&lt;/code&gt; we can write the formula as:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;p^k = p^k[0] * (p^(2^8))^k[1] * (p^(2^16))^k[2] * (p^(2^24))^k[3] mod m&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;k[i]&lt;/code&gt; is a &lt;code&gt;8&lt;/code&gt; bit value (byte). 
&lt;/p&gt;
&lt;p style="direction: ltr"&gt;
Precalculating all values &lt;code&gt;p^n, (p^(2^8))^n&lt;/code&gt;, &lt;code&gt;(p^(2^16))^n&lt;/code&gt;, &lt;code&gt;(p^(2^24))^n&lt;/code&gt; for &lt;code&gt;n&lt;/code&gt; in &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;255&lt;/code&gt; we
reach the formula with &lt;code&gt;4&lt;/code&gt; multiplications and with &lt;code&gt;1024&lt;/code&gt; precalculated
values.
&lt;/p&gt;
&lt;p&gt;
Here is the whole utility to calculate hash factors:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Hash utilities.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public class Hash&lt;br /&gt;
{ 
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Returns a P^value mod 2^31, where P is hash base.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;param name="value"&gt;A value to get hash factor for.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;A hash factor value.&amp;lt;/returns&gt;&lt;br /&gt;
public static int GetHashFactor(int value)&lt;br /&gt;
{&lt;br /&gt;
return factors[(uint)value &amp; 0xff] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 8) &amp; 0xff) | 0x100] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 16) &amp; 0xff) | 0x200] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 24) &amp; 0xff) | 0x300];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Initializes hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
static Hash()&lt;br /&gt;
{&lt;br /&gt;
var values = new int[4 * 256];&lt;br /&gt;
var value = P;&lt;br /&gt;
var current = 1;&lt;br /&gt;
var i = 0;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 256);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 512);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 768);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 1024);&lt;br /&gt;
while(i 
&lt;br /&gt;
factors = values;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// A base to calculate hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public const int P = 1103515245;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
private static readonly int[] factors;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
With this API hash code for a dictionary is a trivial operation:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public int GetHashCode(IDictionary&amp;lt;K, V&gt; dictionary)&lt;br /&gt;
{&lt;br /&gt;
if (dictionary == null)&lt;br /&gt;
{&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in dictionary)&lt;br /&gt;
{&lt;br /&gt;
if ((entry.Key == null) || (entry.Value == null))&lt;br /&gt;
{&lt;br /&gt;
continue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
result += Hash.GetHashFactor(keyComparer.GetHashCode(entry.Key)) *&lt;br /&gt;
valueComparer.GetHashCode(entry.Value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
And finally, here is a reference to a class &lt;code&gt;&lt;a href="http://nesterovsky-bros.com/download/DictionaryEqualityComparer.cs.txt"&gt;DictionaryEqualityComparer&amp;lt;K,
V&gt;&lt;/a&gt;: IEqualityComparer&amp;lt;IDictionary&amp;lt;K, V&gt;&amp;gt;&lt;/code&gt; that allows a dictionary
to be a key in another dictionary.
&lt;/p&gt;
&lt;p style="font-weight: bold"&gt;
Update
&lt;/p&gt;
&lt;p&gt;
We have commited some tests, and have found that with suffiently &amp;quot;good&amp;quot;
implementation of GetHashCode() of key or value we achieve results almost of the same
quality, as the results of the algorithm we have outlined above with much simpler
and straightforward algorithm like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public int GetHashCode(IDictionary&amp;lt;K, V&gt; dictionary)&lt;br /&gt;
{&lt;br /&gt;
if (dictionary == null)&lt;br /&gt;
{&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in dictionary)&lt;br /&gt;
{&lt;br /&gt;
if ((entry.Key == null) || (entry.Value == null))&lt;br /&gt;
{&lt;br /&gt;
continue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var k = entry.Key.GetHashCode();&lt;br /&gt;
var v = entry.Value.GetHashCode();&lt;br /&gt;
&lt;br /&gt;&lt;&lt; 5) + k;&lt;br /&gt;&lt;&lt; (k &gt;
k = (k v = (v &gt; 3)) + v;&lt;br /&gt;
&lt;br /&gt;
result += k ^ v;&lt;br /&gt;
&lt;br /&gt;
//result += Hash.GetHashFactor(keyComparer.GetHashCode(entry.Key)) *&lt;br /&gt;
// valueComparer.GetHashCode(entry.Value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
It was worth to blog about this just to find out that we have outwitted ourselves,
and finally to reach to a trivial hash code implementation for the dictionary.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bc06427b-87e2-4e14-9ebb-1a186f875e3a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4abc49ac-23b2-448e-9951-f94e2393d672</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4abc49ac-23b2-448e-9951-f94e2393d672</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Dealing recently with some task, we were in a position to use a weak dictionary in
the .NET. Instinctively we assumed that it should exist somewhere in the standard
library. We definitely knew that there is a <code>WeakReference</code> class to for
a single instance. We also knew that there is <code>WeakHashMap</code> in java, and
that it's based on java's <code>WeakReference</code>.
</p>
        <p>
So, we were surprised to find that there is no such thing out of the box in .NET.
</p>
        <p>
We have found that java's and .NET's weak references are different. In java
weak references whose targets are GCed can be automatically put into a queue, which
can be used to build clean up logic to remove dead keys from weak hash map. There
is nothing similar in .NET, where weak reference just silently loses it's value.
</p>
        <p>
Internet is full with custom implementations of weak dictionaries in .NET.
</p>
        <p>
.NET 4.5 finally defines a class <a href="http://msdn.microsoft.com/en-us/library/dd287757(v=vs.110).aspx"><code>ConditionalWeakTable&lt;TKey,
TValue&gt;</code></a>, which solves the problem in case when you need to match keys
by instance identity.
</p>
        <p>
Unfortunately in our case we needed to match keys using key's <code>GetHashCode()</code> and <code>Equals()</code>.
So, <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> did not directly work, but
then we found a way to make it work for us.
</p>
        <p>
Here is a quote from the definition:
</p>
        <p style="padding-left: 1em; font-style: italic">
A <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> object is a dictionary that binds
a managed object, which is represented by a key, to its attached property, which is
represented by a value. The object's keys are the individual instances of the TKey
class to which the property is attached, and its values are the property values that
are assigned to the corresponding objects.<br /><br />
...in the <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> class, adding a key/value
pair to the table does not ensure that the key will persist, even if it can be reached
directly from a value stored in the table... Instead, ConditionalWeakTable&lt;TKey,
TValue&gt; automatically removes the key/value entry as soon as no other references to
a key exist outside the table. 
</p>
        <p>
This property of <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> has helped
us to build a way to get a notification when the key is being finalized, which is
the missed ingredient in .NET's weak references.
</p>
        <p>
Assume you have an instance <code>key</code> of type <code>Key</code>. To get a notification
you should define a class <code>Finalizer</code> that will call some handler when
it's finalized, and you should bind <code>key</code> and a finalizer instance
using weak table.
</p>
        <p>
The code looks like this:
</p>
        <p>
          <code>public class Finalizer&lt;K&gt;<br />
  where K: class<br />
{<br />
  public static void Bind(K key, Action&lt;K&gt; handler)<br />
  {<br />
    var finalizer = table.GetValue(key, k =&gt; new Finalizer&lt;K&gt;
{ key = k });<br /><br />
    finalizer.Handler += handler;<br />
  }<br /><br />
  public static void Unbind(K key, Action&lt;K&gt; handler)<br />
  {<br />
    Finalizer finalizer;<br /><br />
    if (table.TryGetValue(key, out finalizer))<br />
    {<br />
      finalizer.Handler -= handler;<br />
    }<br />
  }<br /><br />
  ~Finalizer()<br />
  {<br />
    var handler = Handler;<br /><br />
    if (handler != null)<br />
    {<br />
      handler(key);<br />
    }<br />
  }<br /><br />
  private event Action&lt;K&gt; Handler;<br />
  private K key;<br /><br />
  private static readonly ConditionalWeakTable&lt;K, Finalizer&gt; table =<br />
    new ConditionalWeakTable&lt;K, Finalizer&gt;();<br />
}<br /><br /><br />
Key key = ...<br /><br />
Finalizer.Bind(key, k =&gt; { /* clean up. */ });</code>
        </p>
        <p>
Using this approach we have created a class <a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt">WeakTable&lt;K,
V&gt;</a> modeled after ConditionalWeakTable&lt;TKey, TValue&gt;.
</p>
        <p>
So, this is our take in the problem: <a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt">WeakTable.cs</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4abc49ac-23b2-448e-9951-f94e2393d672" />
      </body>
      <title>WeakTable</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx</link>
      <pubDate>Wed, 08 Jan 2014 21:57:16 GMT</pubDate>
      <description>    &lt;p&gt;
Dealing recently with some task, we were in a position to use a weak dictionary in
the .NET. Instinctively we assumed that it should exist somewhere in the standard
library. We definitely knew that there is a &lt;code&gt;WeakReference&lt;/code&gt; class to for
a single instance. We also knew that there is &lt;code&gt;WeakHashMap&lt;/code&gt; in java, and
that it&amp;#39;s based on java&amp;#39;s &lt;code&gt;WeakReference&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
So, we were surprised to find that there is no such thing out of the box in .NET.
&lt;/p&gt;
&lt;p&gt;
We have found that java&amp;#39;s and .NET&amp;#39;s weak references are different. In java
weak references whose targets are GCed can be automatically put into a queue, which
can be used to build clean up logic to remove dead keys from weak hash map. There
is nothing similar in .NET, where weak reference just silently loses it&amp;#39;s value.
&lt;/p&gt;
&lt;p&gt;
Internet is full with custom implementations of weak dictionaries in .NET.
&lt;/p&gt;
&lt;p&gt;
.NET 4.5 finally defines a class &lt;a href="http://msdn.microsoft.com/en-us/library/dd287757(v=vs.110).aspx"&gt;&lt;code&gt;ConditionalWeakTable&amp;lt;TKey,
TValue&amp;gt;&lt;/code&gt;&lt;/a&gt;, which solves the problem in case when you need to match keys
by instance identity.
&lt;/p&gt;
&lt;p&gt;
Unfortunately in our case we needed to match keys using key&amp;#39;s &lt;code&gt;GetHashCode()&lt;/code&gt; and &lt;code&gt;Equals()&lt;/code&gt;.
So, &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;&lt;/code&gt; did not directly work, but
then we found a way to make it work for us.
&lt;/p&gt;
&lt;p&gt;
Here is a quote from the definition:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
A &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&gt;&lt;/code&gt; object is a dictionary that binds
a managed object, which is represented by a key, to its attached property, which is
represented by a value. The object's keys are the individual instances of the TKey
class to which the property is attached, and its values are the property values that
are assigned to the corresponding objects.&lt;br /&gt;
&lt;br /&gt;
...in the &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&gt;&lt;/code&gt; class, adding a key/value
pair to the table does not ensure that the key will persist, even if it can be reached
directly from a value stored in the table... Instead, ConditionalWeakTable&amp;lt;TKey,
TValue&gt; automatically removes the key/value entry as soon as no other references to
a key exist outside the table. 
&lt;/p&gt;
&lt;p&gt;
This property of &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;&lt;/code&gt; has helped
us to build a way to get a notification when the key is being finalized, which is
the missed ingredient in .NET&amp;#39;s weak references.
&lt;/p&gt;
&lt;p&gt;
Assume you have an instance &lt;code&gt;key&lt;/code&gt; of type &lt;code&gt;Key&lt;/code&gt;. To get a notification
you should define a class &lt;code&gt;Finalizer&lt;/code&gt; that will call some handler when
it&amp;#39;s finalized, and you should bind &lt;code&gt;key&lt;/code&gt; and a finalizer instance
using weak table.
&lt;/p&gt;
&lt;p&gt;
The code looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;public class Finalizer&amp;lt;K&amp;gt;&lt;br /&gt;
&amp;nbsp; where K: class&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; public static void Bind(K key, Action&amp;lt;K&amp;gt; handler)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var finalizer = table.GetValue(key, k =&amp;gt; new Finalizer&amp;lt;K&amp;gt;
{ key = k });&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finalizer.Handler += handler;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static void Unbind(K key, Action&amp;lt;K&amp;gt; handler)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Finalizer finalizer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (table.TryGetValue(key, out finalizer))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finalizer.Handler -= handler;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; ~Finalizer()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var handler = Handler;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (handler != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; handler(key);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; private event Action&amp;lt;K&amp;gt; Handler;&lt;br /&gt;
&amp;nbsp; private K key;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; private static readonly ConditionalWeakTable&amp;lt;K, Finalizer&amp;gt; table =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new ConditionalWeakTable&amp;lt;K, Finalizer&amp;gt;();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key key = ...&lt;br /&gt;
&lt;br /&gt;
Finalizer.Bind(key, k =&amp;gt; { /* clean up. */ });&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Using this approach we have created a class &lt;a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt"&gt;WeakTable&amp;lt;K,
V&amp;gt;&lt;/a&gt; modeled after ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
So, this is our take in the problem: &lt;a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt"&gt;WeakTable.cs&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4abc49ac-23b2-448e-9951-f94e2393d672" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</comments>
      <category>.NET</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=91ba6c08-d73c-416f-a3d7-6da67e5baa1b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,91ba6c08-d73c-416f-a3d7-6da67e5baa1b.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,91ba6c08-d73c-416f-a3d7-6da67e5baa1b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=91ba6c08-d73c-416f-a3d7-6da67e5baa1b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Oftentimes we deal with Hebrew in .NET.
</p>
        <p>
The task we face again and again is attempt to convert a Hebrew text from visual to
logical representation.
</p>
        <p>
The latest demand of such task was when we processed content extracted from PDF. It's
turned out that PDF stores content as graphic primitives, and as result text is stored
visually (often each letter is kept separately).
</p>
        <p>
We solved the task more than a decade ago, by calling <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd374091(v=vs.85).aspx">Uniscribe
API</a>.
</p>
        <p>
The function by itself is a small wrapper around that API, so in .NET 1.0 we were
using managed C++, several years later we have switched to C++/CLI.
</p>
        <p>
But now after many .NET releases, and with 32/64 versions we can see that C++ is only
a guest in .NET world.
</p>
        <p>
To run C++ in .NET you have to install VC runtime libraries adjusted to a specific
.NET version. This turns C++ support in .NET into not a trivial task.
</p>
        <p>
So, we have finally decided to define C# interop for the Uniscribe API, and recreate
that function in pure C#:
</p>
        <p style="padding-left: 1em">
          <code>namespace NesterovskyBros.Bidi<br />
{<br />
  /// &lt;summary&gt;<br />
  /// An utility to convert visual string to logical.<br />
  /// &lt;summary&gt;<br />
  public static class BidiConverter<br />
  {<br />
    /// &lt;summary&gt;<br />
    /// Converts visual string to logical.<br />
    /// &lt;/summary&gt;<br />
    /// &lt;param name="value"&gt;A value to convert.&lt;/param&gt;<br />
    /// &lt;param name="rtl"&gt;A base direction.&lt;/param&gt;<br />
    /// &lt;param name="direction"&gt;<br />
    /// true for visual to logical, and false for logical to visual.<br />
    /// &lt;/param&gt;<br />
    /// &lt;returns&gt;Converted string.&lt;/returns&gt;<br />
    public static string Convert(string value, bool rtl, bool direction);</code>
        </p>
        <p>
You can download this project from <a href="http://www.nesterovsky-bros.com/download/BidiVisualConverter.zip">BidiVisualConverter.zip</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=91ba6c08-d73c-416f-a3d7-6da67e5baa1b" />
      </body>
      <title>Bidi Visual Converter</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,91ba6c08-d73c-416f-a3d7-6da67e5baa1b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/12/27/BidiVisualConverter.aspx</link>
      <pubDate>Fri, 27 Dec 2013 20:36:20 GMT</pubDate>
      <description>    &lt;p&gt;
Oftentimes we deal with Hebrew in .NET.
&lt;/p&gt;
&lt;p&gt;
The task we face again and again is attempt to convert a Hebrew text from visual to
logical representation.
&lt;/p&gt;
&lt;p&gt;
The latest demand of such task was when we processed content extracted from PDF. It&amp;#39;s
turned out that PDF stores content as graphic primitives, and as result text is stored
visually (often each letter is kept separately).
&lt;/p&gt;
&lt;p&gt;
We solved the task more than a decade ago, by calling &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd374091(v=vs.85).aspx"&gt;Uniscribe
API&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The function by itself is a small wrapper around that API, so in .NET 1.0 we were
using managed C++, several years later we have switched to C++/CLI.
&lt;/p&gt;
&lt;p&gt;
But now after many .NET releases, and with 32/64 versions we can see that C++ is only
a guest in .NET world.
&lt;/p&gt;
&lt;p&gt;
To run C++ in .NET you have to install VC runtime libraries adjusted to a specific
.NET version. This turns C++ support in .NET into not a trivial task.
&lt;/p&gt;
&lt;p&gt;
So, we have finally decided to define C# interop for the Uniscribe API, and recreate
that function in pure C#:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;namespace NesterovskyBros.Bidi&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// An utility to convert visual string to logical.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; public static class BidiConverter&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Converts visual string to logical.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to convert.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="rtl"&gt;A base direction.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="direction"&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// true for visual to logical, and false for logical to visual.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;Converted string.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string Convert(string value, bool rtl, bool direction);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
You can download this project from &lt;a href="http://www.nesterovsky-bros.com/download/BidiVisualConverter.zip"&gt;BidiVisualConverter.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=91ba6c08-d73c-416f-a3d7-6da67e5baa1b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,91ba6c08-d73c-416f-a3d7-6da67e5baa1b.aspx</comments>
      <category>.NET</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b3e9c372-f08e-4dba-80eb-c69f1130ef51</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b3e9c372-f08e-4dba-80eb-c69f1130ef51.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b3e9c372-f08e-4dba-80eb-c69f1130ef51</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Before to start we have to confess that afer many years of experience we sincerely
dislike JSF technology, as we think it's outdated compared to html 5 + REST. 
</p>
        <p>
We have a JSF 2.2 application, which is configured to track session through url. In
this case Session ID is stored in url and not in cookies, as there may be many sessions
opened per a client. 
</p>
        <p>
At the same time application uses libraries that expose scripts and css resources.
This resources are referred to like this: 
</p>
        <p style="padding-left: 1em;">
          <code>&lt;link rel="stylesheet" type="text/css" jsfc="h:outputStylesheet"
library="css" name="library-name.css"/&gt;<br />
&lt;script type="text/javascript" jsfc="h:outputScript" name="library-name.js"
library="scripts" target="head"&gt;&lt;/script&gt;</code>
        </p>
        <p>
At runtime this is rendered as: 
</p>
        <p style="padding-left: 1em">
          <code>&lt;link type="text/css" rel="stylesheet"<br />
href="/App/javax.faces.resource/library-name.css.jsf;jsessionid=FC4A893330CCE12E8E20DFAFC73CDF35?ln=css"
/&gt;<br />
&lt;script type="text/javascript" 
<br />
src="/App/javax.faces.resource/library-name.js.jsf;jsessionid=FC4A893330CCE12E8E20DFAFC73CDF35?ln=scripts"&gt;&lt;/script&gt;</code>
        </p>
        <p>
You can see that Session ID is a part of url path, which prevents resource caching
on a client. 
</p>
        <p>
It's not clear whether it's what JSF spec dictates or it's Oracle's
Reference Implementation detail. We're certain, however, that it's too wasteful
in heavy loaded environment, so we have tried to resolve the problem. 
</p>
        <p>
From JSF sources we have found that <code>h:outputStylesheet</code>, <code>h:outputScript</code>,
and <code>h:outputLink</code> all use <code>ExternalContext.encodeResourceURL()</code> method
to build markup url. 
</p>
        <p>
So, here is a solution: to provide custom wrapper for the <code>ExternalContext</code>. 
</p>
        <p>
This is done in two steps: 
</p>
        <ol>
          <li>
create a factory class;</li>
          <li>
register a factory in faces-config.xml;</li>
        </ol>
        <p>
1. Factory is a simple class but unfortunately it's implementation specific: 
</p>
        <p style="padding-left: 1em">
          <code style="direction: ltr">package com.nesterovskyBros.jsf;<br /><br />
import javax.faces.FacesException;<br /><br />
import javax.faces.context.ExternalContext;<br />
import javax.faces.context.ExternalContextWrapper;<br /><br />
import com.sun.faces.context.ExternalContextFactoryImpl;<br /><br />
/**<br />
* {@link ExternalContextFactory} to prevent session id in resource urls.<br />
*/<br />
public class ExternalContextFactory extends ExternalContextFactoryImpl<br />
{<br />
/**<br />
* {@inheritDoc}<br />
*/<br />
@Override<br />
public ExternalContext getExternalContext(<br />
Object context,<br />
Object request,<br />
Object response)<br />
throws FacesException<br />
{<br />
final ExternalContext externalContext = 
<br />
super.getExternalContext(context, request, response); 
<br /><br />
return new ExternalContextWrapper()<br />
{<br />
@Override<br />
public ExternalContext getWrapped()<br />
{<br />
return externalContext;<br />
}<br /><br />
@Override<br />
public String encodeResourceURL(String url)<br />
{<br />
return shouldEncode(url) ? super.encodeResourceURL(url) : url;<br />
}<br /><br />
private boolean shouldEncode(String url)<br />
{ 
<br />
// Decide here whether you want to encode url.<br />
// E.g. in case of h:outputLink you may want to have session id in url,<br />
// so your decision is based on some marker (like &amp;session=1) in url. 
<br />
return false;<br />
}<br />
};<br />
}<br />
}</code>
        </p>
        <p>
2. Registration is just three lines in <code>faces-config.xml</code>:
</p>
        <p style="padding-left: 1em">
          <code>&lt;factory&gt;<br />
&lt;external-context-factory&gt;com.nesterovskyBros.jsf.ExternalContextFactory&lt;/external-context-factory&gt;<br />
&lt;/factory&gt; </code>
        </p>
        <p>
After that change at runtime we have: 
</p>
        <p style="padding-left: 1em">
          <code>&lt;link type="text/css" rel="stylesheet"<br />
href="/App/javax.faces.resource/library-name.css.jsf?ln=css" /&gt;<br />
&lt;script type="text/javascript" 
<br />
src="/App/javax.faces.resource/library-name.js.jsf?ln=scripts"&gt;&lt;/script&gt;</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b3e9c372-f08e-4dba-80eb-c69f1130ef51" />
      </body>
      <title>Library resources in JSF</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b3e9c372-f08e-4dba-80eb-c69f1130ef51.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/11/11/LibraryResourcesInJSF.aspx</link>
      <pubDate>Mon, 11 Nov 2013 13:08:53 GMT</pubDate>
      <description>  &lt;p&gt;
Before to start we have to confess that afer many years of experience we sincerely
dislike JSF technology, as we think it&amp;#39;s outdated compared to html 5 + REST. 
&lt;/p&gt;
&lt;p&gt;
We have a JSF 2.2 application, which is configured to track session through url. In
this case Session ID is stored in url and not in cookies, as there may be many sessions
opened per a client. 
&lt;/p&gt;
&lt;p&gt;
At the same time application uses libraries that expose scripts and css resources.
This resources are referred to like this: 
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; jsfc=&amp;quot;h:outputStylesheet&amp;quot;
library=&amp;quot;css&amp;quot; name=&amp;quot;library-name.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; jsfc=&amp;quot;h:outputScript&amp;quot; name=&amp;quot;library-name.js&amp;quot;
library=&amp;quot;scripts&amp;quot; target=&amp;quot;head&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
At runtime this is rendered as: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;link type="text/css" rel="stylesheet"&lt;br /&gt;
href="/App/javax.faces.resource/library-name.css.jsf;jsessionid=FC4A893330CCE12E8E20DFAFC73CDF35?ln=css"
/&amp;gt;&lt;br /&gt;
&amp;lt;script type="text/javascript" 
&lt;br /&gt;
src="/App/javax.faces.resource/library-name.js.jsf;jsessionid=FC4A893330CCE12E8E20DFAFC73CDF35?ln=scripts"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
You can see that Session ID is a part of url path, which prevents resource caching
on a client. 
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s not clear whether it&amp;#39;s what JSF spec dictates or it&amp;#39;s Oracle&amp;#39;s
Reference Implementation detail. We&amp;#39;re certain, however, that it&amp;#39;s too wasteful
in heavy loaded environment, so we have tried to resolve the problem. 
&lt;/p&gt;
&lt;p&gt;
From JSF sources we have found that &lt;code&gt;h:outputStylesheet&lt;/code&gt;, &lt;code&gt;h:outputScript&lt;/code&gt;,
and &lt;code&gt;h:outputLink&lt;/code&gt; all use &lt;code&gt;ExternalContext.encodeResourceURL()&lt;/code&gt; method
to build markup url. 
&lt;/p&gt;
&lt;p&gt;
So, here is a solution: to provide custom wrapper for the &lt;code&gt;ExternalContext&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
This is done in two steps: 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
create a factory class;&lt;/li&gt;
&lt;li&gt;
register a factory in faces-config.xml;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
1. Factory is a simple class but unfortunately it&amp;#39;s implementation specific: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code style="direction: ltr"&gt;package com.nesterovskyBros.jsf;&lt;br /&gt;
&lt;br /&gt;
import javax.faces.FacesException;&lt;br /&gt;
&lt;br /&gt;
import javax.faces.context.ExternalContext;&lt;br /&gt;
import javax.faces.context.ExternalContextWrapper;&lt;br /&gt;
&lt;br /&gt;
import com.sun.faces.context.ExternalContextFactoryImpl;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
* {@link ExternalContextFactory} to prevent session id in resource urls.&lt;br /&gt;
*/&lt;br /&gt;
public class ExternalContextFactory extends ExternalContextFactoryImpl&lt;br /&gt;
{&lt;br /&gt;
/**&lt;br /&gt;
* {@inheritDoc}&lt;br /&gt;
*/&lt;br /&gt;
@Override&lt;br /&gt;
public ExternalContext getExternalContext(&lt;br /&gt;
Object context,&lt;br /&gt;
Object request,&lt;br /&gt;
Object response)&lt;br /&gt;
throws FacesException&lt;br /&gt;
{&lt;br /&gt;
final ExternalContext externalContext = 
&lt;br /&gt;
super.getExternalContext(context, request, response); 
&lt;br /&gt;
&lt;br /&gt;
return new ExternalContextWrapper()&lt;br /&gt;
{&lt;br /&gt;
@Override&lt;br /&gt;
public ExternalContext getWrapped()&lt;br /&gt;
{&lt;br /&gt;
return externalContext;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public String encodeResourceURL(String url)&lt;br /&gt;
{&lt;br /&gt;
return shouldEncode(url) ? super.encodeResourceURL(url) : url;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private boolean shouldEncode(String url)&lt;br /&gt;
{ 
&lt;br /&gt;
// Decide here whether you want to encode url.&lt;br /&gt;
// E.g. in case of h:outputLink you may want to have session id in url,&lt;br /&gt;
// so your decision is based on some marker (like &amp;amp;session=1) in url. 
&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
};&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
2. Registration is just three lines in &lt;code&gt;faces-config.xml&lt;/code&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;factory&amp;gt;&lt;br /&gt;
&amp;lt;external-context-factory&amp;gt;com.nesterovskyBros.jsf.ExternalContextFactory&amp;lt;/external-context-factory&amp;gt;&lt;br /&gt;
&amp;lt;/factory&amp;gt; &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
After that change at runtime we have: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;link type="text/css" rel="stylesheet"&lt;br /&gt;
href="/App/javax.faces.resource/library-name.css.jsf?ln=css" /&amp;gt;&lt;br /&gt;
&amp;lt;script type="text/javascript" 
&lt;br /&gt;
src="/App/javax.faces.resource/library-name.js.jsf?ln=scripts"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b3e9c372-f08e-4dba-80eb-c69f1130ef51" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b3e9c372-f08e-4dba-80eb-c69f1130ef51.aspx</comments>
      <category>Java</category>
      <category>JSF and Facelets</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7cf68687-5531-41ee-bf63-10b62592157a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7cf68687-5531-41ee-bf63-10b62592157a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Till recently we were living in simple world of string comparisons in SQL style, and
now everything has changed. 
</p>
        <p>
From the university years we knew that strings in SQL are compared by first trimming
traling spaces, and then comparing in C style. 
</p>
        <p>
Well, the picture was a little more complex, as collations were involved (national,
case sensivity), and as different SQL vendors implemented it differently. 
</p>
        <p>
Next,<br />
we're dealing with programs converted from COBOL, which we originally thought
follow SQL rules when strings are compared. 
</p>
        <p>
  
</p>
        <p>
Here is where the problem has started. 
</p>
        <p>
Once we have found that java program has branched differently than original COBOL,
and the reason was that the COBOL and java compared two strings differently: 
</p>
        <ul>
          <li>
COBOL: <code>"A\n" &lt; "A"</code>;</li>
          <li>
Java: <code>"A\n" &gt; "A"</code></li>
        </ul>
        <p>
We have looked into <a href="http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/index.jsp?topic=%2Fcom.ibm.entcobol.doc_3.4%2Frlpdsalp.htm"> COBOL
Language Reference</a> and found the rules: 
</p>
        <div style="padding-left: 1em; font-style: italic">
          <dl>
            <dt style="font-weight: bold">Operands of equal size</dt>
            <dd>
Characters in corresponding positions of the two operands are compared, beginning
with the leftmost character and continuing through the rightmost character. 
<p>
If all pairs of characters through the last pair test as equal, the operands are considered
as equal. 
</p><p>
If a pair of unequal characters is encountered, the characters are tested to determine
their relative positions in the collating sequence. The operand that contains the
character higher in the sequence is considered the greater operand. 
</p></dd>
            <dt style="font-weight: bold">Operands of unequal size</dt>
            <dd>
If the operands are of unequal size, the comparison is made as though the shorter
operand were extended to the right with enough spaces to make the operands equal in
size. 
</dd>
          </dl>
        </div>
        <p>
You can see that strings must not be trimmed but padded with spaces to the longer
string, and only then they are compared. This subtle difference has significant impact
for characters below the space.
</p>
        <p>
So, here we've found that COBOL and SQL comparisons are different.
</p>
        <p>
But then we have questioned how really SQL beheaves?
</p>
        <p>
We've tested comparisons in SQL Server and DB2, and have seen that our understanding
of SQL comparison holds. It works as if trimming spaces, and then comparing.
</p>
        <p>
But again we have looked into SQL-92 definition, and that's what we see there:
</p>
        <p style="font-style: italic; padding-left: 1em">
8.2 &lt;comparison predicate&gt;<br />
3) The comparison of two character strings is determined as follows:<br /><br />
a) If the length in characters of X is not equal to the length in characters of Y,
then the shorter string is effectively replaced, for the purposes of comparison, with
a copy of itself that has been extended to the length of the longer string by concatenation
on the right of one or more pad characters, where the pad character is chosen based
on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent
character different from any character in the character set of X and Y that collates
less than any string under CS. Otherwise, the pad character is a &lt;space&gt;.
</p>
        <p>
So, what we see is that SQL-92 rules are very close to COBOL rules, but then we reach
the question: how come that at least SQL Server and DB2 implement string comparison
differently than SQL-92 dictates?
</p>
        <p>
          <b>Update: </b> we have found that both SQL Server and DB2 have their string collation
defined in a way that &lt;space&gt; is less than any other character. So the following
is always true: <code>'[' + char(13) + ']' &gt; '[ ]'</code>. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7cf68687-5531-41ee-bf63-10b62592157a" />
      </body>
      <title>String comparision: SQL vs COBOL</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/10/14/StringComparisionSQLVsCOBOL.aspx</link>
      <pubDate>Mon, 14 Oct 2013 20:23:11 GMT</pubDate>
      <description>  &lt;p&gt;
Till recently we were living in simple world of string comparisons in SQL style, and
now everything has changed. 
&lt;/p&gt;
&lt;p&gt;
From the university years we knew that strings in SQL are compared by first trimming
traling spaces, and then comparing in C style. 
&lt;/p&gt;
&lt;p&gt;
Well, the picture was a little more complex, as collations were involved (national,
case sensivity), and as different SQL vendors implemented it differently. 
&lt;/p&gt;
&lt;p&gt;
Next,&lt;br /&gt;
we&amp;#39;re dealing with programs converted from COBOL, which we originally thought
follow SQL rules when strings are compared. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Here is where the problem has started. 
&lt;/p&gt;
&lt;p&gt;
Once we have found that java program has branched differently than original COBOL,
and the reason was that the COBOL and java compared two strings differently: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
COBOL: &lt;code&gt;&amp;quot;A\n&amp;quot; &amp;lt; &amp;quot;A&amp;quot;&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
Java: &lt;code&gt;&amp;quot;A\n&amp;quot; &amp;gt; &amp;quot;A&amp;quot;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We have looked into &lt;a href="http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/index.jsp?topic=%2Fcom.ibm.entcobol.doc_3.4%2Frlpdsalp.htm"&gt; COBOL
Language Reference&lt;/a&gt; and found the rules: 
&lt;/p&gt;
&lt;div style="padding-left: 1em; font-style: italic"&gt;
&lt;dl&gt;
&lt;dt style="font-weight: bold"&gt;Operands of equal size&lt;/dt&gt; 
&lt;dd&gt;
Characters in corresponding positions of the two operands are compared, beginning
with the leftmost character and continuing through the rightmost character. 
&lt;p&gt;
If all pairs of characters through the last pair test as equal, the operands are considered
as equal. 
&lt;/p&gt;
&lt;p&gt;
If a pair of unequal characters is encountered, the characters are tested to determine
their relative positions in the collating sequence. The operand that contains the
character higher in the sequence is considered the greater operand. 
&lt;/p&gt;
&lt;/dd&gt;
&lt;dt style="font-weight: bold"&gt;Operands of unequal size&lt;/dt&gt; 
&lt;dd&gt;
If the operands are of unequal size, the comparison is made as though the shorter
operand were extended to the right with enough spaces to make the operands equal in
size. 
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;
You can see that strings must not be trimmed but padded with spaces to the longer
string, and only then they are compared. This subtle difference has significant impact
for characters below the space.
&lt;/p&gt;
&lt;p&gt;
So, here we've found that COBOL and SQL comparisons are different.
&lt;/p&gt;
&lt;p&gt;
But then we have questioned how really SQL beheaves?
&lt;/p&gt;
&lt;p&gt;
We've tested comparisons in SQL Server and DB2, and have seen that our understanding
of SQL comparison holds. It works as if trimming spaces, and then comparing.
&lt;/p&gt;
&lt;p&gt;
But again we have looked into SQL-92 definition, and that&amp;#39;s what we see there:
&lt;/p&gt;
&lt;p style="font-style: italic; padding-left: 1em"&gt;
8.2 &amp;lt;comparison predicate&amp;gt;&lt;br /&gt;
3) The comparison of two character strings is determined as follows:&lt;br /&gt;
&lt;br /&gt;
a) If the length in characters of X is not equal to the length in characters of Y,
then the shorter string is effectively replaced, for the purposes of comparison, with
a copy of itself that has been extended to the length of the longer string by concatenation
on the right of one or more pad characters, where the pad character is chosen based
on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent
character different from any character in the character set of X and Y that collates
less than any string under CS. Otherwise, the pad character is a &amp;lt;space&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
So, what we see is that SQL-92 rules are very close to COBOL rules, but then we reach
the question: how come that at least SQL Server and DB2 implement string comparison
differently than SQL-92 dictates?
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Update: &lt;/b&gt; we have found that both SQL Server and DB2 have their string collation
defined in a way that &amp;lt;space&amp;gt; is less than any other character. So the following
is always true: &lt;code&gt;'[' + char(13) + ']' &gt; '[ ]'&lt;/code&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7cf68687-5531-41ee-bf63-10b62592157a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</comments>
      <category>Java</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c7c57f76-19a7-4b95-a957-2fa974dd72b2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c7c57f76-19a7-4b95-a957-2fa974dd72b2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c7c57f76-19a7-4b95-a957-2fa974dd72b2</wfw:commentRss>
      <title>KendoUI's guid function</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c7c57f76-19a7-4b95-a957-2fa974dd72b2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/08/09/KendoUIsGuidFunction.aspx</link>
      <pubDate>Fri, 09 Aug 2013 14:24:16 GMT</pubDate>
      <description>  &lt;p&gt;
Earlier we have written a post &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/07/30/KendoUIsSlowestFunction.aspx"&gt;KendoUI's
slowest function&lt;/a&gt; and now, we want to point to the next slow function, which is &lt;code&gt;kendo.guid()&lt;/code&gt;.
It&amp;#39;s used to assign &lt;code&gt;uid&lt;/code&gt; to each observable object, and also in couple
of other places.
&lt;/p&gt;
&lt;p&gt;
Here is its source:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; guid: function() {&lt;br /&gt;
var id = "", i, random;&lt;br /&gt;
&lt;br /&gt;
for (i = 0; i &amp;lt; 32; i++) {&lt;br /&gt;
random = math.random() * 16 | 0;&lt;br /&gt;
&lt;br /&gt;
if (i == 8 || i == 12 || i == 16 || i == 20) {&lt;br /&gt;
id += "-";&lt;br /&gt;
}&lt;br /&gt;
id += (i == 12 ? 4 : (i == 16 ? (random &amp; 3 | 8) : random)).toString(16);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return id;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
KendoUI people have decided to define &lt;code&gt;uid&lt;/code&gt; as a string in format of &lt;a href="http://en.wikipedia.org/wiki/Globally_unique_identifier"&gt;Globally
unique identifier&lt;/a&gt;. We think there is no reason to have such a complex value; it&amp;#39;s
enough to have counter to generate &lt;code&gt;uid&lt;/code&gt; values. As KendoUI relies on the
string type of &lt;code&gt;uid&lt;/code&gt;, so we have defined a patch like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var guid = 0&lt;br /&gt;
&lt;br /&gt;
kendo.guid = function() { return ++guid + &amp;quot;&amp;quot; } &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Consider now a test case. It&amp;#39;s almost identical to that in previous post:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Test&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;script src="scripts/jquery/jquery.min..js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src="scripts/kendo/kendo.web.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link href="styles/kendo.common.min.css" rel="stylesheet" /&amp;gt;&lt;br /&gt;
&amp;lt;link href="styles/kendo.default.min.css" rel="stylesheet" /&amp;gt;&lt;br /&gt;
&amp;lt;link href="styles/style.css" rel="stylesheet" /&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
var model;&lt;br /&gt;
&lt;br /&gt;
function init()&lt;br /&gt;
{&lt;br /&gt;
var source = [];&lt;br /&gt;
&lt;br /&gt;
for(var i = 0; i &amp;lt; 1000; ++i)&lt;br /&gt;
{&lt;br /&gt;
source.push({ text: "value " + i, value: "" + i });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
model = kendo.observable(&lt;br /&gt;
{&lt;br /&gt;
value: "1",&lt;br /&gt;
source: new kendo.data.DataSource(&lt;br /&gt;
{&lt;br /&gt;
data: source&lt;br /&gt;
})&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
model.source.read();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function patch()&lt;br /&gt;
{&lt;br /&gt;
var base = kendo.data.binders.widget.source.fn._ns;&lt;br /&gt;
var result;&lt;br /&gt;
&lt;b&gt;var guid = 0;&lt;br /&gt;
&lt;br /&gt;
kendo.guid = function() { return ++guid + &amp;quot;&amp;quot;; };&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
kendo.data.binders.widget.source.fn._ns = function(ns)&lt;br /&gt;
{&lt;br /&gt;
return ns ? base.call(this, ns) :&lt;br /&gt;
(result || (result = base.call(this, ns)));&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function test()&lt;br /&gt;
{&lt;br /&gt;
init();&lt;br /&gt;
kendo.bind("#view", model);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
patch();&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;button onclick="test()"&amp;gt;Click to start test&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p id="view"&amp;gt;&lt;br /&gt;
Select: 
&lt;br /&gt;
&amp;lt;input data-role="dropdownlist" 
&lt;br /&gt;
data-bind="value: value, source: source" 
&lt;br /&gt;
data-text-field="text" 
&lt;br /&gt;
data-value-field="value"/&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Now, we can compare performance with and without that patch.
&lt;/p&gt;
&lt;p&gt;
Here is a run statistics without patch: 
&lt;/p&gt;
&lt;div style="padding-left: 1em"&gt;
&lt;table border="1"&gt;
&lt;colgroup&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col style="color: blue" /&gt;
&lt;col /&gt;
&lt;/colgroup&gt;
&lt;tr&gt;
&lt;td&gt;
Level&lt;/td&gt;
&lt;td&gt;
Function&lt;/td&gt;
&lt;td&gt;
Count&lt;/td&gt;
&lt;td&gt;
Inclusive time (ms)&lt;/td&gt;
&lt;td&gt;
Inclusive time %&lt;/td&gt;
&lt;td&gt;
Avg time (ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
onclick&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
270.73&lt;/td&gt;
&lt;td&gt;
100&lt;/td&gt;
&lt;td&gt;
270.73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1&lt;/td&gt;
&lt;td&gt;
test&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
269.73&lt;/td&gt;
&lt;td&gt;
99.63&lt;/td&gt;
&lt;td&gt;
269.73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1.1&lt;/td&gt;
&lt;td&gt;
init&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
117.07&lt;/td&gt;
&lt;td&gt;
43.24&lt;/td&gt;
&lt;td&gt;
117.07&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="color: red"&gt;
&lt;td&gt;
1.1.1.1&lt;/td&gt;
&lt;td&gt;
guid&lt;/td&gt;
&lt;td&gt;
1,001&lt;/td&gt;
&lt;td&gt;
72.05&lt;/td&gt;
&lt;td&gt;
26.61&lt;/td&gt;
&lt;td&gt;
0.07&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1.2&lt;/td&gt;
&lt;td&gt;
bind&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
152.65&lt;/td&gt;
&lt;td&gt;
56.39&lt;/td&gt;
&lt;td&gt;
152.65&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;
and with patch:
&lt;/p&gt;
&lt;div style="padding-left: 1em"&gt;
&lt;table border="1"&gt;
&lt;colgroup&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col /&gt;
&lt;col style="color: blue" /&gt;
&lt;col /&gt;
&lt;/colgroup&gt;
&lt;tr&gt;
&lt;td&gt;
Level&lt;/td&gt;
&lt;td&gt;
Function&lt;/td&gt;
&lt;td&gt;
Count&lt;/td&gt;
&lt;td&gt;
Inclusive time (ms)&lt;/td&gt;
&lt;td&gt;
Inclusive time %&lt;/td&gt;
&lt;td&gt;
Avg time (ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
onclick&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
172.64&lt;/td&gt;
&lt;td&gt;
100&lt;/td&gt;
&lt;td&gt;
172.64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1&lt;/td&gt;
&lt;td&gt;
test&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
171.65&lt;/td&gt;
&lt;td&gt;
99.42&lt;/td&gt;
&lt;td&gt;
171.65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1.1&lt;/td&gt;
&lt;td&gt;
init&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
62.04&lt;/td&gt;
&lt;td&gt;
35.94&lt;/td&gt;
&lt;td&gt;
62.04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="color: red"&gt;
&lt;td&gt;
1.1.1.1&lt;/td&gt;
&lt;td&gt;
guid&lt;/td&gt;
&lt;td&gt;
1,001&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
0.58&lt;/td&gt;
&lt;td&gt;
0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
1.1.2&lt;/td&gt;
&lt;td&gt;
bind&lt;/td&gt;
&lt;td&gt;
1&lt;/td&gt;
&lt;td&gt;
109.6&lt;/td&gt;
&lt;td&gt;
63.49&lt;/td&gt;
&lt;td&gt;
109.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;
Note that statistics were collected for IE 10.&lt;br /&gt;
An example can be found at &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/slow2.html"&gt;slow2.html&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c7c57f76-19a7-4b95-a957-2fa974dd72b2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c7c57f76-19a7-4b95-a957-2fa974dd72b2.aspx</comments>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7f76695c-3bef-460f-befd-3ae983809d74</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7f76695c-3bef-460f-befd-3ae983809d74.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7f76695c-3bef-460f-befd-3ae983809d74</wfw:commentRss>
      <title>Visual to logical conversion in Java</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7f76695c-3bef-460f-befd-3ae983809d74.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/07/28/VisualToLogicalConversionInJava.aspx</link>
      <pubDate>Sun, 28 Jul 2013 15:44:17 GMT</pubDate>
      <description>  &lt;p&gt;
Time after time we run into the same problem on different platforms, with different
languages. The problem's name is "Visual to Logical conversion for right-to-left or
bidirectional text". The problem is usually due to legacy code, which stores texts
in visual order from left to right. In case of English it&amp;#39;s ok, but with Hebrew
this means that texts are partially reversed.
&lt;/p&gt;
&lt;p&gt;
It worth to note that we've solved the same task with Windows API for native and .NET
applications more than 10 years ago.
&lt;/p&gt;
&lt;p&gt;
On the other hand, for Java, we yet didn't see any acceptable standalone solution.
To remedy this omission, we publish here our solution to this problem.
&lt;/p&gt;
&lt;pre&gt;&lt; count; i++)
    {
       levels[i] = (byte)bidi.getRunLevel(i);
       runs[i] = i;
    }
  
    Bidi.reorderVisually(levels, 0, runs, 0, count);

    StringBuilder result = new StringBuilder();

    for (int i = 0; i &lt; count; i++)
    {
       int index = runs[i];
       int start = bidi.getRunStart(index);
       int end = bidi.getRunLimit(index);
       int level = levels[index];
  
       if ((level &amp; 1) != 0)
       {
         for (; --end &gt;
package com.nesterovskyBros.text;

import java.text.Bidi;

/**
 * Utility that uses {@link Bidi} class. 
 */
public class BidiUtils
{
  /**
   * Implements visual to logical order converter.
   * 
   * @author &amp;lt;a href="http://www.nesterovsky-bros.com"&gt;Nesterovsky bros&amp;lt;/a&gt;
   *
   * @param text an input text in visual order to convert.
   * @return a String value in logical order.
   */
  public static String visualToLogical(String text)
  {
    if ((text == null) || (text.length() == 0))
    {
        return text;
    }
  
    Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
  
    if (bidi.isLeftToRight())
    {
        return text;
    }
  
    int count = bidi.getRunCount();
    byte[] levels = new byte[count];
    Integer[] runs = new Integer[count];
  
    for (int i = 0; i = start;)
         {
           result.append(text.charAt(end));
         }
       }
       else
       {
         result.append(text, start, end);
       }
    }

    return result.toString();
  }
}
  &lt;/pre&gt;
&lt;p&gt;
This method utilizes embeded Bidi&amp;#39;s algorithm, see class &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/text/Bidi.html"&gt;java.text.Bidi&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Be aware that there is no perfect algorithm that covers all possible cases, since
BIDI was written for an opposite task, but our implementation based on &lt;code&gt;Bidi.reorderVisually&lt;/code&gt; is
usually acceptable.
&lt;/p&gt;
&lt;p&gt;
Here is an JUnit test for this method:
&lt;/p&gt;
&lt;pre&gt;
package com.nesterovskyBors.text;

import static org.junit.Assert.*;

import org.junit.Test;

import com.nesterovskyBros.text.BidiUtils;

public class BidiUtilsTests
{

  @Test
  public void testsVisualToLogical()
  {
    String text = "123 יתימאה ןחבמ";
    String actual = BidiUtils.visualToLogical(text);
    String expected = "מבחן האמיתי 123";
  
    assertEquals(expected, actual);
    
    text = "תירבע English תירבע בוש";
    actual = BidiUtils.visualToLogical(text);
    expected = "שוב עברית English עברית";
    
    assertEquals(expected, actual);
  }
}
  &lt;/pre&gt;&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7f76695c-3bef-460f-befd-3ae983809d74" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7f76695c-3bef-460f-befd-3ae983809d74.aspx</comments>
      <category>Java</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c96c3810-95d1-46bd-b413-7fac0cdbf509</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c96c3810-95d1-46bd-b413-7fac0cdbf509.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c96c3810-95d1-46bd-b413-7fac0cdbf509.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c96c3810-95d1-46bd-b413-7fac0cdbf509</wfw:commentRss>
      <title>Kendo progress utility</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c96c3810-95d1-46bd-b413-7fac0cdbf509.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/05/28/KendoProgressUtility.aspx</link>
      <pubDate>Tue, 28 May 2013 05:54:52 GMT</pubDate>
      <description>  &lt;p&gt;
While developing with KendoUI we have found &lt;code&gt;kendo.ui.progress(container, toggle)&lt;/code&gt; function
to be very useful. It's used to show or hide a progress indicator in the container
element.
&lt;/p&gt;
&lt;p&gt;
At the same time we have found that we usually used it in a context of async operation.
This way, we want to show progress, perform some asynchronous operations, hide progress.
So, we clearly want to benifit from &lt;a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization"&gt; RAII&lt;/a&gt; pattern:
we would like to open a progress scope, and to perform some activity withing this
scope.
&lt;/p&gt;
&lt;p&gt;
Arguing like this, we have defined a utility function, which is the fusion of &lt;code&gt;kendo.ui.progress()&lt;/code&gt; and &lt;code&gt;$.when()&lt;/code&gt;.
Its signature is like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;nesterovskyBros.progress = function(instance /*, task ... */)&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;instance&lt;/code&gt; is either &lt;code&gt;Model&lt;/code&gt;, &lt;code&gt;Widget&lt;/code&gt;, &lt;code&gt;JQuery&lt;/code&gt; or
DOM &lt;code&gt;Element&lt;/code&gt;, and &lt;code&gt;task&lt;/code&gt; is one or more deferred objects. This
function shows a progress and returns a &lt;code&gt;Promise&lt;/code&gt; that will hide a progress
when all tasks will be complete. Implementation is trivial, so we quote it here:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;// Fusion of kendo.ui.progress() and $.when().&lt;br /&gt;
scope.progress = function(instance /*, task ... */)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; if (instance instanceof Model)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; instance = instance.owner &amp;&amp; instance.owner();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (instance instanceof Widget)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; instance = instance.element;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (instance &amp;&amp; instance.nodeType)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; instance = $(instance);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; var id = ns + "-progress"; // "nesterovskyBros-progress";&lt;br /&gt;
&amp;nbsp; var progress = (instance &amp;&amp; instance.data(id)) || 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (arguments.length &amp;lt; 2)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return progress;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; var result = $.when.apply(null, [].slice.call(arguments, 1));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (instance)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; instance.data(id, ++progress);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; kendo.ui.progress(instance, progress &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; result.always(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; progress = instance.data(id) || 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance.data(id, --progress);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; kendo.ui.progress(instance, progress &amp;gt;
0);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return result;&lt;br /&gt;
}; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The use is like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;nesterovskyBros.progress(element, $.ajax("/service1"), $.ajax("/service2")).then(myFunc);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The code can be found at &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls.js"&gt; controls.js&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c96c3810-95d1-46bd-b413-7fac0cdbf509" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c96c3810-95d1-46bd-b413-7fac0cdbf509.aspx</comments>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=04f31825-657d-470b-9223-bb1e8961fc9d</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,04f31825-657d-470b-9223-bb1e8961fc9d.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,04f31825-657d-470b-9223-bb1e8961fc9d.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=04f31825-657d-470b-9223-bb1e8961fc9d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While trying to generalize our practices from KendoUI related projects we've participated
so far, we updated <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"> control.js</a> -
a small javascript additions to KendoUI.
</p>
        <p>
At present we have defined:
</p>
        <p>
1. An extended model. See <a href="2013/04/03/KendoUIExtendedModel.aspx" rel="bookmark">KendoUI
extended model</a>. 
</p>
        <p>
2. A lightweight user control - a widget to bind a template and a model, and to facilitate
declarative instantiation. See <a href="2013/03/26/KendoUIUserControl.aspx" rel="bookmark">KendoUI
User control</a>. 
</p>
        <p>
3. A reworked version of nesterovskyBros.defineControl() function. 
</p>
        <p style="padding-left: 1em">
          <code>var widgetType = scope.defineControl(<br />
{<br />
   name: widget-name-string,<br />
   model: widget-model-type,<br />
   template: optional-content-template,<br />
   windowOptions: optional-window-options<br />
},<br />
base);</code>
        </p>
        <p>
When <code>optional-content-template</code> is not specified then template is calculated
as following:
</p>
        <p style="padding-left: 1em">
          <code> var template = options.temlate || proto.template || model.temlate;<br /><br />
if (template === undefined) 
<br />
{<br />
  template = scope.template(options.name.toLowerCase() + "-template"); 
<br />
} </code>
        </p>
        <p>
When <code>windowOptions</code> is specified then <code>widgetType.dialog(options)</code> function
is defined. It's used to open dialog based on the specified user control. <code>windowOptions</code> is
passed to <code>kendo.ui.Window</code> constructor. <code>windowOptions.closeOnEscape</code> indicates
whether to close opened dialog on escape.
</p>
        <p>
          <code>widgetType.dialog()</code> returns a <code>kendo.ui.Window</code> instance with
content based on the user control. Window instance contains functions: 
</p>
        <ul>
          <li>
            <code>result()</code> - a <code>$.Deffered</code> for the dialog result, and 
</li>
          <li>
            <code>model()</code> - referring to the user control model. 
</li>
        </ul>
        <p>
 The model instance has functions:
</p>
        <ul>
          <li>
 <code>dialog()</code> referring to the dialog, and 
</li>
          <li>
            <code>result()</code> referring to the dialog result.</li>
        </ul>
        <p>
          <code>widget.dialog()</code> allows all css units in <code>windowOptions.width</code> and <code>windowOptions.height</code> parameters.
</p>
        <p>
          <code>base</code> - is optional user control base. It defaults to <code>nesterovskyBros.ui.UserControl</code>.
</p>
        <p>
4. Adjusted splitter. See <a href="2013/05/14/AdjustKendoUISplitter.aspx" rel="bookmark">Adjust
KendoUI Splitter</a>.
</p>
        <p>
5. Auto resize support.
</p>
        <p>
Layout is often depends on available area. One example is <code>Splitter</code> widget
that recalculates its panes when window or container <code>Splitter</code> is resized.
There are other cases when you would like to adjust layout when a container's
area is changed like: adjust grid, tab, editor or user's control contents.
</p>
        <p>
KendoUI does not provide a solution for this problem, so we have defined our own.
</p>
        <ul>
          <li>
A widget can be marked with <code>class="auto-resize"</code> marker;</li>
          <li>
A widget may define a <code>widgetType.autoResize(element)</code> function that adapts
widget to a new size.</li>
          <li>
A code can call <code>nesterovskyBros.resize(element)</code> function at trigger resizing
of the subtree.</li>
        </ul>
        <p>
To support existing controls we have defined <code>autoResize()</code> function for <code>Grid</code>, <code>Splitter</code>, <code>TabStrip</code>,
and <code>Editor</code> widgets.
</p>
        <p>
To see how auto resizing works, it's best to look into <a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html">index.html</a>, <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/products.tmpl.html"> products.tmpl.html</a>,
and into the implementation <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"> controls.js</a>.
</p>
        <p>
Please note that we consider <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"> controls.js</a> as
an addition to KendoUI library. If in the future the library will integrate or implement
similar features we will be happy to start using their API.
</p>
        <p>
See also: <a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx">Compile
KendoUI templates</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=04f31825-657d-470b-9223-bb1e8961fc9d" />
      </body>
      <title>KendoUI controls.js</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,04f31825-657d-470b-9223-bb1e8961fc9d.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/05/18/KendoUIControlsjs.aspx</link>
      <pubDate>Sat, 18 May 2013 10:59:36 GMT</pubDate>
      <description>  &lt;p&gt;
While trying to generalize our practices from KendoUI related projects we've participated
so far, we updated &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"&gt; control.js&lt;/a&gt; -
a small javascript additions to KendoUI.
&lt;/p&gt;
&lt;p&gt;
At present we have defined:
&lt;/p&gt;
&lt;p&gt;
1. An extended model. See &lt;a href="2013/04/03/KendoUIExtendedModel.aspx" rel="bookmark"&gt;KendoUI
extended model&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
2. A lightweight user control - a widget to bind a template and a model, and to facilitate
declarative instantiation. See &lt;a href="2013/03/26/KendoUIUserControl.aspx" rel="bookmark"&gt;KendoUI
User control&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
3. A reworked version of nesterovskyBros.defineControl() function. 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;var widgetType = scope.defineControl(&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; name: widget-name-string,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; model: widget-model-type,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; template: optional-content-template,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; windowOptions: optional-window-options&lt;br /&gt;
},&lt;br /&gt;
base);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
When &lt;code&gt;optional-content-template&lt;/code&gt; is not specified then template is calculated
as following:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var template = options.temlate || proto.template || model.temlate;&lt;br /&gt;
&lt;br /&gt;
if (template === undefined) 
&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; template = scope.template(options.name.toLowerCase() + "-template"); 
&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
When &lt;code&gt;windowOptions&lt;/code&gt; is specified then &lt;code&gt;widgetType.dialog(options)&lt;/code&gt; function
is defined. It&amp;#39;s used to open dialog based on the specified user control. &lt;code&gt;windowOptions&lt;/code&gt; is
passed to &lt;code&gt;kendo.ui.Window&lt;/code&gt; constructor. &lt;code&gt;windowOptions.closeOnEscape&lt;/code&gt; indicates
whether to close opened dialog on escape.
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;widgetType.dialog()&lt;/code&gt; returns a &lt;code&gt;kendo.ui.Window&lt;/code&gt; instance with
content based on the user control. Window instance contains functions: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;result()&lt;/code&gt; - a &lt;code&gt;$.Deffered&lt;/code&gt; for the dialog result, and 
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model()&lt;/code&gt; - referring to the user control model. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;nbsp;The model instance has functions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&amp;nbsp;&lt;code&gt;dialog()&lt;/code&gt; referring to the dialog, and 
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;result()&lt;/code&gt; referring to the dialog result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;code&gt;widget.dialog()&lt;/code&gt; allows all css units in &lt;code&gt;windowOptions.width&lt;/code&gt; and &lt;code&gt;windowOptions.height&lt;/code&gt; parameters.
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;base&lt;/code&gt; - is optional user control base. It defaults to &lt;code&gt;nesterovskyBros.ui.UserControl&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
4. Adjusted splitter. See &lt;a href="2013/05/14/AdjustKendoUISplitter.aspx" rel="bookmark"&gt;Adjust
KendoUI Splitter&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
5. Auto resize support.
&lt;/p&gt;
&lt;p&gt;
Layout is often depends on available area. One example is &lt;code&gt;Splitter&lt;/code&gt; widget
that recalculates its panes when window or container &lt;code&gt;Splitter&lt;/code&gt; is resized.
There are other cases when you would like to adjust layout when a container&amp;#39;s
area is changed like: adjust grid, tab, editor or user&amp;#39;s control contents.
&lt;/p&gt;
&lt;p&gt;
KendoUI does not provide a solution for this problem, so we have defined our own.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A widget can be marked with &lt;code&gt;class=&amp;quot;auto-resize&amp;quot;&lt;/code&gt; marker;&lt;/li&gt;
&lt;li&gt;
A widget may define a &lt;code&gt;widgetType.autoResize(element)&lt;/code&gt; function that adapts
widget to a new size.&lt;/li&gt;
&lt;li&gt;
A code can call &lt;code&gt;nesterovskyBros.resize(element)&lt;/code&gt; function at trigger resizing
of the subtree.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To support existing controls we have defined &lt;code&gt;autoResize()&lt;/code&gt; function for &lt;code&gt;Grid&lt;/code&gt;, &lt;code&gt;Splitter&lt;/code&gt;, &lt;code&gt;TabStrip&lt;/code&gt;,
and &lt;code&gt;Editor&lt;/code&gt; widgets.
&lt;/p&gt;
&lt;p&gt;
To see how auto resizing works, it&amp;#39;s best to look into &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html"&gt;index.html&lt;/a&gt;, &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/products.tmpl.html"&gt; products.tmpl.html&lt;/a&gt;,
and into the implementation &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"&gt; controls.js&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Please note that we consider &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"&gt; controls.js&lt;/a&gt; as
an addition to KendoUI library. If in the future the library will integrate or implement
similar features we will be happy to start using their API.
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx"&gt;Compile
KendoUI templates&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=04f31825-657d-470b-9223-bb1e8961fc9d" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,04f31825-657d-470b-9223-bb1e8961fc9d.aspx</comments>
      <category>Announce</category>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9b30445a-be57-4140-a839-fab46b42c76e</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9b30445a-be57-4140-a839-fab46b42c76e.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9b30445a-be57-4140-a839-fab46b42c76e.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9b30445a-be57-4140-a839-fab46b42c76e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We heavily use kendo.ui.Splitter widget. Unfortunately it has several drawbacks:
</p>
        <ul>
          <li>
you cannot easily configure panes declaratively;</li>
          <li>
you cannot define a pane that takes space according to its content.</li>
        </ul>
        <p>
Although we don't like to patch widgets, in this case we found no better way but
to patch two functions: <code>kendo.ui.Splitter.fn._initPanes</code>, and  <code>kendo.ui.Splitter.fn._resize</code>.
</p>
        <p>
After the fix, splitter markup may look like the following:
</p>
        <p style="padding-left: 1em">
          <code> &lt;div style="height: 100%" data-role="splitter" data-orientation="vertical"&gt;<br />
  &lt;div <strong>data-pane</strong>='{ size: "<strong>auto</strong>",
resizable: false, scrollable: false }'&gt;<br />
    Header with size depending on content.<br />
  &lt;/div&gt;<br />
  &lt;div data-pane='{ resizable: false, scrollable: true }'&gt;<br />
    Body with size equal to a remaining area.<br />
  &lt;/div&gt;<br />
  &lt;div data-pane='{ size: "auto", resizable: false, scrollable: false }'&gt;<br />
    Footer with size depending on content.<br />
  &lt;/div&gt;<br />
&lt;/div&gt;</code>
        </p>
        <p>
Each pane may define a <code>data-pane</code> attribute with pane parameters. A pane
may specify <code>size = "auto"</code> to take space according to its content.
</p>
        <p>
The code can be found at <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/splitter.js"> splitter.js</a> A
test can be seen at <a href="http://www.nesterovsky-bros.com/download/KendoUI/splitter.html"> splitter.html</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9b30445a-be57-4140-a839-fab46b42c76e" />
      </body>
      <title>Adjust KendoUI Splitter</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9b30445a-be57-4140-a839-fab46b42c76e.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/05/14/AdjustKendoUISplitter.aspx</link>
      <pubDate>Tue, 14 May 2013 07:34:59 GMT</pubDate>
      <description>&lt;p&gt;
We heavily use kendo.ui.Splitter widget. Unfortunately it has several drawbacks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
you cannot easily configure panes declaratively;&lt;/li&gt;
&lt;li&gt;
you cannot define a pane that takes space according to its content.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Although we don&amp;#39;t like to patch widgets, in this case we found no better way but
to patch two functions: &lt;code&gt;kendo.ui.Splitter.fn._initPanes&lt;/code&gt;, and&amp;nbsp; &lt;code&gt;kendo.ui.Splitter.fn._resize&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
After the fix, splitter markup may look like the following:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;div style=&amp;quot;height: 100%&amp;quot; data-role="splitter" data-orientation="vertical"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div &lt;strong&gt;data-pane&lt;/strong&gt;=&amp;#39;{ size: &amp;quot;&lt;strong&gt;auto&lt;/strong&gt;&amp;quot;,
resizable: false, scrollable: false }&amp;#39;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Header with size depending on content.&lt;br /&gt;
&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div data-pane='{ resizable: false, scrollable: true }'&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Body with size equal to a remaining area.&lt;br /&gt;
&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div data-pane='{ size: "auto", resizable: false, scrollable: false }'&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Footer with size depending on content.&lt;br /&gt;
&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Each pane may define a &lt;code&gt;data-pane&lt;/code&gt; attribute with pane parameters. A pane
may specify &lt;code&gt;size = &amp;quot;auto&amp;quot;&lt;/code&gt; to take space according to its content.
&lt;/p&gt;
&lt;p&gt;
The code can be found at &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/splitter.js"&gt; splitter.js&lt;/a&gt; A
test can be seen at &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/splitter.html"&gt; splitter.html&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9b30445a-be57-4140-a839-fab46b42c76e" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9b30445a-be57-4140-a839-fab46b42c76e.aspx</comments>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p style="direction: ltr">
Although WCF REST service + JSON is outdated comparing to Web API, there are yet a
lot of such solutions (and probably will appear new ones) that use such "old"
technology. 
</p>
        <p>
One of the crucial points of any web application is an error handler that allows gracefully
resolve server-side exceptions and routes them as JSON objects to the client for further
processing. There are dozen approachesin Internet that solve this issue  (e.g. <a href="http://blog.manglar.com/how-to-provide-custom-json-exceptions-from-as-wcf-service/">http://blog.manglar.com/how-to-provide-custom-json-exceptions-from-as-wcf-service/</a>),
but there is no one that demonstrates error handling ot the client-side. We realize
that it's impossible to write something general that suits for every web application,
but we'd like to show a client-side error handler that utilizes JSON and KendoUI.
</p>
        <p style="direction: ltr">
On our opinion, the successfull error handler must display an understandable error
message on one hand, and on the other hand it has to provide technical info for developers
in order to investigate the exception reason (and to fix it, if need):
</p>
        <table border="0">
          <tr>
            <td style="vertical-align: top;">
              <a href="http://www.nesterovsky-bros.com/images/colapsed-error-dialog.png">
                <img src="http://www.nesterovsky-bros.com/images/thumb-colapsed-error-dialog.png" alt="collapsed error dialog" />
              </a>
            </td>
            <td>
              <a href="http://www.nesterovsky-bros.com/images/expanded-error-dialog.png">
                <img src="http://www.nesterovsky-bros.com/images/thumb-expanded-error-dialog.png" alt="collapsed error dialog" />
              </a>
            </td>
          </tr>
        </table>
        <p>
You may <a href="http://www.nesterovsky-bros.com/download/ErrorHandling.zip">download
demo project here</a>. It contains three crucial parts:
</p>
        <ul>
          <li>
A server-side error handler that catches all exceptions and serializes them as JSON
objects (see <strong>/Code/JsonErrorHandler.cs</strong> and <strong>/Code/JsonWebHttpBehaviour.cs</strong>).</li>
          <li>
An error dialog that's based on user-control defined in previous articles (see <strong>/scripts/controls/error.js</strong>,<strong> /scripts/controls/error.resources.js</strong> and <strong>/scripts/templates/error.tmpl.html</strong>).</li>
          <li>
A client-side error handler that displays errors in user-friendly's manner (see <strong>/scripts/api/api.js</strong>,
method <strong>defaultErrorHandler()</strong>).</li>
        </ul>
        <p>
Of course this is only a draft solution, but it defines a direction for further customizations
in your web applications.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f" />
      </body>
      <title>Error handling in WCF based web applications</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/05/13/ErrorHandlingInWCFBasedWebApplications.aspx</link>
      <pubDate>Mon, 13 May 2013 23:09:02 GMT</pubDate>
      <description>   &lt;p style="direction: ltr"&gt;
Although WCF REST service + JSON is outdated comparing to Web API, there are yet a
lot of such solutions (and probably will appear new ones) that use such &amp;quot;old&amp;quot;
technology. 
&lt;/p&gt;
&lt;p&gt;
One of the crucial points of any web application is an error handler that allows gracefully
resolve server-side exceptions and routes them as JSON objects to the client for further
processing. There are dozen approachesin Internet that solve this issue&amp;nbsp; (e.g. &lt;a href="http://blog.manglar.com/how-to-provide-custom-json-exceptions-from-as-wcf-service/"&gt;http://blog.manglar.com/how-to-provide-custom-json-exceptions-from-as-wcf-service/&lt;/a&gt;),
but there is no one that demonstrates error handling ot the client-side. We realize
that it&amp;#39;s impossible to write something general that suits for every web application,
but we&amp;#39;d like to show a client-side error handler that utilizes JSON and KendoUI.
&lt;/p&gt;
&lt;p style="direction: ltr"&gt;
On our opinion, the successfull error handler must display an understandable error
message on one hand, and on the other hand it has to provide technical info for developers
in order to investigate the exception reason (and to fix it, if need):
&lt;/p&gt;
&lt;table border="0"&gt;
&lt;tr&gt;
&lt;td style="vertical-align: top;"&gt;
&lt;a href="http://www.nesterovsky-bros.com/images/colapsed-error-dialog.png"&gt; &lt;img src="http://www.nesterovsky-bros.com/images/thumb-colapsed-error-dialog.png" alt="collapsed error dialog" /&gt; &lt;/a&gt; 
&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://www.nesterovsky-bros.com/images/expanded-error-dialog.png"&gt; &lt;img src="http://www.nesterovsky-bros.com/images/thumb-expanded-error-dialog.png" alt="collapsed error dialog" /&gt; &lt;/a&gt; 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
You may &lt;a href="http://www.nesterovsky-bros.com/download/ErrorHandling.zip"&gt;download
demo project here&lt;/a&gt;. It contains three crucial parts:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A server-side error handler that catches all exceptions and serializes them as JSON
objects (see &lt;strong&gt;/Code/JsonErrorHandler.cs&lt;/strong&gt; and &lt;strong&gt;/Code/JsonWebHttpBehaviour.cs&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
An error dialog that&amp;#39;s based on user-control defined in previous articles (see &lt;strong&gt;/scripts/controls/error.js&lt;/strong&gt;,&lt;strong&gt; /scripts/controls/error.resources.js&lt;/strong&gt; and &lt;strong&gt;/scripts/templates/error.tmpl.html&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
A client-side error handler that displays errors in user-friendly&amp;#39;s manner (see &lt;strong&gt;/scripts/api/api.js&lt;/strong&gt;,
method &lt;strong&gt;defaultErrorHandler()&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Of course this is only a draft solution, but it defines a direction for further customizations
in your web applications.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,3af8fe47-6f58-4e53-b4e8-6ee5a9203c2f.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7a17cd30-d829-4b17-946a-a4da45143faa</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7a17cd30-d829-4b17-946a-a4da45143faa.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7a17cd30-d829-4b17-946a-a4da45143faa.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7a17cd30-d829-4b17-946a-a4da45143faa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Useful links to those who are still dealing with Cool:GEN.
</p>
        <ul>
          <li>
            <a href="http://www.iet.co.uk/">Information Engineering Technology</a>
          </li>
          <li>
            <a href="http://ietgen.blogspot.co.uk/">IET Gen Development Blog</a>
          </li>
        </ul>
        <p>
The site is not cool by itself, but the value is in the tools that authors provide
to simplify Cool:GEN development. Especially we would like to mention:
</p>
        <ul>
          <li>
GuardIEn - Version control, change and model management and automated builds for CA
Gen, and</li>
          <li>
VerifIEr - Automated code checking and standards verification.</li>
        </ul>
        <p>
These tools help to manage clean and error free models, which simplifies next migration
to Java and C# that we perform.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7a17cd30-d829-4b17-946a-a4da45143faa" />
      </body>
      <title>Cool:GEN links</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7a17cd30-d829-4b17-946a-a4da45143faa.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/04/29/CoolGENLinks.aspx</link>
      <pubDate>Mon, 29 Apr 2013 03:54:56 GMT</pubDate>
      <description>&lt;p&gt;
Useful links to those who are still dealing with Cool:GEN.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.iet.co.uk/"&gt;Information Engineering Technology&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://ietgen.blogspot.co.uk/"&gt;IET Gen Development Blog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The site is not cool by itself, but the value is in the tools that authors provide
to simplify Cool:GEN development. Especially we would like to mention:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
GuardIEn - Version control, change and model management and automated builds for CA
Gen, and&lt;/li&gt;
&lt;li&gt;
VerifIEr - Automated code checking and standards verification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
These tools help to manage clean and error free models, which simplifies next migration
to Java and C# that we perform.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7a17cd30-d829-4b17-946a-a4da45143faa" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7a17cd30-d829-4b17-946a-a4da45143faa.aspx</comments>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=3e27a213-6843-4ad2-b603-6bc29f0ea3e0</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3e27a213-6843-4ad2-b603-6bc29f0ea3e0.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,3e27a213-6843-4ad2-b603-6bc29f0ea3e0.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=3e27a213-6843-4ad2-b603-6bc29f0ea3e0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
To simplify KendoUI development we have defined <code>nesterovskyBros.data.Model</code>,
which extends <code>kend.data.Model</code> class. 
</p>
        <h3>Extensions in <code>nesterovskyBros.data.Model</code></h3>
        <ol>
          <li>
As with <code>kendo.data.Model</code> there is <code>fields</code> Object - a set
of key/value pairs to configure the model fields, but fields have some more options: 
<ul><li><code>fields.fieldName.serializable Boolean</code> - indicates whether the field appears
in an object returned in <code>model.toJSON()</code>. Default is <code>true</code>.</li><li><code>fields.fieldName.updateDirty Boolean</code> - indicates whether the change of
the property should trigger <code>dirty</code> field change. Default is <code>true</code>.</li></ul></li>
          <li>
When model defines a field and there is a prototype function with the same name then
this function is used to get and set a field value.</li>
          <li>
When property is changed through the <code>model.set()</code> method then <code>dirty</code> change
event is triggered (provided that fields.fieldName.updateDirty !== false). This helps
to build a dependcy graph on that property.</li>
          <li>
When model instance is consturcted, the data passed in are validated, nullable and
default values are set.</li>
        </ol>
        <h3>Model example
</h3>
        <p>
Here is an example of a model:
</p>
        <p style="padding-left: 1em">
          <code>nesterovskyBros.data.ProductModel = nesterovskyBros.data.Model.define(<br />
{<br /><br />
fields:<br />
{<br />
  name: { type: "string", defaultValue: "Product Name" },<br />
  price: { type: "number", defaultValue: 10 },<br />
  unitsInStockValue: { type: "number", defaultValue: 10, serializable: false
},<br />
  unitsInStock: { type: "string" }<br />
},<br /><br />
unitsInStock: function(value)<br />
{<br />
  if (value === undefined)<br />
  {<br />
    var count = this.get("unitsInStockValue");<br /><br />
    return ["one", "two", "three", "four"][count] || (count + "");<br />
  }<br />
  else<br />
  {<br />
    this.set("unitsInStockValue", ({one: 1, two: 2, three: 3, four:
4 })[value] || value);<br />
  }<br />
}<br /><br />
}); </code>
        </p>
        <p>
Notice that:
</p>
        <ul>
          <li>
            <code>unitsInStock</code> property is implemented as a function - this helps to map
model values to presentation values. 
</li>
          <li>
when you call <code>model.toJSON()</code>, or <code>JSON.stringify()</code> you will
see in result <code>name</code>, <code>price</code>, <code>unitsInStock</code> values
only - this helps to get model's state and to store it somewhere (e.g. in <code>sessionStorage</code>).</li>
          <li>
in a code:<br /><code>  var model = new nesterovskyBros.data.ProductModel({ price: "7",
unitsInStock: "one" });</code><br />
the following is true: 
<br /><code>  (typeof(model.price) == "number") &amp;&amp; (mode.price ==
7) &amp;&amp; (model.name == "Product Name") &amp;&amp; (model.unitsInStockValue
== 1)</code></li>
        </ul>
        <p>
As with <a href="http://www.nesterovsky-bros.com/weblog/2013/03/26/KendoUIUserControl.aspx">UserControl</a> the
implemntation is defined in the <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js">controls.js</a>.
The sample page is the same <a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html">index.html</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3e27a213-6843-4ad2-b603-6bc29f0ea3e0" />
      </body>
      <title>KendoUI extended model</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3e27a213-6843-4ad2-b603-6bc29f0ea3e0.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/04/03/KendoUIExtendedModel.aspx</link>
      <pubDate>Wed, 03 Apr 2013 20:37:49 GMT</pubDate>
      <description>  &lt;p&gt;
To simplify KendoUI development we have defined &lt;code&gt;nesterovskyBros.data.Model&lt;/code&gt;,
which extends &lt;code&gt;kend.data.Model&lt;/code&gt; class. 
&lt;/p&gt;
&lt;h3&gt;Extensions in &lt;code&gt;nesterovskyBros.data.Model&lt;/code&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
As with &lt;code&gt;kendo.data.Model&lt;/code&gt; there is &lt;code&gt;fields&lt;/code&gt; Object - a set
of key/value pairs to configure the model fields, but fields have some more options: 
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fields.fieldName.serializable Boolean&lt;/code&gt; - indicates whether the field appears
in an object returned in &lt;code&gt;model.toJSON()&lt;/code&gt;. Default is &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fields.fieldName.updateDirty Boolean&lt;/code&gt; - indicates whether the change of
the property should trigger &lt;code&gt;dirty&lt;/code&gt; field change. Default is &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
When model defines a field and there is a prototype function with the same name then
this function is used to get and set a field value.&lt;/li&gt;
&lt;li&gt;
When property is changed through the &lt;code&gt;model.set()&lt;/code&gt; method then &lt;code&gt;dirty&lt;/code&gt; change
event is triggered (provided that fields.fieldName.updateDirty !== false). This helps
to build a dependcy graph on that property.&lt;/li&gt;
&lt;li&gt;
When model instance is consturcted, the data passed in are validated, nullable and
default values are set.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Model example
&lt;/h3&gt;
&lt;p&gt;
Here is an example of a model:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;nesterovskyBros.data.ProductModel = nesterovskyBros.data.Model.define(&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
fields:&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; name: { type: "string", defaultValue: "Product Name" },&lt;br /&gt;
&amp;nbsp; price: { type: "number", defaultValue: 10 },&lt;br /&gt;
&amp;nbsp; unitsInStockValue: { type: "number", defaultValue: 10, serializable: false
},&lt;br /&gt;
&amp;nbsp; unitsInStock: { type: "string" }&lt;br /&gt;
},&lt;br /&gt;
&lt;br /&gt;
unitsInStock: function(value)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; if (value === undefined)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var count = this.get("unitsInStockValue");&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return ["one", "two", "three", "four"][count] || (count + "");&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; else&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this.set("unitsInStockValue", ({one: 1, two: 2, three: 3, four:
4 })[value] || value);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}); &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Notice that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;unitsInStock&lt;/code&gt; property is implemented as a function - this helps to map
model values to presentation values. 
&lt;/li&gt;
&lt;li&gt;
when you call &lt;code&gt;model.toJSON()&lt;/code&gt;, or &lt;code&gt;JSON.stringify()&lt;/code&gt; you will
see in result &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;unitsInStock&lt;/code&gt; values
only - this helps to get model&amp;#39;s state and to store it somewhere (e.g. in &lt;code&gt;sessionStorage&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
in a code:&lt;br /&gt;
&lt;code&gt;&amp;nbsp; var model = new nesterovskyBros.data.ProductModel({ price: &amp;quot;7&amp;quot;,
unitsInStock: &amp;quot;one&amp;quot; });&lt;/code&gt; 
&lt;br /&gt;
the following is true: 
&lt;br /&gt;
&lt;code&gt;&amp;nbsp; (typeof(model.price) == &amp;quot;number&amp;quot;) &amp;amp;&amp;amp; (mode.price ==
7) &amp;amp;&amp;amp; (model.name == &amp;quot;Product Name&amp;quot;) &amp;amp;&amp;amp; (model.unitsInStockValue
== 1)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As with &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/03/26/KendoUIUserControl.aspx"&gt;UserControl&lt;/a&gt; the
implemntation is defined in the &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/api/controls.js"&gt;controls.js&lt;/a&gt;.
The sample page is the same &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html"&gt;index.html&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3e27a213-6843-4ad2-b603-6bc29f0ea3e0" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,3e27a213-6843-4ad2-b603-6bc29f0ea3e0.aspx</comments>
      <category>javascript</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=f4337446-1b5e-4007-a1f8-a62b9d99681f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f4337446-1b5e-4007-a1f8-a62b9d99681f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=f4337446-1b5e-4007-a1f8-a62b9d99681f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Developing with KendoUI we try to formalize tasks. With this in mind we would like
to have user controls. 
</p>
        <p>
We define user control as following:
</p>
        <p style="padding-left: 1em">
It is a javascript class that extends Widget.<br />
It offers a way to reuse UI.<br />
It allows to define a model and a template with UI and data binding.
</p>
        <p>
Unfortunately, KendoUI does not have such API, though one can easily define it; so
we have defined our version.
</p>
        <p>
Here we review our solution. We have taken a grid KendoUI example and converted it
into a user control.
</p>
        <h3 style="direction: ltr">User control on the page
</h3>
        <p style="direction: ltr">
See <a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html">index.html</a></p>
        <p style="padding-left: 1em">
          <code style="direction: ltr">&lt;!DOCTYPE html&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
  &lt;title&gt;Test&lt;/title&gt;<br /><br />
  <strong>&lt;!-- (1) Include templates for controls. --&gt;</strong><br />
  &lt;script src="<a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.js">scripts/templates.js</a>"&gt;&lt;/script&gt;<br /><br />
  &lt;script src="scripts/jquery/jquery.js"&gt;&lt;/script&gt;<br />
  &lt;script src="scripts/kendo/kendo.web.min.js"&gt;&lt;/script&gt;<br /><br />
  <strong>&lt;!-- (2) UserControl definition. --&gt;</strong><br />
  &lt;script src="<a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls.js">scripts/controls.js</a>"&gt;&lt;/script&gt;<br /><br />
  <strong>&lt;!-- (3) Confirm dialog user control. --&gt;</strong><br />
  &lt;script src="<a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/confirm.js">scripts/controls/confirm.js</a>"&gt;&lt;/script&gt;<br /><br />
  <strong>&lt;!-- (4) Products user control. --&gt;</strong><br />
  &lt;script src="<a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/products.js">scripts/controls/products.js</a>"&gt;&lt;/script&gt;<br /><br />
  &lt;link href="styles/kendo.common.min.css" rel="stylesheet" /&gt;<br />
  &lt;link href="styles/kendo.default.min.css" rel="stylesheet" /&gt;<br />
  &lt;script&gt;<br />
$(function ()<br />
{<br />
  <strong>// (5) Bind the page.</strong><br />
  kendo.bind(<br />
    document.body,<br />
    <strong>// (6) Model as a datasource.</strong><br />
    { source: [new nesterovskyBros.data.ProductsModel] });<br />
});<br />
  &lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
  <strong>&lt;!-- (7) User control and its binding. --&gt;</strong><br />
  &lt;div data-role="<strong>products</strong>" data-bind="<strong>source: source</strong>"&gt;&lt;/div&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt; </code>
        </p>
        <p>
That's what we see here:
</p>
        <ol>
          <li>
Templates that define layouts. See "<a href="http://www.nesterovsky-bros.com/weblog/2013/01/06/HowToLoadKendoUITemplatesFromExternalFiles.aspx">How
To: Load KendoUI Templates from External Files</a>", and <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt">templates.tt</a>.</li>
          <li>
Definition of the UserControl widget.</li>
          <li>
Confirm dialog user control (we shall mention it later).</li>
          <li>
Products user control.</li>
          <li>
Data binding that instantiates page controls.</li>
          <li>
Model is passed to a user control through the dataSource.</li>
          <li>
Use of Products user control. Notice that "data-role" defines control type,
"source" refers to the model.</li>
        </ol>
        <h3>User Control declaration
</h3>
        <p>
Declaration consists of a view and a model. 
</p>
        <p>
View is html with data binding. See <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/products.tmpl.html">products.tmpl.html</a></p>
        <p>
We build our project using Visual Studio, so templates packaging is done with <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt">templates.tt</a>.
This transformation converts products template into a tag:
</p>
        <p style="padding-left: 1em">
          <code>&lt;script id="products-template" type="text/x-kendo-template"&gt;</code>
        </p>
        <p>
thus template can be referred by a utility function: <code>nesterovskyBros.template("products-template")</code>.
</p>
        <p>
Model inherits kedo.data.Model. Here how it looks:
</p>
        <p style="padding-left: 1em">
          <code>
            <strong>// (1) Define a ProducsModel class</strong>.<br />
nesterovskyBros.data.ProductsModel = <a href="http://docs.kendoui.com/api/framework/model">kendo.data.Model.define</a>(<br />
{<br /><br /><strong>// (2) Model properties.</strong><br />
fields:<br />
{<br />
  productName: { type: "string", defaultValue: "Product Name" },<br />
  productPrice: { type: "number", defaultValue: 10 },<br />
  productUnitsInStock: { type: "number", defaultValue: 10 },<br />
  products: { type: "default", defaultValue: [] }<br />
},<br /><br /><strong>// (3) Model methods.</strong><br />
addProduct: function () { ... },<br />
deleteProduct: function (e) { ... },<br />
...<br /><br />
});<br /><br /><strong>// (4) Register user control.</strong><br />
nesterovskyBros.ui.Products = nesterovskyBros.defineControl(<br />
{<br />
  name: "Products",<br />
  model: nesterovskyBros.data.ProductsModel<br />
});</code>
        </p>
        <p>
That's what we have here:
</p>
        <ol>
          <li>
We define a model that inherits KendoUI Model.</li>
          <li>
We define model fields.</li>
          <li>
We define model methods.</li>
          <li>
Register user control with  <code>nesterovskyBros.defineControl(proto)</code> call,
where:<br /><ul><li><code>proto.name</code> - defines user control name;</li><li><code>proto.model</code> - defines model type;</li><li><code>proto.template</code> - defines optional template. If not specified, a template
is retrieved from <code>$("#" + proto.name.toLowerCase() + "-template").html()</code>.</li></ul></li>
        </ol>
        <h3>UserControl API
</h3>
        <p>
Now, what's remained is API for the UserControl. See <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls.js">controls.js</a>.
</p>
        <ol>
          <li>
UserControl defines following events:<br /><ul><li><code>change</code> - triggered when data source is changed;</li><li><code>dataBound</code> - triggered when widget is data bound;</li><li><code>dataBinding</code> - triggered befor widget data binding;</li><li><code>save</code> - used to notify user to save model state.</li></ul></li>
          <li>
UserControl defines following options:<br /><ul><li><code>autoBind (default false)</code> - autoBind data source;</li><li><code>template (default $.noop)</code> - user control template.</li></ul></li>
          <li>
UserControl defines <code>dataSource</code> field and <code>setDataSource()</code> method.</li>
          <li>
UserControl defines <code>rebind()</code> method to manually rebuild widget's
view from the template and model.</li>
          <li>
UserControl sets/deletes model.owner, which is a function returning a user control
widget when model is bound/unbound to the widget.</li>
          <li>
When UserControl binds/unbinds model a <code>model.refresh</code> method is called,
if any.</li>
          <li>
You usually define you control with a call <code>nesterovskyBros.defineControl(proto)</code>.
See above.</li>
          <li>
There is also a convenience method to build a dialog based on a user control: nesterovskyBros.defineDialog(options),
where<br /><ul><li><code>options.name</code> - a user control name (used in the data-role);</li><li><code>options.model</code> - a model type;</li><li><code>options.windowOptions</code> - a window options.</li></ul>
This method returns a function that recieves a user control model, and returns a dialog
(<code>kendo.ui.Window</code>) based on the user control.<br />
Dialog has <code>model()</code> function that returns an instance of model.<br />
Model has <code>dialog()</code> function that returns an instance of the dialog.<br />
Dialog and model have <code>result()</code> function that returns an instance of deferred
object used to track dialog completion.<br />
The example of user control dialog is <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/confirm.js">confirm.js</a> and <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/confirm.tmpl.html">confirm.tmpl.html</a>.
The use is in the <a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/products.js">products.js</a> deleteProduct():<br /><p style="padding-left: 1em"><code>deleteProduct: function(e) 
<br />
{<br />
  var that = this;<br /><br />
  return nesterovskyBros.dialog.confirm(<br />
  {<br />
    title: "Please confirm",<br />
    message: "Do you want to delete the record?",<br />
    confirm: "Yes",<br />
    cancel: "No"<br />
  }).<br />
  open().<br />
  center().<br />
  result().<br />
  then(<br />
    function(confirmed)<br />
    {<br />
      if (!confirmed)<br />
      {<br />
        return;<br />
      }<br />
      ...<br />
   });<br />
}</code></p></li>
        </ol>
        <h3>Last
</h3>
        <p>
User controls along with technique to manage and cache templates allow us to build
robust web applications. As the added value it's became a trivial task to build
SPA.
</p>
        <p>
See also: <a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx">Compile
KendoUI templates</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f4337446-1b5e-4007-a1f8-a62b9d99681f" />
      </body>
      <title>KendoUI User control</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f4337446-1b5e-4007-a1f8-a62b9d99681f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/03/26/KendoUIUserControl.aspx</link>
      <pubDate>Tue, 26 Mar 2013 21:40:05 GMT</pubDate>
      <description>  &lt;p&gt;
Developing with KendoUI we try to formalize tasks. With this in mind we would like
to have user controls. 
&lt;/p&gt;
&lt;p&gt;
We define user control as following:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
It is a javascript class that extends Widget.&lt;br /&gt;
It offers a way to reuse UI.&lt;br /&gt;
It allows to define a model and a template with UI and data binding.
&lt;/p&gt;
&lt;p&gt;
Unfortunately, KendoUI does not have such API, though one can easily define it; so
we have defined our version.
&lt;/p&gt;
&lt;p&gt;
Here we review our solution. We have taken a grid KendoUI example and converted it
into a user control.
&lt;/p&gt;
&lt;h3 style="direction: ltr"&gt;User control on the page
&lt;/h3&gt;
&lt;p style="direction: ltr"&gt;
See &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/index.html"&gt;index.html&lt;/a&gt;
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code style="direction: ltr"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;title&amp;gt;Test&amp;lt;/title&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;&amp;lt;!-- (1) Include templates for controls. --&amp;gt;&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="&lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.js"&gt;scripts/templates.js&lt;/a&gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="scripts/jquery/jquery.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="scripts/kendo/kendo.web.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;&amp;lt;!-- (2) UserControl definition. --&amp;gt;&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="&lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls.js"&gt;scripts/controls.js&lt;/a&gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;&amp;lt;!-- (3) Confirm dialog user control. --&amp;gt;&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="&lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/confirm.js"&gt;scripts/controls/confirm.js&lt;/a&gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;&amp;lt;!-- (4) Products user control. --&amp;gt;&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;script src="&lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/products.js"&gt;scripts/controls/products.js&lt;/a&gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;link href="styles/kendo.common.min.css" rel="stylesheet" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;link href="styles/kendo.default.min.css" rel="stylesheet" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;script&amp;gt;&lt;br /&gt;
$(function ()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;// (5) Bind the page.&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; kendo.bind(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; document.body,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;// (6) Model as a datasource.&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { source: [new nesterovskyBros.data.ProductsModel] });&lt;br /&gt;
});&lt;br /&gt;
&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;&amp;lt;!-- (7) User control and its binding. --&amp;gt;&lt;/strong&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;div data-role="&lt;strong&gt;products&lt;/strong&gt;" data-bind="&lt;strong&gt;source: source&lt;/strong&gt;"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s what we see here:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Templates that define layouts. See &amp;quot;&lt;a href="http://www.nesterovsky-bros.com/weblog/2013/01/06/HowToLoadKendoUITemplatesFromExternalFiles.aspx"&gt;How
To: Load KendoUI Templates from External Files&lt;/a&gt;&amp;quot;, and &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt"&gt;templates.tt&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
Definition of the UserControl widget.&lt;/li&gt;
&lt;li&gt;
Confirm dialog user control (we shall mention it later).&lt;/li&gt;
&lt;li&gt;
Products user control.&lt;/li&gt;
&lt;li&gt;
Data binding that instantiates page controls.&lt;/li&gt;
&lt;li&gt;
Model is passed to a user control through the dataSource.&lt;/li&gt;
&lt;li&gt;
Use of Products user control. Notice that &amp;quot;data-role&amp;quot; defines control type,
&amp;quot;source&amp;quot; refers to the model.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;User Control declaration
&lt;/h3&gt;
&lt;p&gt;
Declaration consists of a view and a model. 
&lt;/p&gt;
&lt;p&gt;
View is html with data binding. See &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/products.tmpl.html"&gt;products.tmpl.html&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
We build our project using Visual Studio, so templates packaging is done with &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt"&gt;templates.tt&lt;/a&gt;.
This transformation converts products template into a tag:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;script id="products-template" type="text/x-kendo-template"&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
thus template can be referred by a utility function: &lt;code&gt;nesterovskyBros.template(&amp;quot;products-template&amp;quot;)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Model inherits kedo.data.Model. Here how it looks:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&lt;strong&gt;// (1) Define a ProducsModel class&lt;/strong&gt;.&lt;br /&gt;
nesterovskyBros.data.ProductsModel = &lt;a href="http://docs.kendoui.com/api/framework/model"&gt;kendo.data.Model.define&lt;/a&gt;(&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;// (2) Model properties.&lt;/strong&gt;
&lt;br /&gt;
fields:&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; productName: { type: "string", defaultValue: "Product Name" },&lt;br /&gt;
&amp;nbsp; productPrice: { type: "number", defaultValue: 10 },&lt;br /&gt;
&amp;nbsp; productUnitsInStock: { type: "number", defaultValue: 10 },&lt;br /&gt;
&amp;nbsp; products: { type: "default", defaultValue: [] }&lt;br /&gt;
},&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;// (3) Model methods.&lt;/strong&gt;
&lt;br /&gt;
addProduct: function () { ... },&lt;br /&gt;
deleteProduct: function (e) { ... },&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;// (4) Register user control.&lt;/strong&gt;
&lt;br /&gt;
nesterovskyBros.ui.Products = nesterovskyBros.defineControl(&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; name: "Products",&lt;br /&gt;
&amp;nbsp; model: nesterovskyBros.data.ProductsModel&lt;br /&gt;
});&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
That's what we have here:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We define a model that inherits KendoUI Model.&lt;/li&gt;
&lt;li&gt;
We define model fields.&lt;/li&gt;
&lt;li&gt;
We define model methods.&lt;/li&gt;
&lt;li&gt;
Register user control with&amp;nbsp; &lt;code&gt;nesterovskyBros.defineControl(proto)&lt;/code&gt; call,
where:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;proto.name&lt;/code&gt; - defines user control name;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;proto.model&lt;/code&gt; - defines model type;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;proto.template&lt;/code&gt; - defines optional template. If not specified, a template
is retrieved from &lt;code&gt;$(&amp;quot;#&amp;quot; + proto.name.toLowerCase() + &amp;quot;-template&amp;quot;).html()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;UserControl API
&lt;/h3&gt;
&lt;p&gt;
Now, what&amp;#39;s remained is API for the UserControl. See &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls.js"&gt;controls.js&lt;/a&gt;.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
UserControl defines following events:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;change&lt;/code&gt; - triggered when data source is changed;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dataBound&lt;/code&gt; - triggered when widget is data bound;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dataBinding&lt;/code&gt; - triggered befor widget data binding;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;save&lt;/code&gt; - used to notify user to save model state.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
UserControl defines following options:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;autoBind (default false)&lt;/code&gt; - autoBind data source;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;template (default $.noop)&lt;/code&gt; - user control template.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
UserControl defines &lt;code&gt;dataSource&lt;/code&gt; field and &lt;code&gt;setDataSource()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;
UserControl defines &lt;code&gt;rebind()&lt;/code&gt; method to manually rebuild widget&amp;#39;s
view from the template and model.&lt;/li&gt;
&lt;li&gt;
UserControl sets/deletes model.owner, which is a function returning a user control
widget when model is bound/unbound to the widget.&lt;/li&gt;
&lt;li&gt;
When UserControl binds/unbinds model a &lt;code&gt;model.refresh&lt;/code&gt; method is called,
if any.&lt;/li&gt;
&lt;li&gt;
You usually define you control with a call &lt;code&gt;nesterovskyBros.defineControl(proto)&lt;/code&gt;.
See above.&lt;/li&gt;
&lt;li&gt;
There is also a convenience method to build a dialog based on a user control: nesterovskyBros.defineDialog(options),
where&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;options.name&lt;/code&gt; - a user control name (used in the data-role);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;options.model&lt;/code&gt; - a model type;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;options.windowOptions&lt;/code&gt; - a window options.&lt;/li&gt;
&lt;/ul&gt;
This method returns a function that recieves a user control model, and returns a dialog
(&lt;code&gt;kendo.ui.Window&lt;/code&gt;) based on the user control.&lt;br /&gt;
Dialog has &lt;code&gt;model()&lt;/code&gt; function that returns an instance of model.&lt;br /&gt;
Model has &lt;code&gt;dialog()&lt;/code&gt; function that returns an instance of the dialog.&lt;br /&gt;
Dialog and model have &lt;code&gt;result()&lt;/code&gt; function that returns an instance of deferred
object used to track dialog completion.&lt;br /&gt;
The example of user control dialog is &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/confirm.js"&gt;confirm.js&lt;/a&gt; and &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates/confirm.tmpl.html"&gt;confirm.tmpl.html&lt;/a&gt;.
The use is in the &lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/controls/products.js"&gt;products.js&lt;/a&gt; deleteProduct():&lt;br /&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;deleteProduct: function(e) 
&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; var that = this;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return nesterovskyBros.dialog.confirm(&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; title: "Please confirm",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; message: "Do you want to delete the record?",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; confirm: "Yes",&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cancel: "No"&lt;br /&gt;
&amp;nbsp; }).&lt;br /&gt;
&amp;nbsp; open().&lt;br /&gt;
&amp;nbsp; center().&lt;br /&gt;
&amp;nbsp; result().&lt;br /&gt;
&amp;nbsp; then(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function(confirmed)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!confirmed)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Last
&lt;/h3&gt;
&lt;p&gt;
User controls along with technique to manage and cache templates allow us to build
robust web applications. As the added value it&amp;#39;s became a trivial task to build
SPA.
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx"&gt;Compile
KendoUI templates&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f4337446-1b5e-4007-a1f8-a62b9d99681f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,f4337446-1b5e-4007-a1f8-a62b9d99681f.aspx</comments>
      <category>javascript</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b17502e5-9edf-43d2-9fab-7a5a3124ddf5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b17502e5-9edf-43d2-9fab-7a5a3124ddf5.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b17502e5-9edf-43d2-9fab-7a5a3124ddf5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Kendo UI Docs contains an article "<a href="http://docs.kendoui.com/howto/load-templates-external-files">How
To: Load Templates from External Files</a>", where authors review two way of
dealing with Kendo UI templates.
</p>
        <p>
While using Kendo UI we have found our own answer to: <i>where will the Kendo UI templates
be defined and maintained?</i></p>
        <p style="float: right">
          <img alt="solution tree" src="content/binary/templates.png" style="width: 320px" />
        </p>
        <p>
In our .NET project we have decided to keep templates separately, and to store them
under the "templates" folder. Those templates are in fact include html,
head, and stylesheet links. This is to help us to present those tempates in the design
view. 
</p>
        <p>
In our scripts folder, we have defined a small text transformation template: "templates.tt",
which produces "templates.js" file. This template takes body contents of
each "*.tmpl.html" file from "templates" folder and builds string
of the form:
</p>
        <p style="padding-left: 1em">
          <code>document.write('&lt;script id="footer-template" type="text/x-kendo-template"&gt;...&lt;/script&gt;&lt;script
id="row-template" type="text/x-kendo-template"&gt;...&lt;/script&gt;');</code>
        </p>
        <p>
In our page that uses templates, we include "templates.js":
</p>
        <p style="padding-left: 1em">
          <code> &lt;!DOCTYPE html&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;script src="scripts/templates.js"&gt;&lt;/script&gt; 
<br />
...</code>
        </p>
        <p>
Thus, we have:
</p>
        <ul>
          <li>
clean separation of templates and page content;</li>
          <li>
automatically generated templates include file.</li>
        </ul>
        <p>
          <a href="http://www.nesterovsky-bros.com/download/WebTemplates.zip">WebTemplates.zip</a> contains
a web project demonstrating our technique. "<a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt">templates.tt</a>"
is text template transformation used in the project.
</p>
        <p>
See also: <a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx">Compile
KendoUI templates</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b17502e5-9edf-43d2-9fab-7a5a3124ddf5" />
      </body>
      <title>How To: Load KendoUI Templates from External Files</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b17502e5-9edf-43d2-9fab-7a5a3124ddf5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/01/06/HowToLoadKendoUITemplatesFromExternalFiles.aspx</link>
      <pubDate>Sun, 06 Jan 2013 19:43:19 GMT</pubDate>
      <description>&lt;p&gt;
Kendo UI Docs contains an article &amp;quot;&lt;a href="http://docs.kendoui.com/howto/load-templates-external-files"&gt;How
To: Load Templates from External Files&lt;/a&gt;&amp;quot;, where authors review two way of
dealing with Kendo UI templates.
&lt;/p&gt;
&lt;p&gt;
While using Kendo UI we have found our own answer to: &lt;i&gt;where will the Kendo UI templates
be defined and maintained?&lt;/i&gt;
&lt;/p&gt;
&lt;p style="float: right"&gt;
&lt;img alt="solution tree" src="content/binary/templates.png" style="width: 320px" /&gt;
&lt;/p&gt;
&lt;p&gt;
In our .NET project we have decided to keep templates separately, and to store them
under the &amp;quot;templates&amp;quot; folder. Those templates are in fact include html,
head, and stylesheet links. This is to help us to present those tempates in the design
view. 
&lt;/p&gt;
&lt;p&gt;
In our scripts folder, we have defined a small text transformation template: &amp;quot;templates.tt&amp;quot;,
which produces &amp;quot;templates.js&amp;quot; file. This template takes body contents of
each &amp;quot;*.tmpl.html&amp;quot; file from &amp;quot;templates&amp;quot; folder and builds string
of the form:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;document.write('&amp;lt;script id="footer-template" type="text/x-kendo-template"&amp;gt;...&amp;lt;/script&amp;gt;&amp;lt;script
id="row-template" type="text/x-kendo-template"&amp;gt;...&amp;lt;/script&amp;gt;');&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In our page that uses templates, we include &amp;quot;templates.js&amp;quot;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; &amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;scripts/templates.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; 
&lt;br /&gt;
...&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Thus, we have:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
clean separation of templates and page content;&lt;/li&gt;
&lt;li&gt;
automatically generated templates include file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;a href="http://www.nesterovsky-bros.com/download/WebTemplates.zip"&gt;WebTemplates.zip&lt;/a&gt; contains
a web project demonstrating our technique. &amp;quot;&lt;a href="http://www.nesterovsky-bros.com/download/KendoUI/scripts/templates.tt"&gt;templates.tt&lt;/a&gt;&amp;quot;
is text template transformation used in the project.
&lt;/p&gt;
&lt;p&gt;
See also: &lt;a href="http://www.nesterovsky-bros.com/weblog/2013/07/07/CompileKendoUITemplates.aspx"&gt;Compile
KendoUI templates&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b17502e5-9edf-43d2-9fab-7a5a3124ddf5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b17502e5-9edf-43d2-9fab-7a5a3124ddf5.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>javascript</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=6d962206-6ca4-4ed5-828b-551082e660dc</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,6d962206-6ca4-4ed5-828b-551082e660dc.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,6d962206-6ca4-4ed5-828b-551082e660dc.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=6d962206-6ca4-4ed5-828b-551082e660dc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Two monthes ago we have started <a href="http://www.nesterovsky-bros.com/weblog/2012/09/07/ChangeColumnTypeInSQLServer2008R2.aspx"> a
process of changing column type from <code>smallint</code> to <code>int</code> in
a big database.</a></p>
        <p>
This was splitted in two phases:
</p>
        <ol>
          <li>
Change tables and internal stored procedures and functions.</li>
          <li>
Change interface API and update all clients.</li>
        </ol>
        <p>
The first part took almost two monthes to complete. Please read earlier post about
the technique we have selected for the implementation. In total we have transferred
about 15 billion rows. During this time database was online.
</p>
        <p>
The second part was short but the problem was that we did not control all clients,
so could not arbitrary change types of parameters and of result columns. 
</p>
        <p>
All our clients use Entity Framework 4 to access the database. All access is done
though stored procedures. So suppose there was a procedure:
</p>
        <p style="padding-left: 1em">
          <code>create procedure Data.GetReports(@type smallint) as<br />
begin<br />
select Type, ... from Data.Report where Type = @type;<br />
end;</code>
        </p>
        <p>
where column <code>"Type"</code> was of type <code>smallint</code>. Now
we were going to change it to:
</p>
        <p style="padding-left: 1em">
          <code>create procedure Data.GetReports(@type int) as<br />
begin<br />
select Type, ... from Data.Report where Type = @type;<br />
end;</code>
        </p>
        <p>
where <code>"Type"</code> column became of type <code>int</code>.
</p>
        <p>
Our tests have shown that EF bears with change of types of input parameters, but throws
exceptions when column type has been changed, even when a value fits the range. The
reason is that EF uses method <code><a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getint16.aspx">SqlDataReader.GetInt16</a></code> to
access the column value. This method has a remark: "<i>No conversions are performed;
therefore, the data retrieved must already be a 16-bit signed integer.</i>"
</p>
        <p>
Fortunately, we have found that EF allows additional columns in the result set. This
helped us to formulate the solution. We have updated the procedure definition like
this:
</p>
        <p style="padding-left: 1em">
          <code>create procedure Data.GetReports(@type int) as<br />
begin<br />
select 
<br />
cast(Type as smallint) Type, -- deprecated<br />
Type TypeEx, ... 
<br />
from 
<br />
Data.Report 
<br />
where 
<br />
Type = @type;<br />
end;</code>
        </p>
        <p>
This way:
</p>
        <ul>
          <li>
result column <code>"Type"</code> is declared as deprecated;</li>
          <li>
old clients still work;</li>
          <li>
all clients should be updated to use <code>"TypeEx"</code> column;</li>
          <li>
after all clients will be updated we shall remove <code>"Type"</code> column from
the result set.</li>
        </ul>
        <p>
So there is a clear migration process.
</p>
        <p>
P.S. we don't understand why <code>SqlDataReader</code> doesn't support value
conversion. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=6d962206-6ca4-4ed5-828b-551082e660dc" />
      </body>
      <title>Change column type in SQL Server, Part 2</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,6d962206-6ca4-4ed5-828b-551082e660dc.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/11/09/ChangeColumnTypeInSQLServerPart2.aspx</link>
      <pubDate>Fri, 09 Nov 2012 16:41:27 GMT</pubDate>
      <description>  &lt;p&gt;
Two monthes ago we have started &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/09/07/ChangeColumnTypeInSQLServer2008R2.aspx"&gt; a
process of changing column type from &lt;code&gt;smallint&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt; in
a big database.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This was splitted in two phases:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Change tables and internal stored procedures and functions.&lt;/li&gt;
&lt;li&gt;
Change interface API and update all clients.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The first part took almost two monthes to complete. Please read earlier post about
the technique we have selected for the implementation. In total we have transferred
about 15 billion rows. During this time database was online.
&lt;/p&gt;
&lt;p&gt;
The second part was short but the problem was that we did not control all clients,
so could not arbitrary change types of parameters and of result columns. 
&lt;/p&gt;
&lt;p&gt;
All our clients use Entity Framework 4 to access the database. All access is done
though stored procedures. So suppose there was a procedure:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create procedure Data.GetReports(@type smallint) as&lt;br /&gt;
begin&lt;br /&gt;
select Type, ... from Data.Report where Type = @type;&lt;br /&gt;
end;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where column &lt;code&gt;&amp;quot;Type&amp;quot;&lt;/code&gt; was of type &lt;code&gt;smallint&lt;/code&gt;. Now
we were going to change it to:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create procedure Data.GetReports(@type int) as&lt;br /&gt;
begin&lt;br /&gt;
select Type, ... from Data.Report where Type = @type;&lt;br /&gt;
end;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;&amp;quot;Type&amp;quot;&lt;/code&gt; column became of type &lt;code&gt;int&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Our tests have shown that EF bears with change of types of input parameters, but throws
exceptions when column type has been changed, even when a value fits the range. The
reason is that EF uses method &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getint16.aspx"&gt;SqlDataReader.GetInt16&lt;/a&gt;&lt;/code&gt; to
access the column value. This method has a remark: &amp;quot;&lt;i&gt;No conversions are performed;
therefore, the data retrieved must already be a 16-bit signed integer.&lt;/i&gt;&amp;quot;
&lt;/p&gt;
&lt;p&gt;
Fortunately, we have found that EF allows additional columns in the result set. This
helped us to formulate the solution. We have updated the procedure definition like
this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create procedure Data.GetReports(@type int) as&lt;br /&gt;
begin&lt;br /&gt;
select 
&lt;br /&gt;
cast(Type as smallint) Type, -- deprecated&lt;br /&gt;
Type TypeEx, ... 
&lt;br /&gt;
from 
&lt;br /&gt;
Data.Report 
&lt;br /&gt;
where 
&lt;br /&gt;
Type = @type;&lt;br /&gt;
end;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This way:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
result column &lt;code&gt;&amp;quot;Type&amp;quot;&lt;/code&gt; is declared as deprecated;&lt;/li&gt;
&lt;li&gt;
old clients still work;&lt;/li&gt;
&lt;li&gt;
all clients should be updated to use &lt;code&gt;&amp;quot;TypeEx&amp;quot;&lt;/code&gt; column;&lt;/li&gt;
&lt;li&gt;
after all clients will be updated we shall remove &lt;code&gt;"Type"&lt;/code&gt; column from
the result set.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So there is a clear migration process.
&lt;/p&gt;
&lt;p&gt;
P.S. we don&amp;#39;t understand why &lt;code&gt;SqlDataReader&lt;/code&gt; doesn&amp;#39;t support value
conversion. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=6d962206-6ca4-4ed5-828b-551082e660dc" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,6d962206-6ca4-4ed5-828b-551082e660dc.aspx</comments>
      <category>.NET</category>
      <category>SQL Server puzzle</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=f6c7bf47-0313-44d5-a3a2-6aefc7719112</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f6c7bf47-0313-44d5-a3a2-6aefc7719112.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,f6c7bf47-0313-44d5-a3a2-6aefc7719112.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=f6c7bf47-0313-44d5-a3a2-6aefc7719112</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we had a discussion with DBA regarding optimization strategey we have selected
for some queries.
</p>
        <p>
We have a table in our database. These are facts about that table:
</p>
        <ul>
          <li>
the table is partitioned by date;</li>
          <li>
each partition contains a month worth of data;</li>
          <li>
the table contains at present about 110 million rows;</li>
          <li>
the table ever grows;</li>
          <li>
the table is most accessed in the database;</li>
          <li>
the most accessed part of the data is related to last 2-3 days, which is about 150000
rows.</li>
        </ul>
        <p>
The way we have optimized access to that table was a core of the dispute. 
</p>
        <p>
We have created filtered index that includes data for the last 3 days.
</p>
        <p>
To achieve desired effect we had to:
</p>
        <ul>
          <li>
create a job that recreates that index once a day, as filter condition is moving;</li>
          <li>
adjust queries that access the table, as we had to use several access pathes to the
table depending on date.</li>
        </ul>
        <p>
As result we can see that under the load, stored procedures that access that table
became almost 50% faster. On the other hand maintainance became more complicated.
</p>
        <p>
DBA who didn't like the database complications had to agree that there are speed
improvements. He said that there should be a better way to achieve the same effect
but could not find it.
</p>
        <p>
Are there a better way to optimize access to this table?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f6c7bf47-0313-44d5-a3a2-6aefc7719112" />
      </body>
      <title>Over optimization in sql server</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,f6c7bf47-0313-44d5-a3a2-6aefc7719112.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/10/29/OverOptimizationInSqlServer.aspx</link>
      <pubDate>Mon, 29 Oct 2012 08:34:39 GMT</pubDate>
      <description>  &lt;p&gt;
Recently we had a discussion with DBA regarding optimization strategey we have selected
for some queries.
&lt;/p&gt;
&lt;p&gt;
We have a table in our database. These are facts about that table:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
the table is partitioned by date;&lt;/li&gt;
&lt;li&gt;
each partition contains a month worth of data;&lt;/li&gt;
&lt;li&gt;
the table contains at present about 110 million rows;&lt;/li&gt;
&lt;li&gt;
the table ever grows;&lt;/li&gt;
&lt;li&gt;
the table is most accessed in the database;&lt;/li&gt;
&lt;li&gt;
the most accessed part of the data is related to last 2-3 days, which is about 150000
rows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The way we have optimized access to that table was a core of the dispute. 
&lt;/p&gt;
&lt;p&gt;
We have created filtered index that includes data for the last 3 days.
&lt;/p&gt;
&lt;p&gt;
To achieve desired effect we had to:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
create a job that recreates that index once a day, as filter condition is moving;&lt;/li&gt;
&lt;li&gt;
adjust queries that access the table, as we had to use several access pathes to the
table depending on date.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As result we can see that under the load, stored procedures that access that table
became almost 50% faster. On the other hand maintainance became more complicated.
&lt;/p&gt;
&lt;p&gt;
DBA who didn&amp;#39;t like the database complications had to agree that there are speed
improvements. He said that there should be a better way to achieve the same effect
but could not find it.
&lt;/p&gt;
&lt;p&gt;
Are there a better way to optimize access to this table?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=f6c7bf47-0313-44d5-a3a2-6aefc7719112" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,f6c7bf47-0313-44d5-a3a2-6aefc7719112.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a030c1e6-63cc-4bbe-8cc1-e64243b07c39</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a030c1e6-63cc-4bbe-8cc1-e64243b07c39.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a030c1e6-63cc-4bbe-8cc1-e64243b07c39.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a030c1e6-63cc-4bbe-8cc1-e64243b07c39</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We're implementing UDT changes in the big database. Earlier, that User Defined
Type was based on <code>smallint</code>, and now we have to use <code>int</code> as
the base.
</p>
        <p>
The impact here is manyfold:
</p>
        <ol>
          <li>
Clients of the database should be prepared to use wider types.</li>
          <li>
All stored procedures, functions, triggers, and views should be updated accordingly.</li>
          <li>
Impact on the database size should be analyzed.</li>
          <li>
Types of columns in tables should be changed.</li>
          <li>
Performance impact should be minimal.</li>
        </ol>
        <p>
Now, we're trying to address (3), (5) and to implement (4), while trying to keep
interface with clients using old types.
</p>
        <p>
As for database size impact, we have found that an index fragmentation is a 
primary disk space waster (see <a href="http://www.nesterovsky-bros.com/weblog/2012/08/30/ReorganizeIndexInSQLServer.aspx">Reorganize
index in SQL Server</a>). We have performed some partial index reorganization and
can see now that we can gain back hundreds of GB of a disk space. On the other hand
we use page compression, so we expect that change of types will not increase sizes
of tables considerably. Indeed, our measurments show that tables will only be ~1-3%
bigger.
</p>
        <p>
The change of types of columns is untrivial task. The problem is that if you try to
change column's type (which is part of clustered index) directly then you should
temporary remove foreign keys, and to rebuild all indices. This won't work neither
due to disk space required for the operation (a huge transaction log is required),
nor due to availability of tables (we're talking about days or even weeks to rebuild
indices).
</p>
        <p>
To work-around the problem we have selected another way. For each target table T we
performed the following:
</p>
        <ul>
          <li>
Renamed table T to T_old;</li>
          <li>
Created a table T_new with required type changes;</li>
          <li>
Created a view named T, which is union of T_old for the dates before a split date
and T_new for the dates after the split date;</li>
          <li>
Created instead of insert/update/delete triggers for the view T.</li>
          <li>
Created a procedures that move data in bulks from T_old to the T_new, update split
date in view definitions, and delete data from T_old.</li>
        </ul>
        <p>
Note that:
</p>
        <ul>
          <li>
the new view uses wider column types, so we had to change stored procedures that clients
use to cast those columns back to shorter types to prevent side effects (fortunately
all access to this database is through stored procedures and functions);</li>
          <li>
the procedures that transfer data between new and old tables may work online;</li>
          <li>
the quality of execution plans did not degrade due to switch from table to a view;</li>
          <li>
all data related to the date after the split date are inserted into T_new table.</li>
        </ul>
        <p>
After transfer will be complete we shall drop T_old tables, and T views, and will
rename T_new tables into T.
</p>
        <p>
This will complete part 4 of the whole task. Our estimations are that it will take
a month or even more to complete the transfer. However solution is rather slow, the
database will stay online whole this period, which is required condition.
</p>
        <p>
The next task is to deal with type changes in parameters of stored procedures and
column types of output result sets. We're not sure yet what's the best way
to deal with it, and probably shall complain about in in next posts.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a030c1e6-63cc-4bbe-8cc1-e64243b07c39" />
      </body>
      <title>Change column type in SQL Server 2008 R2</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a030c1e6-63cc-4bbe-8cc1-e64243b07c39.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/09/07/ChangeColumnTypeInSQLServer2008R2.aspx</link>
      <pubDate>Fri, 07 Sep 2012 20:57:36 GMT</pubDate>
      <description>  &lt;p&gt;
We&amp;#39;re implementing UDT changes in the big database. Earlier, that User Defined
Type was based on &lt;code&gt;smallint&lt;/code&gt;, and now we have to use &lt;code&gt;int&lt;/code&gt; as
the base.
&lt;/p&gt;
&lt;p&gt;
The impact here is manyfold:
&lt;/p&gt;
&lt;ol &gt;
&lt;li&gt;
Clients of the database should be prepared to use wider types.&lt;/li&gt;
&lt;li&gt;
All stored procedures, functions, triggers, and views should be updated accordingly.&lt;/li&gt;
&lt;li&gt;
Impact on the database size should be analyzed.&lt;/li&gt;
&lt;li&gt;
Types of columns in tables should be changed.&lt;/li&gt;
&lt;li&gt;
Performance impact should be minimal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Now, we&amp;#39;re trying to address (3), (5) and to implement (4), while trying to keep
interface with clients using old types.
&lt;/p&gt;
&lt;p&gt;
As for database size impact, we have found that an index fragmentation is a&amp;nbsp;
primary disk space waster (see &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/08/30/ReorganizeIndexInSQLServer.aspx"&gt;Reorganize
index in SQL Server&lt;/a&gt;). We have performed some partial index reorganization and
can see now that we can gain back hundreds of GB of a disk space. On the other hand
we use page compression, so we expect that change of types will not increase sizes
of tables considerably. Indeed, our measurments show that tables will only be ~1-3%
bigger.
&lt;/p&gt;
&lt;p&gt;
The change of types of columns is untrivial task. The problem is that if you try to
change column&amp;#39;s type (which is part of clustered index) directly then you should
temporary remove foreign keys, and to rebuild all indices. This won&amp;#39;t work neither
due to disk space required for the operation (a huge transaction log is required),
nor due to availability of tables (we&amp;#39;re talking about days or even weeks to rebuild
indices).
&lt;/p&gt;
&lt;p&gt;
To work-around the problem we have selected another way. For each target table T we
performed the following:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Renamed table T to T_old;&lt;/li&gt;
&lt;li&gt;
Created a table T_new with required type changes;&lt;/li&gt;
&lt;li&gt;
Created a view named T, which is union of T_old for the dates before a split date
and T_new for the dates after the split date;&lt;/li&gt;
&lt;li&gt;
Created instead of insert/update/delete triggers for the view T.&lt;/li&gt;
&lt;li&gt;
Created a procedures that move data in bulks from T_old to the T_new, update split
date in view definitions, and delete data from T_old.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Note that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
the new view uses wider column types, so we had to change stored procedures that clients
use to cast those columns back to shorter types to prevent side effects (fortunately
all access to this database is through stored procedures and functions);&lt;/li&gt;
&lt;li&gt;
the procedures that transfer data between new and old tables may work online;&lt;/li&gt;
&lt;li&gt;
the quality of execution plans did not degrade due to switch from table to a view;&lt;/li&gt;
&lt;li&gt;
all data related to the date after the split date are inserted into T_new table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
After transfer will be complete we shall drop T_old tables, and T views, and will
rename T_new tables into T.
&lt;/p&gt;
&lt;p&gt;
This will complete part 4 of the whole task. Our estimations are that it will take
a month or even more to complete the transfer. However solution is rather slow, the
database will stay online whole this period, which is required condition.
&lt;/p&gt;
&lt;p&gt;
The next task is to deal with type changes in parameters of stored procedures and
column types of output result sets. We&amp;#39;re not sure yet what&amp;#39;s the best way
to deal with it, and probably shall complain about in in next posts.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a030c1e6-63cc-4bbe-8cc1-e64243b07c39" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a030c1e6-63cc-4bbe-8cc1-e64243b07c39.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2776c571-a218-4163-bcd6-60364eefa40c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2776c571-a218-4163-bcd6-60364eefa40c.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2776c571-a218-4163-bcd6-60364eefa40c.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2776c571-a218-4163-bcd6-60364eefa40c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Back in 2006 and 2007 we have defined <code>dbo.Numbers</code> function: <a href="http://www.nesterovsky-bros.com/weblog/2006/10/02/NumbersTableInSQLServer2005.aspx"> Numbers
table in SQL Server 2005</a>, <a href="http://www.nesterovsky-bros.com/weblog/2007/02/23/ParadeOfNumbers.aspx"> Parade
of numbers</a>. Such construct is very important in a set based programming. E.g.
XPath 2 contains a range expression like this: <code>"1 to 10"</code> to
return a sequence of numbers. Unfortunately neither SQL Server 2008 R2, nor SQL Server
2012 support such construct, so <code>dbo.Numbers</code> function is still actual. 
</p>
        <p>
After all these years the function evolved a little bit to achieve a better performance.
Here is its source:
</p>
        <p style="padding-left: 1em">
          <code>-- Returns numbers table.<br />
-- Table has a following structure: table(value int not null);<br />
-- value is an integer number that contains numbers from 1 to a specified value.<br />
create function dbo.Numbers<br />
( 
<br />
-- Number of rows to return.<br />
@count int<br />
)<br />
returns table 
<br />
as<br />
return 
<br />
with Number8 as<br />
(<br />
select 
<br />
* 
<br />
from<br />
(<br />
values 
<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),<br />
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)<br />
) N(Value)<br />
),<br />
Number32(Value) as<br />
(<br />
select 
<br />
0 
<br />
from 
<br />
Number8 N1<br />
left join<br />
Number8 N2 
<br />
on<br />
@count &gt; 0x100<br />
left join<br />
Number8 N3<br />
left join<br />
Number8 N4<br />
on<br />
@count &gt; 0x1000000<br />
on<br />
@count &gt; 0x10000<br />
)<br />
select top(@count) row_number() over(order by @count) Value from Number32; </code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2776c571-a218-4163-bcd6-60364eefa40c" />
      </body>
      <title>Numbers table in SQL Server - year 2012</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2776c571-a218-4163-bcd6-60364eefa40c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/09/01/NumbersTableInSQLServerYear2012.aspx</link>
      <pubDate>Sat, 01 Sep 2012 20:16:49 GMT</pubDate>
      <description>&lt;p&gt;
Back in 2006 and 2007 we have defined &lt;code&gt;dbo.Numbers&lt;/code&gt; function: &lt;a href="http://www.nesterovsky-bros.com/weblog/2006/10/02/NumbersTableInSQLServer2005.aspx"&gt; Numbers
table in SQL Server 2005&lt;/a&gt;, &lt;a href="http://www.nesterovsky-bros.com/weblog/2007/02/23/ParadeOfNumbers.aspx"&gt; Parade
of numbers&lt;/a&gt;. Such construct is very important in a set based programming. E.g.
XPath 2 contains a range expression like this: &lt;code&gt;&amp;quot;1 to 10&amp;quot;&lt;/code&gt; to
return a sequence of numbers. Unfortunately neither SQL Server 2008 R2, nor SQL Server
2012 support such construct, so &lt;code&gt;dbo.Numbers&lt;/code&gt; function is still actual. 
&lt;/p&gt;
&lt;p&gt;
After all these years the function evolved a little bit to achieve a better performance.
Here is its source:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- Returns numbers table.&lt;br /&gt;
-- Table has a following structure: table(value int not null);&lt;br /&gt;
-- value is an integer number that contains numbers from 1 to a specified value.&lt;br /&gt;
create function dbo.Numbers&lt;br /&gt;
( 
&lt;br /&gt;
-- Number of rows to return.&lt;br /&gt;
@count int&lt;br /&gt;
)&lt;br /&gt;
returns table 
&lt;br /&gt;
as&lt;br /&gt;
return 
&lt;br /&gt;
with Number8 as&lt;br /&gt;
(&lt;br /&gt;
select 
&lt;br /&gt;
* 
&lt;br /&gt;
from&lt;br /&gt;
(&lt;br /&gt;
values 
&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0),&lt;br /&gt;
(0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)&lt;br /&gt;
) N(Value)&lt;br /&gt;
),&lt;br /&gt;
Number32(Value) as&lt;br /&gt;
(&lt;br /&gt;
select 
&lt;br /&gt;
0 
&lt;br /&gt;
from 
&lt;br /&gt;
Number8 N1&lt;br /&gt;
left join&lt;br /&gt;
Number8 N2 
&lt;br /&gt;
on&lt;br /&gt;
@count &amp;gt; 0x100&lt;br /&gt;
left join&lt;br /&gt;
Number8 N3&lt;br /&gt;
left join&lt;br /&gt;
Number8 N4&lt;br /&gt;
on&lt;br /&gt;
@count &amp;gt; 0x1000000&lt;br /&gt;
on&lt;br /&gt;
@count &amp;gt; 0x10000&lt;br /&gt;
)&lt;br /&gt;
select top(@count) row_number() over(order by @count) Value from Number32; &lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2776c571-a218-4163-bcd6-60364eefa40c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2776c571-a218-4163-bcd6-60364eefa40c.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=af238304-6c85-4127-95cf-ed2f4407d468</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,af238304-6c85-4127-95cf-ed2f4407d468.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,af238304-6c85-4127-95cf-ed2f4407d468.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=af238304-6c85-4127-95cf-ed2f4407d468</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We're working with an online database, which is ever populated with a new data.
Database activity is mostly around recent data. Activity against older data declines
with increasing the distance from today. The ratio of an amount of a new data, say
for a last month, to the whole data, at present stays at ~1%. The size of database
is measured in TBs.
</p>
        <p>
While we're developers and not DBA's,  you will see from a later blog
posts why we're bothered with the database size. In short we're planning to
change some UDF type from <code>smallint</code> to <code>int</code>. This will impact
on many tables, and the task now is to estimate that impact.
</p>
        <p>
Our first attempts to measure the difference between table sizes before and after
type change showed that a data fragmentation often masks the difference, so we started
to look at a way to reduce fragmentation.
</p>
        <p>
Internet is full with recomentations. An advice can be found in BOL at <a href="http://technet.microsoft.com/en-us/library/ms189858.aspx">Reorganize
and Rebuild Indexes</a>.
</p>
        <p>
So, our best help in this task is the function <code>sys.dm_db_index_physical_stats</code>,
which reports statistics about fragmentation.
</p>
        <p>
Analysing what that function has given to us we could see that we had a highly fragmented
data. There was no reason to bear with that taking into an account that the most of
the data stored in the database is historical, which is rarely accessed and even more
rarely updated.
</p>
        <p>
The next simplest instument adviced is:
</p>
        <p style="padding-left: 1em">
          <code>alter index { index_name | ALL } on &lt;object&gt; reorganize [ PARTITION =
partition_number ];</code>
        </p>
        <p>
The less trivial but often more efficient instrument is the use of online index rebuild
and index reorganize depending on index type and a level of fragmentation. 
</p>
        <p>
All in all our estimation is that rebuilding or reorganizing indices frees ~100-200GBs
of disk space. While, it's only a small percent of total database size, it gives
us several monthes worth of a disk space! 
</p>
        <p>
Earlier we overlooked SQL Server API to monitor fragmentation, rebuild, and reorganize
indices, and now we're going to create a job that will regulary defragment the
database.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=af238304-6c85-4127-95cf-ed2f4407d468" />
      </body>
      <title>Reorganize index in SQL Server</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,af238304-6c85-4127-95cf-ed2f4407d468.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/08/30/ReorganizeIndexInSQLServer.aspx</link>
      <pubDate>Thu, 30 Aug 2012 08:59:29 GMT</pubDate>
      <description> &lt;p&gt;
We&amp;#39;re working with an online database, which is ever populated with a new data.
Database activity is mostly around recent data. Activity against older data declines
with increasing the distance from today. The ratio of an amount of a new data, say
for a last month, to the whole data, at present stays at ~1%. The size of database
is measured in TBs.
&lt;/p&gt;
&lt;p&gt;
While we&amp;#39;re developers and not DBA&amp;#39;s,&amp;nbsp; you will see from a later blog
posts why we&amp;#39;re bothered with the database size. In short we&amp;#39;re planning to
change some UDF type from &lt;code&gt;smallint&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt;. This will impact
on many tables, and the task now is to estimate that impact.
&lt;/p&gt;
&lt;p&gt;
Our first attempts to measure the difference between table sizes before and after
type change showed that a data fragmentation often masks the difference, so we started
to look at a way to reduce fragmentation.
&lt;/p&gt;
&lt;p&gt;
Internet is full with recomentations. An advice can be found in BOL at &lt;a href="http://technet.microsoft.com/en-us/library/ms189858.aspx"&gt;Reorganize
and Rebuild Indexes&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So, our best help in this task is the function &lt;code&gt;sys.dm_db_index_physical_stats&lt;/code&gt;,
which reports statistics about fragmentation.
&lt;/p&gt;
&lt;p&gt;
Analysing what that function has given to us we could see that we had a highly fragmented
data. There was no reason to bear with that taking into an account that the most of
the data stored in the database is historical, which is rarely accessed and even more
rarely updated.
&lt;/p&gt;
&lt;p&gt;
The next simplest instument adviced is:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;alter index { index_name | ALL } on &amp;lt;object&amp;gt; reorganize [ PARTITION =
partition_number ];&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The less trivial but often more efficient instrument is the use of online index rebuild
and index reorganize depending on index type and a level of fragmentation. 
&lt;/p&gt;
&lt;p&gt;
All in all our estimation is that rebuilding or reorganizing indices frees ~100-200GBs
of disk space. While, it&amp;#39;s only a small percent of total database size, it gives
us several monthes worth of a disk space! 
&lt;/p&gt;
&lt;p&gt;
Earlier we overlooked SQL Server API to monitor fragmentation, rebuild, and reorganize
indices, and now we&amp;#39;re going to create a job that will regulary defragment the
database.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=af238304-6c85-4127-95cf-ed2f4407d468" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,af238304-6c85-4127-95cf-ed2f4407d468.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a</wfw:commentRss>
      <title>Snapshot of data per last date available</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/08/19/SnapshotOfDataPerLastDateAvailable.aspx</link>
      <pubDate>Sun, 19 Aug 2012 05:57:55 GMT</pubDate>
      <description>  &lt;p&gt;
We have a large table in the form:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create table dbo.Data&lt;br /&gt;
(&lt;br /&gt;
Date date not null,&lt;br /&gt;
Type int not null,&lt;br /&gt;
Value nvarchar(50) null,&lt;br /&gt;
primary key clustered(Date, Type)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
create unique nonclustered index IX_Data on dbo.Data(Type, Date);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Among other queries we often need a snapshot of data per each &lt;code&gt;Type&lt;/code&gt; for
a latest &lt;code&gt;Date&lt;/code&gt; available:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select&lt;br /&gt;
max(Date) Date,&lt;br /&gt;
Type&lt;br /&gt;
from&lt;br /&gt;
dbo.Data&lt;br /&gt;
group by&lt;br /&gt;
Type&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
We have found that the above select does not run well on our data set. In fact &lt;code&gt;dbo.Data&lt;/code&gt; grows
with time, while snapshot we need stays more or less of the same size. The best solution
to such query is to precalculate it. One way would be to create an indexed view, but
SQL Server does not support &lt;code&gt;max()&lt;/code&gt; aggregate in indexed views. 
&lt;/p&gt;
&lt;p&gt;
So, we have decided to add additional &lt;code&gt;bit&lt;/code&gt; field &lt;code&gt;dbo.Data.Last&lt;/code&gt; indicating
that a row belongs to a last date snapshot, and to create filtered index to access
that snapshot:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create table dbo.Data&lt;br /&gt;
(&lt;br /&gt;
Date date not null,&lt;br /&gt;
Type int not null,&lt;br /&gt;
Value nvarchar(50) null,&lt;br /&gt;
&lt;strong&gt;Last bit not null default 0,&lt;br /&gt;
&lt;/strong&gt; primary key clustered(Date, Type)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
create unique nonclustered index IX_Data on dbo.Data(Type, Date);&lt;br /&gt;
&lt;br /&gt;
create unique nonclustered index IX_Data_Last on dbo.Data(Type) 
&lt;br /&gt;
include(Date) 
&lt;br /&gt;
where Last = 1;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
One way to support &lt;code&gt;Last&lt;/code&gt; indicator is to create a trigger that will adjust &lt;code&gt;Last&lt;/code&gt; value:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create trigger dbo.Data_Update on dbo.Data&lt;br /&gt;
after insert,delete,update&lt;br /&gt;
as 
&lt;br /&gt;
begin&lt;br /&gt;&lt; 2)&lt;br /&gt;
if (trigger_nestlevel(@@procid) begin&lt;br /&gt;
set nocount on;&lt;br /&gt;
&lt;br /&gt;
with D as&lt;br /&gt;
(&lt;br /&gt;
select Date, Type from deleted&lt;br /&gt;
union&lt;br /&gt;
select Date, Type from inserted&lt;br /&gt;
),&lt;br /&gt;
U as&lt;br /&gt;
(&lt;br /&gt;
select&lt;br /&gt;
V.Date, V.Type&lt;br /&gt;
from&lt;br /&gt;
D&lt;br /&gt;
inner join&lt;br /&gt;
dbo.Data V&lt;br /&gt;
on&lt;br /&gt;
(V.Last = 1) and&lt;br /&gt;
(V.Type = D.Type)&lt;br /&gt;
union&lt;br /&gt;
select&lt;br /&gt;
max(V.Date) Date,&lt;br /&gt;
V.Type&lt;br /&gt;
from&lt;br /&gt;
D&lt;br /&gt;
inner join&lt;br /&gt;
dbo.Data V&lt;br /&gt;
on&lt;br /&gt;
V.Type = D.Type&lt;br /&gt;
group by&lt;br /&gt;
V.Type&lt;br /&gt;
),&lt;br /&gt;
V as&lt;br /&gt;
(&lt;br /&gt;
select&lt;br /&gt;
rank() over(partition by V.Type order by V.Date desc) Row,&lt;br /&gt;
V.*&lt;br /&gt;
from&lt;br /&gt;
dbo.Data V&lt;br /&gt;
inner join&lt;br /&gt;
U&lt;br /&gt;
on&lt;br /&gt;
(V.Date = U.Date) and&lt;br /&gt;
(V.Type = U.Type)&lt;br /&gt;
)&lt;br /&gt;
update V set Last = 1 - cast(Row - 1 as bit);&lt;br /&gt;
end;&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
With &lt;code&gt;Last&lt;/code&gt; indicator in action, our original query has been transformed
to:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select Date, Type from dbo.Data where Last = 1&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Execution plan shows that a new filtered index &lt;code&gt;IX_Data_Last&lt;/code&gt; is used.
Execution speed has increased considerably. As our actual table contains other bit
fields, so &lt;code&gt;Last&lt;/code&gt; indicator did not increase the table size, as SQL Server
packs each 8 bit fields in one byte.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8fcf8ab3-2bc8-4ef5-b27e-dee6bac94e3a.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=cad54317-1876-4b98-a8d2-7e44e5dda1f7</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=cad54317-1876-4b98-a8d2-7e44e5dda1f7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Earlier we have shown <a href="http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx"> how
to build streaming xml reader from business data</a> and have reminded about <a href="http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx">ForwardXPathNavigator
which helps to create a streaming xslt transformation</a>. Now we want to show how
to stream content produced with xslt out of WCF service.
</p>
        <p>
To achieve streaming in WCF one needs: 
</p>
        <p>
1. To configure service to use streaming. Description on how to do this can be found
in the internet. See web.config of the sample <a href="http://www.nesterovsky-bros.com/download/Streaming.zip"> Streaming.zip</a> for
the details.
</p>
        <p>
2. Create a service with a method returning <code>Stream</code>:
</p>
        <p>
          <code>[ServiceContract(Namespace = "http://www.nesterovsky-bros.com")]<br />
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]<br />
public class Service<br />
{<br />
[OperationContract]<br />
[WebGet(RequestFormat = WebMessageFormat.Json)]<br />
public Stream GetPeopleHtml(int count, int seed)<br />
{<br />
...<br />
}<br />
}</code>
        </p>
        <p>
2. Return a <code>Stream</code> from xsl transformation. 
</p>
        <p>
Unfortunately (we mentioned it already), <code>XslCompiledTransform</code> generates
its output into <code>XmlWriter</code> (or into output <code>Stream</code>) rather
than exposes result as <code>XmlReader</code>, while WCF gets input stream and passes
it to a client. 
</p>
        <p>
We could generate xslt output into a file or a memory <code>Stream</code> and then
return that content as input <code>Stream</code>, but this will defeat a goal of streaming,
as client would have started to get data no earlier that the xslt completed its work.
What we need instead is a pipe that form xslt output <code>Stream</code> to an input <code>Stream</code> returned
from WCF.
</p>
        <p>
.NET implements pipe streams, so our task is trivial. We have defined a utility method
that creates an input <code>Stream</code> from a generator populating an output <code>Stream</code>:
</p>
        <p>
          <code> public static Stream GetPipedStream(Action&lt;Stream&gt; generator)<br />
{<br />
var output = new AnonymousPipeServerStream();<br />
var input = new AnonymousPipeClientStream(<br />
output.GetClientHandleAsString());<br /><br />
Task.Factory.StartNew(<br />
() =&gt;<br />
{<br />
using(output)<br />
{<br />
generator(output);<br />
output.WaitForPipeDrain();<br />
}<br />
},<br />
TaskCreationOptions.LongRunning);<br /><br />
return input;<br />
} </code>
        </p>
        <p>
We wrapped xsl transformation as such a generator:
</p>
        <p>
          <code>[OperationContract]<br />
[WebGet(RequestFormat = WebMessageFormat.Json)]<br />
public Stream GetPeopleHtml(int count, int seed)<br />
{<br />
var context = WebOperationContext.Current;<br /><br />
context.OutgoingResponse.ContentType = "text/html";<br />
context.OutgoingResponse.Headers["Content-Disposition"] = 
<br />
"attachment;filename=reports.html";<br /><br />
var cache = HttpRuntime.Cache;<br />
var path = HttpContext.Current.Server.MapPath("~/People.xslt");<br />
var transform = cache[path] as XslCompiledTransform;<br /><br />
if (transform == null)<br />
{<br />
transform = new XslCompiledTransform();<br />
transform.Load(path);<br />
cache.Insert(path, transform, new CacheDependency(path));<br />
}<br /><br />
return Extensions.<strong>GetPipedStream</strong>(<br />
output =&gt;<br />
{<br />
// We have a streamed business data.<br />
var people = Data.CreateRandomData(count, seed, 0, count);<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream =<br />
people.<strong>ToXmlStream</strong>("people", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
{<br />
// XPath forward navigator is used as an input source.<br />
transform.Transform(<br />
new <strong>ForwardXPathNavigator</strong>(reader),<br />
new XsltArgumentList(),<br />
output);<br />
}<br />
});<br />
}</code>
        </p>
        <p>
This way we have build a code that streams data directly from business data to a client
in a form of report. A set of utility functions and classes helped us to overcome
.NET's limitations and to build simple code that one can easily support.
</p>
        <p>
The sources can be found at <a href="http://www.nesterovsky-bros.com/download/Streaming.zip"> Streaming.zip</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7" />
      </body>
      <title>Stream xslt transformation through WCF</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/08/03/StreamXsltTransformationThroughWCF.aspx</link>
      <pubDate>Fri, 03 Aug 2012 22:32:49 GMT</pubDate>
      <description>  &lt;p&gt;
Earlier we have shown &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx"&gt; how
to build streaming xml reader from business data&lt;/a&gt; and have reminded about &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx"&gt;ForwardXPathNavigator
which helps to create a streaming xslt transformation&lt;/a&gt;. Now we want to show how
to stream content produced with xslt out of WCF service.
&lt;/p&gt;
&lt;p&gt;
To achieve streaming in WCF one needs: 
&lt;/p&gt;
&lt;p&gt;
1. To configure service to use streaming. Description on how to do this can be found
in the internet. See web.config of the sample &lt;a href="http://www.nesterovsky-bros.com/download/Streaming.zip"&gt; Streaming.zip&lt;/a&gt; for
the details.
&lt;/p&gt;
&lt;p&gt;
2. Create a service with a method returning &lt;code&gt;Stream&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;[ServiceContract(Namespace = "http://www.nesterovsky-bros.com")]&lt;br /&gt;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;
public class Service&lt;br /&gt;
{&lt;br /&gt;
[OperationContract]&lt;br /&gt;
[WebGet(RequestFormat = WebMessageFormat.Json)]&lt;br /&gt;
public Stream GetPeopleHtml(int count, int seed)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
2. Return a &lt;code&gt;Stream&lt;/code&gt; from xsl transformation. 
&lt;/p&gt;
&lt;p&gt;
Unfortunately (we mentioned it already), &lt;code&gt;XslCompiledTransform&lt;/code&gt; generates
its output into &lt;code&gt;XmlWriter&lt;/code&gt; (or into output &lt;code&gt;Stream&lt;/code&gt;) rather
than exposes result as &lt;code&gt;XmlReader&lt;/code&gt;, while WCF gets input stream and passes
it to a client. 
&lt;/p&gt;
&lt;p&gt;
We could generate xslt output into a file or a memory &lt;code&gt;Stream&lt;/code&gt; and then
return that content as input &lt;code&gt;Stream&lt;/code&gt;, but this will defeat a goal of streaming,
as client would have started to get data no earlier that the xslt completed its work.
What we need instead is a pipe that form xslt output &lt;code&gt;Stream&lt;/code&gt; to an input &lt;code&gt;Stream&lt;/code&gt; returned
from WCF.
&lt;/p&gt;
&lt;p&gt;
.NET implements pipe streams, so our task is trivial. We have defined a utility method
that creates an input &lt;code&gt;Stream&lt;/code&gt; from a generator populating an output &lt;code&gt;Stream&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; public static Stream GetPipedStream(Action&amp;lt;Stream&amp;gt; generator)&lt;br /&gt;
{&lt;br /&gt;
var output = new AnonymousPipeServerStream();&lt;br /&gt;
var input = new AnonymousPipeClientStream(&lt;br /&gt;
output.GetClientHandleAsString());&lt;br /&gt;
&lt;br /&gt;
Task.Factory.StartNew(&lt;br /&gt;
() =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
using(output)&lt;br /&gt;
{&lt;br /&gt;
generator(output);&lt;br /&gt;
output.WaitForPipeDrain();&lt;br /&gt;
}&lt;br /&gt;
},&lt;br /&gt;
TaskCreationOptions.LongRunning);&lt;br /&gt;
&lt;br /&gt;
return input;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We wrapped xsl transformation as such a generator:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;[OperationContract]&lt;br /&gt;
[WebGet(RequestFormat = WebMessageFormat.Json)]&lt;br /&gt;
public Stream GetPeopleHtml(int count, int seed)&lt;br /&gt;
{&lt;br /&gt;
var context = WebOperationContext.Current;&lt;br /&gt;
&lt;br /&gt;
context.OutgoingResponse.ContentType = "text/html";&lt;br /&gt;
context.OutgoingResponse.Headers["Content-Disposition"] = 
&lt;br /&gt;
"attachment;filename=reports.html";&lt;br /&gt;
&lt;br /&gt;
var cache = HttpRuntime.Cache;&lt;br /&gt;
var path = HttpContext.Current.Server.MapPath("~/People.xslt");&lt;br /&gt;
var transform = cache[path] as XslCompiledTransform;&lt;br /&gt;
&lt;br /&gt;
if (transform == null)&lt;br /&gt;
{&lt;br /&gt;
transform = new XslCompiledTransform();&lt;br /&gt;
transform.Load(path);&lt;br /&gt;
cache.Insert(path, transform, new CacheDependency(path));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return Extensions.&lt;strong&gt;GetPipedStream&lt;/strong&gt;(&lt;br /&gt;
output =&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
// We have a streamed business data.&lt;br /&gt;
var people = Data.CreateRandomData(count, seed, 0, count);&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream =&lt;br /&gt;
people.&lt;strong&gt;ToXmlStream&lt;/strong&gt;("people", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
{&lt;br /&gt;
// XPath forward navigator is used as an input source.&lt;br /&gt;
transform.Transform(&lt;br /&gt;
new &lt;strong&gt;ForwardXPathNavigator&lt;/strong&gt;(reader),&lt;br /&gt;
new XsltArgumentList(),&lt;br /&gt;
output);&lt;br /&gt;
}&lt;br /&gt;
});&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This way we have build a code that streams data directly from business data to a client
in a form of report. A set of utility functions and classes helped us to overcome
.NET&amp;#39;s limitations and to build simple code that one can easily support.
&lt;/p&gt;
&lt;p&gt;
The sources can be found at &lt;a href="http://www.nesterovsky-bros.com/download/Streaming.zip"&gt; Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=cad54317-1876-4b98-a8d2-7e44e5dda1f7" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,cad54317-1876-4b98-a8d2-7e44e5dda1f7.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=24094700-ca7e-4e73-8b30-fbdc9d72072a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=24094700-ca7e-4e73-8b30-fbdc9d72072a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the previous <a href="http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx"> post
about streaming</a> we have dropped at the point where we have <code>XmlReader</code> in
hands, which continously gets data from <code>IEnumerable&lt;Person&gt;</code> source.
Now we shall remind about <code>ForwardXPathNavigator</code> - a class we have built
back in 2002, which adds streaming transformations to .NET's xslt processor.
</p>
        <p>
While <code>XslCompiledTransform</code> is desperately obsolete, and no upgrade will
possibly follow; still it's among the fastest xslt 1.0 processors. With <code> ForwardXPathNavigator</code> we
add ability to transform input data of arbitrary size to this processor.
</p>
        <p>
We find it interesting that <a href="http://www.w3.org/TR/xslt-30/#streaming-concepts"> xslt
3.0 Working Draft defines streaming processing</a> in a way that closely matches rules
for <code>ForwardXPathNavigator</code>:
</p>
        <div style="padding-left: 1em; font-style: italic">
          <p>
Streaming achieves two important objectives: it allows large documents to be transformed
without requiring correspondingly large amounts of memory; and it allows the processor
to start producing output before it has finished receiving its input, thus reducing
latency.
</p>
          <p>
The rules for streamability, which are defined in detail in <i>19.3 Streamability
Analysis</i>, impose two main constraints:
</p>
          <ul>
            <li>
              <p>
The only nodes reachable from the node that is currently being processed are its attributes
and namespaces, its ancestors and their attributes and namespaces, and its descendants
and their attributes and namespaces. The siblings of the node, and the siblings of
its ancestors, are not reachable in the tree, and any attempt to use their values
is a static error. However, constructs (for example, simple forms of <code>xsl:number</code>,
and simple positional patterns) that require knowledge of the number of preceding
elements by name are permitted.
</p>
            </li>
            <li>
              <p>
When processing a given node in the tree, each descendant node can only be visited
once. Essentially this allows two styles of processing: either visit each of the children
once, and then process that child with the same restrictions applied; or process all
the descendants in a single pass, in which case it is not possible while processing
a descendant to make any further downward selection.
</p>
            </li>
          </ul>
        </div>
        <p>
The only significant difference between <code>ForwardXPathNavigator</code> and xlst
3.0 streaming is in that we reported violations of rules for streamability at runtime,
while xslt 3.0 attempts to perform this analysis at compile time.
</p>
        <p>
Here the C# code for the xslt streamed transformation:
</p>
        <p>
          <code> var transform = new XslCompiledTransform();<br /><br />
transform.Load("People.xslt");<br /><br />
// We have a streamed business data.<br />
var people = Data.CreateRandomData(10000, 0, 0, 10000);<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream =<br />
people.ToXmlStream("people", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
using(var output = File.Create("people.html"))<br />
{<br />
// XPath forward navigator is used as an input source.<br />
transform.Transform(<br /><strong>new ForwardXPathNavigator(reader)</strong>,<br />
new XsltArgumentList(),<br />
output);<br />
} </code>
        </p>
        <p>
Notice how <code>XmlReader</code> is wrapped into <code>ForwardXPathNavigator</code>.
</p>
        <p>
To complete the picture we need xslt that follows the streaming rules:
</p>
        <p>
          <code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>"<br />
xmlns:msxsl="urn:schemas-microsoft-com:xslt"<br />
xmlns:d="<a href="http://www.nesterovsky-bros.com">http://www.nesterovsky-bros.com</a>"<br />
exclude-result-prefixes="msxsl d"&gt;<br /><br />
&lt;xsl:output method="html" indent="yes"/&gt;<br /><br />
&lt;!-- Root template processed in the streaming mode. --&gt;<br />
&lt;xsl:template match="/d:people"&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;List of persons&lt;/title&gt;<br />
&lt;style type="text/css"&gt;<br />
.even<br />
{<br />
}<br /><br />
.odd<br />
{<br />
background: #d0d0d0;<br />
}<br />
&lt;/style&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;table border="1"&gt;<br />
&lt;tr&gt;<br />
&lt;th&gt;ID&lt;/th&gt;<br />
&lt;th&gt;First name&lt;/th&gt;<br />
&lt;th&gt;Last name&lt;/th&gt;<br />
&lt;th&gt;City&lt;/th&gt;<br />
&lt;th&gt;Title&lt;/th&gt;<br />
&lt;th&gt;Age&lt;/th&gt;<br />
&lt;/tr&gt;<br /><br />
&lt;xsl:for-each select="d:person"&gt;<br />
&lt;!-- 
<br />
Get element snapshot.<br />
A snapshot allows arbitrary access to the element's content.<br />
--&gt;<br />
&lt;xsl:variable name="person"&gt;<br />
&lt;xsl:copy-of select="."/&gt;<br />
&lt;/xsl:variable&gt;<br /><br />
&lt;xsl:variable name="position" select="position()"/&gt;<br /><br />
&lt;xsl:apply-templates mode="snapshot" select="msxsl:node-set($person)/d:person"&gt;<br />
&lt;xsl:with-param name="position" select="$position"/&gt;<br />
&lt;/xsl:apply-templates&gt;<br />
&lt;/xsl:for-each&gt;<br />
&lt;/table&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;xsl:template mode="snapshot" match="d:person"&gt;<br />
&lt;xsl:param name="position"/&gt;<br /><br />
&lt;tr&gt;<br />
&lt;xsl:attribute name="class"&gt;<br />
&lt;xsl:choose&gt;<br />
&lt;xsl:when test="$position mod 2 = 1"&gt;<br />
&lt;xsl:text&gt;odd&lt;/xsl:text&gt;<br />
&lt;/xsl:when&gt;<br />
&lt;xsl:otherwise&gt;<br />
&lt;xsl:text&gt;even&lt;/xsl:text&gt;<br />
&lt;/xsl:otherwise&gt;<br />
&lt;/xsl:choose&gt;<br />
&lt;/xsl:attribute&gt;<br /><br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Id"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:FirstName"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:LastName"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:City"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Title"/&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;<br />
&lt;xsl:value-of select="d:Age"/&gt;<br />
&lt;/td&gt;<br />
&lt;/tr&gt;<br />
&lt;/xsl:template&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </p>
        <p>
So, we have started with a streamed entity data, proceeded to the streamed XmlReader
and reached to the streamed xslt transformation.
</p>
        <p>
But at the final post about streaming we shall remind a simple way of building WCF
service returning html stream from our xslt transformation.
</p>
        <p>
The sources can be found at <a href="http://www.nesterovsky-bros.com/download/Streaming.zip"> Streaming.zip</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a" />
      </body>
      <title>Streaming xslt transformation with ForwardXPathNavigator</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx</link>
      <pubDate>Thu, 26 Jul 2012 18:49:51 GMT</pubDate>
      <description>&lt;p&gt;
In the previous &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx"&gt; post
about streaming&lt;/a&gt; we have dropped at the point where we have &lt;code&gt;XmlReader&lt;/code&gt; in
hands, which continously gets data from &lt;code&gt;IEnumerable&amp;lt;Person&amp;gt;&lt;/code&gt; source.
Now we shall remind about &lt;code&gt;ForwardXPathNavigator&lt;/code&gt; - a class we have built
back in 2002, which adds streaming transformations to .NET&amp;#39;s xslt processor.
&lt;/p&gt;
&lt;p&gt;
While &lt;code&gt;XslCompiledTransform&lt;/code&gt; is desperately obsolete, and no upgrade will
possibly follow; still it&amp;#39;s among the fastest xslt 1.0 processors. With &lt;code&gt; ForwardXPathNavigator&lt;/code&gt; we
add ability to transform input data of arbitrary size to this processor.
&lt;/p&gt;
&lt;p&gt;
We find it interesting that &lt;a href="http://www.w3.org/TR/xslt-30/#streaming-concepts"&gt; xslt
3.0 Working Draft defines streaming processing&lt;/a&gt; in a way that closely matches rules
for &lt;code&gt;ForwardXPathNavigator&lt;/code&gt;:
&lt;/p&gt;
&lt;div style="padding-left: 1em; font-style: italic"&gt;
&lt;p&gt;
Streaming achieves two important objectives: it allows large documents to be transformed
without requiring correspondingly large amounts of memory; and it allows the processor
to start producing output before it has finished receiving its input, thus reducing
latency.
&lt;/p&gt;
&lt;p&gt;
The rules for streamability, which are defined in detail in &lt;i&gt;19.3 Streamability
Analysis&lt;/i&gt;, impose two main constraints:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
The only nodes reachable from the node that is currently being processed are its attributes
and namespaces, its ancestors and their attributes and namespaces, and its descendants
and their attributes and namespaces. The siblings of the node, and the siblings of
its ancestors, are not reachable in the tree, and any attempt to use their values
is a static error. However, constructs (for example, simple forms of &lt;code&gt;xsl:number&lt;/code&gt;,
and simple positional patterns) that require knowledge of the number of preceding
elements by name are permitted.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
When processing a given node in the tree, each descendant node can only be visited
once. Essentially this allows two styles of processing: either visit each of the children
once, and then process that child with the same restrictions applied; or process all
the descendants in a single pass, in which case it is not possible while processing
a descendant to make any further downward selection.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;
The only significant difference between &lt;code&gt;ForwardXPathNavigator&lt;/code&gt; and xlst
3.0 streaming is in that we reported violations of rules for streamability at runtime,
while xslt 3.0 attempts to perform this analysis at compile time.
&lt;/p&gt;
&lt;p&gt;
Here the C# code for the xslt streamed transformation:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; var transform = new XslCompiledTransform();&lt;br /&gt;
&lt;br /&gt;
transform.Load("People.xslt");&lt;br /&gt;
&lt;br /&gt;
// We have a streamed business data.&lt;br /&gt;
var people = Data.CreateRandomData(10000, 0, 0, 10000);&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream =&lt;br /&gt;
people.ToXmlStream("people", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
using(var output = File.Create("people.html"))&lt;br /&gt;
{&lt;br /&gt;
// XPath forward navigator is used as an input source.&lt;br /&gt;
transform.Transform(&lt;br /&gt;
&lt;strong&gt;new ForwardXPathNavigator(reader)&lt;/strong&gt;,&lt;br /&gt;
new XsltArgumentList(),&lt;br /&gt;
output);&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice how &lt;code&gt;XmlReader&lt;/code&gt; is wrapped into &lt;code&gt;ForwardXPathNavigator&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
To complete the picture we need xslt that follows the streaming rules:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="&lt;a href="http://www.w3.org/1999/XSL/Transform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/a&gt;"&lt;br /&gt;
xmlns:msxsl="urn:schemas-microsoft-com:xslt"&lt;br /&gt;
xmlns:d="&lt;a href="http://www.nesterovsky-bros.com"&gt;http://www.nesterovsky-bros.com&lt;/a&gt;"&lt;br /&gt;
exclude-result-prefixes="msxsl d"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:output method="html" indent="yes"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Root template processed in the streaming mode. --&amp;gt;&lt;br /&gt;
&amp;lt;xsl:template match="/d:people"&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;List of persons&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;
.even&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.odd&lt;br /&gt;
{&lt;br /&gt;
background: #d0d0d0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;table border="1"&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;First name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Last name&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;City&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Title&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;th&amp;gt;Age&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:for-each select="d:person"&amp;gt;&lt;br /&gt;
&amp;lt;!-- 
&lt;br /&gt;
Get element snapshot.&lt;br /&gt;
A snapshot allows arbitrary access to the element&amp;#39;s content.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;xsl:variable name="person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:copy-of select="."/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:variable name="position" select="position()"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:apply-templates mode="snapshot" select="msxsl:node-set($person)/d:person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:with-param name="position" select="$position"/&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:apply-templates&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;xsl:template mode="snapshot" match="d:person"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:param name="position"/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;xsl:attribute name="class"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:choose&amp;gt;&lt;br /&gt;
&amp;lt;xsl:when test="$position mod 2 = 1"&amp;gt;&lt;br /&gt;
&amp;lt;xsl:text&amp;gt;odd&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:when&amp;gt;&lt;br /&gt;
&amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;lt;xsl:text&amp;gt;even&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Id"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:FirstName"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:LastName"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:City"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Title"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;&lt;br /&gt;
&amp;lt;xsl:value-of select="d:Age"/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
So, we have started with a streamed entity data, proceeded to the streamed XmlReader
and reached to the streamed xslt transformation.
&lt;/p&gt;
&lt;p&gt;
But at the final post about streaming we shall remind a simple way of building WCF
service returning html stream from our xslt transformation.
&lt;/p&gt;
&lt;p&gt;
The sources can be found at &lt;a href="http://www.nesterovsky-bros.com/download/Streaming.zip"&gt; Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=24094700-ca7e-4e73-8b30-fbdc9d72072a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,24094700-ca7e-4e73-8b30-fbdc9d72072a.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=382cb645-ac89-4cbb-b2f9-14913fb1f743</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,382cb645-ac89-4cbb-b2f9-14913fb1f743.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,382cb645-ac89-4cbb-b2f9-14913fb1f743.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=382cb645-ac89-4cbb-b2f9-14913fb1f743</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you're using .NET's <code>IDictionary&lt;K, V&gt;</code> you have probably
found its access API too boring. Indeed at each access point you have to write a code
like this:
</p>
        <p>
          <code> MyValueType value;<br />
var hasValue = dictionary.TryGetValue(key, out value);<br />
...</code>
        </p>
        <p>
In many, if not in most, cases the value is of a reference type, and you do not usually
store <code>null</code> values, so it would be fine if dictionary returned <code>null</code> when
value does not exist for the key.
</p>
        <p>
To deal with this small nuisance we have declared a couple of accessor extension methods:
</p>
        <p>
          <code>public static class Extensions<br />
{<br />
public static V Get&lt;K, V&gt;(this IDictionary&lt;K, V&gt; dictionary, K key)<br />
where V: class<br />
{<br />
V value;<br /><br />
if (key == null)<br />
{<br />
value = null;<br />
}<br />
else<br />
{<br />
dictionary.TryGetValue(key, out value);<br />
}<br /><br />
return value;<br />
}<br /><br />
public static V Get&lt;K, V&gt;(this IDictionary&lt;K, V&gt; dictionary, K? key)<br />
where V: class<br />
where K: struct<br />
{<br />
V value;<br /><br />
if (key == null)<br />
{<br />
value = null;<br />
}<br />
else<br />
{<br />
dictionary.TryGetValue(key.GetValueOrDefault(), out value);<br />
}<br /><br />
return value;<br />
}<br />
}</code>
        </p>
        <p>
These methods simplify dictionary access to:
</p>
        <p>
          <code>var value = dictionary.Get(key);<br />
...</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=382cb645-ac89-4cbb-b2f9-14913fb1f743" />
      </body>
      <title>Dictionary extension</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,382cb645-ac89-4cbb-b2f9-14913fb1f743.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/07/25/DictionaryExtension.aspx</link>
      <pubDate>Wed, 25 Jul 2012 05:54:33 GMT</pubDate>
      <description>  &lt;p&gt;
If you&amp;#39;re using .NET&amp;#39;s &lt;code&gt;IDictionary&amp;lt;K, V&amp;gt;&lt;/code&gt; you have probably
found its access API too boring. Indeed at each access point you have to write a code
like this:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; MyValueType value;&lt;br /&gt;
var hasValue = dictionary.TryGetValue(key, out value);&lt;br /&gt;
...&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In many, if not in most, cases the value is of a reference type, and you do not usually
store &lt;code&gt;null&lt;/code&gt; values, so it would be fine if dictionary returned &lt;code&gt;null&lt;/code&gt; when
value does not exist for the key.
&lt;/p&gt;
&lt;p&gt;
To deal with this small nuisance we have declared a couple of accessor extension methods:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;public static class Extensions&lt;br /&gt;
{&lt;br /&gt;
public static V Get&amp;lt;K, V&amp;gt;(this IDictionary&amp;lt;K, V&amp;gt; dictionary, K key)&lt;br /&gt;
where V: class&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if (key == null)&lt;br /&gt;
{&lt;br /&gt;
value = null;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
dictionary.TryGetValue(key, out value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static V Get&amp;lt;K, V&amp;gt;(this IDictionary&amp;lt;K, V&amp;gt; dictionary, K? key)&lt;br /&gt;
where V: class&lt;br /&gt;
where K: struct&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if (key == null)&lt;br /&gt;
{&lt;br /&gt;
value = null;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
dictionary.TryGetValue(key.GetValueOrDefault(), out value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return value;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
These methods simplify dictionary access to:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;var value = dictionary.Get(key);&lt;br /&gt;
...&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=382cb645-ac89-4cbb-b2f9-14913fb1f743" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,382cb645-ac89-4cbb-b2f9-14913fb1f743.aspx</comments>
      <category>.NET</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=60b3cb37-5da9-4f28-a35f-38d1ef3cccce</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=60b3cb37-5da9-4f28-a35f-38d1ef3cccce</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For some reason neither .NET's <code>XmlSerializer</code> nor <code>DataContractSerializer</code> allow
reading data through an <code>XmlReader</code>. These APIs work other way round writing
data into an <code>XmlWriter</code>. To get data through <code>XmlReader</code> one
needs to write it to some destination like a file or memory stream, and then to read
it using <code>XmlReader</code>. This complicates streaming design considerably.
</p>
        <p>
In fact the very same happens with other .NET APIs.
</p>
        <p>
We think the reason of why .NET designers preferred <code>XmlWriter</code> to <code>XmlReader</code> in
those APIs is that <code>XmlReader</code>'s implementation is a state machine
like, while <code>XmlWriter</code>'s implementation looks like a regular procedure.
It's much harder to <strong>manually</strong> write and to support a correct state
machine logic than a procedure.
</p>
        <p>
If history would have gone slightly different way, and if yield return, lambda, and
Enumerator API appeared before <code>XmlReader</code>, and <code>XmlWriter</code> then,
we think, both these classes looked differently. Xml source would have been described
with a <code>IEnumerable&lt;XmlEvent&gt;</code> instead of <code>XmlReader</code>,
and <code>XmlWriter</code> must be looked like a function receiving <code>IEnumerable&lt;XmlEvent&gt;</code>.
Implementing <code>XmlReader</code> would have meant a creating a enumerator. Yield
return and Enumerable API would have helped to implement it in a procedural way.
</p>
        <p>
But in our present we have to deal with the fact that <code>DataContractSerializer</code> should
write the data into <code>XmlWriter</code>, so let's assume we have a project
that uses Entity Framework to access the database, and that you have a data class <code>Person</code>,
and data access method <code>GetPeople()</code>:
</p>
        <p>
          <code> [DataContract(Name = "person", Namespace = "http://www.nesterovsky-bros.com")]<br />
public class Person 
<br />
{ 
<br />
[DataMember] public int Id { get; set; } 
<br />
[DataMember] public string FirstName { get; set; } 
<br />
[DataMember] public string LastName { get; set; } 
<br />
[DataMember] public string City { get; set; } 
<br />
[DataMember] public string Title { get; set; } 
<br />
[DataMember] public DateTime BirthDate { get; set; } 
<br />
[DataMember] public int Age { get; set; } 
<br />
} 
<br /><br />
public static IEnumerable&lt;Person&gt; GetPeople() { ... }</code>
        </p>
        <p>
And your goal is to expose result of <code>GetPeople()</code> as <code>XmlReader</code>.
We achieve result with three simple steps:
</p>
        <ol>
          <li>
Define <code>JoinedStream</code> - an input <code>Stream</code> implementation that
reads data from a enumeration of streams (<code>IEnumerable&lt;Stream&gt;</code>).</li>
          <li>
Build xml parts in the form of <code>IEnumerable&lt;Stream&gt;</code>.</li>
          <li>
Combine parts into final xml stream.</li>
        </ol>
        <p>
The code is rather simple, so here we qoute its essential part:
</p>
        <p>
          <code> public static class Extensions<br />
{<br />
public static Stream JoinStreams(this IEnumerable&lt;Stream&gt; streams, bool closeStreams
= true)<br />
{<br />
return new JoinedStream(streams, closeStreams);<br />
}<br /><br />
public static Stream ToXmlStream&lt;T&gt;(<br />
this IEnumerable&lt;T&gt; items, 
<br />
string rootName = null, 
<br />
string rootNamespace = null)<br />
{<br />
return items.ToXmlStreamParts&lt;T&gt;(rootName, rootNamespace).<br />
JoinStreams(false);<br />
}<br /><br />
private static IEnumerable&lt;Stream&gt; ToXmlStreamParts&lt;T&gt;(<br />
this IEnumerable&lt;T&gt; items,<br />
string rootName = null,<br />
string rootNamespace = null)<br />
{<br />
if (rootName == null)<br />
{<br />
rootName = "ArrayOfItems";<br />
}<br /><br />
if (rootNamespace == null)<br />
{<br />
rootNamespace = "";<br />
}<br /><br />
var serializer = new DataContractSerializer(typeof(T));<br />
var stream = new MemoryStream();<br />
var writer = XmlDictionaryWriter.CreateTextWriter(stream);<br /><br />
writer.WriteStartDocument();<br />
writer.WriteStartElement(rootName, rootNamespace);<br />
writer.WriteXmlnsAttribute("s", XmlSchema.Namespace);<br />
writer.WriteXmlnsAttribute("i", XmlSchema.InstanceNamespace);<br /><br />
foreach(var item in items)<br />
{<br />
serializer.WriteObject(writer, item);<br />
writer.WriteString(" ");<br /><br />
writer.Flush();<br />
stream.Position = 0;<br /><br />
yield return stream;<br /><br />
stream.Position = 0;<br />
stream.SetLength(0);<br />
}<br /><br />
writer.WriteEndElement();<br />
writer.WriteEndDocument();<br /><br />
writer.Flush();<br />
stream.Position = 0;<br /><br />
yield return stream;<br />
}<br /><br />
private class JoinedStream: Stream<br />
{<br />
public JoinedStream(IEnumerable&lt;Stream&gt; streams, bool closeStreams = true)<br />
...<br />
}<br />
} </code>
        </p>
        <p>
The use is even more simple:
</p>
        <p>
          <code> // We have a streamed business data.<br />
var people = GetPeople();<br /><br />
// We want to see it as streamed xml data.<br />
using(var stream = people.ToXmlStream("persons", "http://www.nesterovsky-bros.com"))<br />
using(var reader = XmlReader.Create(stream))<br />
{<br />
...<br />
}</code>
        </p>
        <p>
We have packed the sample into the project <a href="http://www.nesterovsky-bros.com/download/Streaming.zip">Streaming.zip</a>.
</p>
        <p>
In the <a href="http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx">next
post</a> we're going to remind about streaming processing in xslt. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce" />
      </body>
      <title>Streaming entity data</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2012/07/22/StreamingEntityData.aspx</link>
      <pubDate>Sun, 22 Jul 2012 20:38:29 GMT</pubDate>
      <description>  &lt;p&gt;
For some reason neither .NET&amp;#39;s &lt;code&gt;XmlSerializer&lt;/code&gt; nor &lt;code&gt;DataContractSerializer&lt;/code&gt; allow
reading data through an &lt;code&gt;XmlReader&lt;/code&gt;. These APIs work other way round writing
data into an &lt;code&gt;XmlWriter&lt;/code&gt;. To get data through &lt;code&gt;XmlReader&lt;/code&gt; one
needs to write it to some destination like a file or memory stream, and then to read
it using &lt;code&gt;XmlReader&lt;/code&gt;. This complicates streaming design considerably.
&lt;/p&gt;
&lt;p&gt;
In fact the very same happens with other .NET APIs.
&lt;/p&gt;
&lt;p&gt;
We think the reason of why .NET designers preferred &lt;code&gt;XmlWriter&lt;/code&gt; to &lt;code&gt;XmlReader&lt;/code&gt; in
those APIs is that &lt;code&gt;XmlReader&lt;/code&gt;&amp;#39;s implementation is a state machine
like, while &lt;code&gt;XmlWriter&lt;/code&gt;&amp;#39;s implementation looks like a regular procedure.
It&amp;#39;s much harder to &lt;strong&gt;manually&lt;/strong&gt; write and to support a correct state
machine logic than a procedure.
&lt;/p&gt;
&lt;p&gt;
If history would have gone slightly different way, and if yield return, lambda, and
Enumerator API appeared before &lt;code&gt;XmlReader&lt;/code&gt;, and &lt;code&gt;XmlWriter&lt;/code&gt; then,
we think, both these classes looked differently. Xml source would have been described
with a &lt;code&gt;IEnumerable&amp;lt;XmlEvent&amp;gt;&lt;/code&gt; instead of &lt;code&gt;XmlReader&lt;/code&gt;,
and &lt;code&gt;XmlWriter&lt;/code&gt; must be looked like a function receiving &lt;code&gt;IEnumerable&amp;lt;XmlEvent&amp;gt;&lt;/code&gt;.
Implementing &lt;code&gt;XmlReader&lt;/code&gt; would have meant a creating a enumerator. Yield
return and Enumerable API would have helped to implement it in a procedural way.
&lt;/p&gt;
&lt;p&gt;
But in our present we have to deal with the fact that &lt;code&gt;DataContractSerializer&lt;/code&gt; should
write the data into &lt;code&gt;XmlWriter&lt;/code&gt;, so let&amp;#39;s assume we have a project
that uses Entity Framework to access the database, and that you have a data class &lt;code&gt;Person&lt;/code&gt;,
and data access method &lt;code&gt;GetPeople()&lt;/code&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; [DataContract(Name = &amp;quot;person&amp;quot;, Namespace = &amp;quot;http://www.nesterovsky-bros.com&amp;quot;)]&lt;br /&gt;
public class Person 
&lt;br /&gt;
{ 
&lt;br /&gt;
[DataMember] public int Id { get; set; } 
&lt;br /&gt;
[DataMember] public string FirstName { get; set; } 
&lt;br /&gt;
[DataMember] public string LastName { get; set; } 
&lt;br /&gt;
[DataMember] public string City { get; set; } 
&lt;br /&gt;
[DataMember] public string Title { get; set; } 
&lt;br /&gt;
[DataMember] public DateTime BirthDate { get; set; } 
&lt;br /&gt;
[DataMember] public int Age { get; set; } 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;br /&gt;
public static IEnumerable&amp;lt;Person&amp;gt; GetPeople() { ... }&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And your goal is to expose result of &lt;code&gt;GetPeople()&lt;/code&gt; as &lt;code&gt;XmlReader&lt;/code&gt;.
We achieve result with three simple steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Define &lt;code&gt;JoinedStream&lt;/code&gt; - an input &lt;code&gt;Stream&lt;/code&gt; implementation that
reads data from a enumeration of streams (&lt;code&gt;IEnumerable&amp;lt;Stream&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
Build xml parts in the form of &lt;code&gt;IEnumerable&amp;lt;Stream&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
Combine parts into final xml stream.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The code is rather simple, so here we qoute its essential part:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; public static class Extensions&lt;br /&gt;
{&lt;br /&gt;
public static Stream JoinStreams(this IEnumerable&amp;lt;Stream&amp;gt; streams, bool closeStreams
= true)&lt;br /&gt;
{&lt;br /&gt;
return new JoinedStream(streams, closeStreams);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static Stream ToXmlStream&amp;lt;T&amp;gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&amp;gt; items, 
&lt;br /&gt;
string rootName = null, 
&lt;br /&gt;
string rootNamespace = null)&lt;br /&gt;
{&lt;br /&gt;
return items.ToXmlStreamParts&amp;lt;T&amp;gt;(rootName, rootNamespace).&lt;br /&gt;
JoinStreams(false);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private static IEnumerable&amp;lt;Stream&amp;gt; ToXmlStreamParts&amp;lt;T&amp;gt;(&lt;br /&gt;
this IEnumerable&amp;lt;T&amp;gt; items,&lt;br /&gt;
string rootName = null,&lt;br /&gt;
string rootNamespace = null)&lt;br /&gt;
{&lt;br /&gt;
if (rootName == null)&lt;br /&gt;
{&lt;br /&gt;
rootName = "ArrayOfItems";&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (rootNamespace == null)&lt;br /&gt;
{&lt;br /&gt;
rootNamespace = "";&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var serializer = new DataContractSerializer(typeof(T));&lt;br /&gt;
var stream = new MemoryStream();&lt;br /&gt;
var writer = XmlDictionaryWriter.CreateTextWriter(stream);&lt;br /&gt;
&lt;br /&gt;
writer.WriteStartDocument();&lt;br /&gt;
writer.WriteStartElement(rootName, rootNamespace);&lt;br /&gt;
writer.WriteXmlnsAttribute("s", XmlSchema.Namespace);&lt;br /&gt;
writer.WriteXmlnsAttribute("i", XmlSchema.InstanceNamespace);&lt;br /&gt;
&lt;br /&gt;
foreach(var item in items)&lt;br /&gt;
{&lt;br /&gt;
serializer.WriteObject(writer, item);&lt;br /&gt;
writer.WriteString(" ");&lt;br /&gt;
&lt;br /&gt;
writer.Flush();&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
&lt;br /&gt;
yield return stream;&lt;br /&gt;
&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
stream.SetLength(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
writer.WriteEndElement();&lt;br /&gt;
writer.WriteEndDocument();&lt;br /&gt;
&lt;br /&gt;
writer.Flush();&lt;br /&gt;
stream.Position = 0;&lt;br /&gt;
&lt;br /&gt;
yield return stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private class JoinedStream: Stream&lt;br /&gt;
{&lt;br /&gt;
public JoinedStream(IEnumerable&amp;lt;Stream&amp;gt; streams, bool closeStreams = true)&lt;br /&gt;
...&lt;br /&gt;
}&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The use is even more simple:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt; // We have a streamed business data.&lt;br /&gt;
var people = GetPeople();&lt;br /&gt;
&lt;br /&gt;
// We want to see it as streamed xml data.&lt;br /&gt;
using(var stream = people.ToXmlStream("persons", "http://www.nesterovsky-bros.com"))&lt;br /&gt;
using(var reader = XmlReader.Create(stream))&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
We have packed the sample into the project &lt;a href="http://www.nesterovsky-bros.com/download/Streaming.zip"&gt;Streaming.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
In the &lt;a href="http://www.nesterovsky-bros.com/weblog/2012/07/26/StreamingXsltTransformationWithForwardXPathNavigator.aspx"&gt;next
post&lt;/a&gt; we&amp;#39;re going to remind about streaming processing in xslt. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=60b3cb37-5da9-4f28-a35f-38d1ef3cccce" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,60b3cb37-5da9-4f28-a35f-38d1ef3cccce.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
      <category>xslt</category>
    </item>
  </channel>
</rss>