<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8714281344164032543</id><updated>2024-08-29T23:04:33.345-07:00</updated><category term="NHibernate"/><category term="DDD"/><category term="TDD"/><category term="bi-directional"/><category term="invariant"/><category term=".net 4.5"/><category term="APM"/><category term="AR"/><category term="Aggregate"/><category term="Async CTP"/><category term="Asynchronous Programming"/><category term="Binding"/><category term="Classic TDD"/><category term="DI"/><category term="DTO"/><category term="Dependency"/><category term="LINQ"/><category term="Mockist TDD"/><category term="NotifyProperyChanged"/><category term="Object Graph"/><category term="OpenAsync"/><category term="POCO"/><category term="RGR"/><category term="Red-Green-Refactor"/><category term="SRP"/><category term="T4"/><category term="UUT"/><category term="Velocity"/><category term="WPF"/><category term="await"/><category term="clean code"/><category term="concurrent users"/><category term="cross cutting"/><category term="db lock"/><category term="encapsulation"/><category term="hbm files"/><category term="hbm2net"/><category term="high cohesion"/><category term="internal members"/><category term="isolated tests"/><category term="performance"/><category term="repository"/><category term="root"/><category term="transient"/><category term="validation"/><title type='text'>{ progmatica }</title><subtitle type='html'>Good software design | Itzik Saban</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-3131628928042098984</id><published>2014-02-19T13:43:00.000-08:00</published><updated>2014-03-04T00:55:42.171-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="clean code"/><category scheme="http://www.blogger.com/atom/ns#" term="encapsulation"/><category scheme="http://www.blogger.com/atom/ns#" term="high cohesion"/><category scheme="http://www.blogger.com/atom/ns#" term="SRP"/><title type='text'>Keeping clean code principles for esoteric classes...?</title><content type='html'>Let&#39;s face it, most of our classes will never by used by more than a lonely class. If this is the case, it seems that many of the clean code principles are meaningless for those classes... Or are they?&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;SRP&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
One principle to consider, is the &lt;i&gt;Single Responsibility Principle.&lt;/i&gt;&amp;nbsp;In his book, &lt;i&gt;Principles, &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;aa8f4b93-8078-41cf-83e9-037711d6aee1&quot; id=&quot;39ee317f-ebe8-4bde-875c-d6195b192fa2&quot;&gt;Paterens and&lt;/span&gt; Practices&amp;nbsp;&lt;/i&gt;(PPP), &quot;Uncle Bob&quot; gives the example of the &lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;Rectangle &lt;/i&gt;&lt;/span&gt;class. This class has 2 responsibilities: the first is to provide a mathematical model of the geometry of a rectangle, and the other is to give some GUI services such&amp;nbsp;as drawing it on the screen. Two different applications use this class:&amp;nbsp;&lt;i style=&quot;color: #e06666;&quot;&gt;&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;0246dac4-269b-4a0b-9a6e-1762a2ba0880&quot; id=&quot;cc376634-29a1-4a87-b86c-3e18045a80e4&quot;&gt;&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;125fc6d9-769e-4d2f-80b9-1688995672c6&quot; id=&quot;19c92f43-6048-47c0-85b6-4de92c9af07f&quot;&gt;GraphicalApplication&lt;/span&gt;&lt;/span&gt; &lt;/i&gt;and&amp;nbsp;&lt;i style=&quot;color: #e06666;&quot;&gt;ComputationalGeometryApplication. &lt;/i&gt;If a change to the&amp;nbsp;&lt;i style=&quot;color: #e06666;&quot;&gt;&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;0cfce620-adff-4b10-94ab-677831d2cbe6&quot; id=&quot;ed02589c-8c34-4c69-9934-3dce6a3cb4f4&quot;&gt;&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;9772a215-1cb8-4137-9730-5eab5a8bf511&quot; id=&quot;d582112e-0e1d-4a45-a4f0-3867cfed2924&quot;&gt;GraphicalApplication&lt;/span&gt;&lt;/span&gt; &lt;/i&gt;causes the&amp;nbsp;&lt;i style=&quot;color: #e06666;&quot;&gt;Rectangle &lt;/i&gt;class to change for some reason, the other application, &lt;i style=&quot;color: #e06666;&quot;&gt;ComputationalGeometryApplication&lt;/i&gt;, needs to be&amp;nbsp;rebuilt, retested, and redeployed.&lt;br /&gt;
That really sounds bad, but as I stated at the beginning, most of our classes are never being used by more than one class, not to mention more than one application...&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;High Cohesion&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Another principle is the &lt;i&gt;High Cohesion Principle&lt;/i&gt;. This principle states that most of a class&#39;s members should be in use by most of the functionality it exposes. Usually, classes that violate this principle, expose many functionalities and therefore have many private members that need to be instantiated. When you need to use some &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;be23a185-9dae-4324-8c4f-6f1fcbf93a54&quot; id=&quot;c072b00e-d943-41dd-957a-c98c7b4e4ded&quot;&gt;functionality&lt;/span&gt; of such a class, you must go through a painful instantiation process - you must provide &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;7fe3be8b-aaf5-4d5c-b493-c18c75225ecc&quot; id=&quot;1953854b-2ba4-4157-a820-0e5b959effc4&quot;&gt;&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;be23a185-9dae-4324-8c4f-6f1fcbf93a54&quot; id=&quot;9d0c21b2-4187-46cd-b1b7-224bd4762314&quot;&gt;it&lt;/span&gt;&lt;/span&gt; all the state it needs, even if most of this state is irrelevant to your needs.&lt;br /&gt;
And yet again, if a class is&amp;nbsp;only&amp;nbsp;being used by a lonely class, then probably all the functionalities and all the required variables &lt;u style=&quot;font-weight: bold;&quot;&gt;are&lt;/u&gt; &lt;u style=&quot;font-weight: bold;&quot;&gt;truly&lt;/u&gt;&amp;nbsp;relevant to that lonely class.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Encapsulation&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
The last principle I would like to consider is encapsulation. In his other book, &lt;i&gt;Clean Code&lt;/i&gt;, &quot;Uncle Bob&quot; says about encapsulation:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i&gt;&quot;There is a reason that we keep our variables private. We don’t want anyone else to depend on them. We want to keep the freedom to change their type or implementation on a whim or an impulse.&amp;nbsp;&lt;/i&gt;&lt;i&gt;Why, then, do so many programmers automatically add getters and setters&amp;nbsp;&lt;/i&gt;&lt;i&gt;to their objects, exposing their private variables as if they were public?&quot;&lt;/i&gt;&lt;/blockquote&gt;
&lt;/blockquote&gt;
But if a class of mine is only being used by a lonely class, what&#39;s the big deal? If I will ever need to change the type or the implementation of a variable my class exposes, I will only have to change two classes - my class and the class that &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;3e12e8ad-f504-4f52-b6e4-51c5cf0322c7&quot; id=&quot;b88f5a7e-c140-429a-ad03-65a089bb0d06&quot;&gt;use&lt;/span&gt; it, not such a big deal...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;But wait...&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Having said all that, I still encourage you to keep&amp;nbsp;those principles for &lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;ALL&amp;nbsp;&lt;/b&gt;&lt;/span&gt;your classes, even for those that are only being used by a lonely class.&lt;br /&gt;
&lt;br /&gt;
It&#39;s true, most of your classes will never be in use by more than one class, not to mention more than one application.&lt;br /&gt;
And yet, &lt;b&gt;sometime in the future, some of them will!&lt;/b&gt; You never know which classes are those; you never know when will&amp;nbsp;they&amp;nbsp;start to be in use in other places; you never know how much are&amp;nbsp;they&amp;nbsp;going to be used.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Therefore, treat each and every class as if it is going to be used by many classes, there is a chance it will...</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/3131628928042098984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2014/02/keeping-clean-code-principles-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3131628928042098984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3131628928042098984'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2014/02/keeping-clean-code-principles-for.html' title='Keeping clean code principles for esoteric classes...?'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-1391104938324167701</id><published>2013-10-31T08:36:00.000-07:00</published><updated>2014-03-02T23:37:22.935-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Classic TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="DI"/><category scheme="http://www.blogger.com/atom/ns#" term="isolated tests"/><category scheme="http://www.blogger.com/atom/ns#" term="Mockist TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><title type='text'>Mockist TDD vs Classic TDD</title><content type='html'>&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
If you want to practice TDD there are two main approaches to choose from:
mockist TDD or classic TDD (Martin Fowler). In this post &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;85285981-35de-421d-8ec6-81e4baea8606&quot; id=&quot;181708d7-60d6-4144-9eb9-9db22a0ba405&quot;&gt;i&lt;/span&gt; would like to compare between the two.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
First, I’ll describe the two approaches and later I will list the pros and
cons of the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;ad465143-562e-49af-b7d8-77bd5ba55879&quot; id=&quot;610a1dea-58a1-45b7-a912-ecf6260a0d9e&quot;&gt;mockist&lt;/span&gt; approach. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;Mockist TDD&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
With this approach, you&#39;re working in a high granularity, meaning every
class has its own test fixture. As a result, each test fixture should only
test&amp;nbsp;&lt;b&gt;one&lt;/b&gt; CUT (&lt;b&gt;C&lt;/b&gt;lass &lt;b&gt;U&lt;/b&gt;nder &lt;b&gt;T&lt;/b&gt;est) and &lt;b&gt;none&lt;/b&gt; of
the classes the CUT depends on, assuming they all have their own test fixtures. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;
Suppose we have a class A that uses class
B. To achieve the high granularity we’ve talked about, TestFixtureA must use a Test Double
of B, as shown in figure 1:&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBj1i9hohuxQUPHBaidinxpnSlLZ_q1TYN3PFlh-aRJVzFVwyGdeKAm6eCo88WJJ23EnFFkC5RGeS2xwIClBZbjH1DFHQAhcmnX83nWojihWKv6rcFugaBljUfUp8_-b1olZZw0l-IWDUU/s1600/figure1.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBj1i9hohuxQUPHBaidinxpnSlLZ_q1TYN3PFlh-aRJVzFVwyGdeKAm6eCo88WJJ23EnFFkC5RGeS2xwIClBZbjH1DFHQAhcmnX83nWojihWKv6rcFugaBljUfUp8_-b1olZZw0l-IWDUU/s1600/figure1.PNG&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 1&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br clear=&quot;ALL&quot; /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
Of course our design must support dependency injection to achieve that
and it means &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;2f102fe9-84be-403d-91b4-c5e29700f09c&quot; id=&quot;d6928dee-ae5f-4abf-bdee-799ed70324c7&quot;&gt;class&lt;/span&gt; A must work against an interface of B and it also requires a
way to inject a concrete instance of B into class A (via constructor/setters/IoC
etc.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
That’s why this approach is called &lt;i&gt;Mockist TDD&lt;/i&gt; since it has an
extensive use of Mocks (Test Doubles). It is also called &lt;i&gt;Isolated Testing&lt;/i&gt;
since each class is tested in an isolated way.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;
&lt;b&gt;NOTE&lt;/b&gt;: we isolate class A from class B even if class B is a regular
business class that has no interactions with any external resources such as
DB\web service\files system etc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;Classic TDD&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
With this approach, you&#39;re working in a low granularity, meaning every &lt;b&gt;graph&lt;/b&gt;
of classes has its own test fixture. As a result, each test fixture covers a
&lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;b6872c70-9ca9-45fb-a12f-24f0980354da&quot; id=&quot;b1584e26-8c40-4179-a926-c5f1630b416c&quot;&gt;graph&lt;/span&gt; of classes implicitly by testing the graph&#39;s root.&lt;/div&gt;
&lt;br clear=&quot;ALL&quot; /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxb_2k-BrsY1qkCLNnnSNI-OZRi5nKYSjbSSslgivJj-WJFULSrxH27vm9u6Yi7Ua7PNkrsK7SeaIzFz9kshXEXqQ-CwfM4aUbQcYz4eCXMnqXYhB7zLujYlQFRnX3bLaatCEsMBN9nzZ/s1600/figure2.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxb_2k-BrsY1qkCLNnnSNI-OZRi5nKYSjbSSslgivJj-WJFULSrxH27vm9u6Yi7Ua7PNkrsK7SeaIzFz9kshXEXqQ-CwfM4aUbQcYz4eCXMnqXYhB7zLujYlQFRnX3bLaatCEsMBN9nzZ/s1600/figure2.PNG&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 2&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Usually you don&#39;t test the inner classes of the graph explicitly since
they are already tested implicitly by the tests of their root, thus, you avoid
coverage duplications. This lets you keep the inner classes with an &lt;span style=&quot;color: #548dd4; mso-themecolor: text2; mso-themetint: 153;&quot;&gt;internal&lt;/span&gt;
access modifier unless they are in use by other projects.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;Pros &amp;amp; Cons&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
Let’s describe the pros and cons of the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;503b4736-95c4-437a-a12c-9975898d8b38&quot; id=&quot;62747aa2-57ea-44ab-98f8-93b2e6de7c6c&quot;&gt;mockist&lt;/span&gt; approach.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;b&gt;&lt;u&gt;Pros&lt;o:p&gt;&lt;/o:p&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpFirst&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;1.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;More TDD’ish &lt;/b&gt;–
since all the classes the CUT depends on are mocked, you can start testing the
CUT without implementing the classes it depends on. Think about the classic
approach, when you come to test some CUT, you should first implement its
dependencies, but before that you should first implement their dependencies and
so forth.&lt;b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;2.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;High granularity &lt;/b&gt;–
this means:&lt;b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 72pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;a.&lt;span style=&quot;font-size: 7pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;Smaller test fixtures – one
per class, unlike one per &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;b48af8b7-dc4f-48e4-b5d5-6f29429fcef8&quot; id=&quot;dff2c1ac-be1a-47ce-b0d9-6f32cbc5f53d&quot;&gt;graph&lt;/span&gt; of classes in the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;b48af8b7-dc4f-48e4-b5d5-6f29429fcef8&quot; id=&quot;4344cdad-db59-4e45-bbde-f2e591080ce3&quot;&gt;classic&lt;/span&gt; approach.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 72pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;b.&lt;span style=&quot;font-size: 7pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;Smaller test setups – take
a look on TestFixtureA at figure 2: the &lt;i&gt;Arrange&lt;/i&gt; phase
(Arrange-Act-Assert) of tests like this is quite large since it has to &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;a01d9808-b905-4a32-8ed0-9766fbe05dfe&quot; id=&quot;a7b0c30d-2b60-4333-8675-90b028e7640b&quot;&gt;setup&lt;/span&gt; a state
for too many classes in the graph. This quite a crucial issue – the
bigger the test, the bigger the risk of having bugs in the test itself.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 72pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;c.&lt;span style=&quot;font-size: 7pt;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;Frequent &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;4b9a1254-34d8-40f8-9562-87796ce83a69&quot; id=&quot;b4139fca-6ad9-4de7-a93a-c40d1654a961&quot;&gt;checkins&lt;/span&gt;/commits –
think about it, with the classic approach, your tests won’t pass before all the
classes the CUT depends on are implemented correctly, thus, the frequency of
your &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;4b9a1254-34d8-40f8-9562-87796ce83a69&quot; id=&quot;ff3516f1-df5b-4183-bff6-992b37e5ae91&quot;&gt;checkins&lt;/span&gt; (commits) is reduced dramatically (you don&#39;t want to commit &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;4b9a1254-34d8-40f8-9562-87796ce83a69&quot; id=&quot;0d28add8-4264-4e6b-9a2d-7edb99d27c07&quot;&gt;red&lt;/span&gt; tests).&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpLast&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;3.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;More alternatives to
do DI – &lt;/b&gt;take a look at figure 3, suppose you need to inject different
concretes of interface I into class C. With the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;0b591aba-b563-4346-af07-778e69fee6ce&quot; id=&quot;9ed3c5b9-d193-45c1-a76a-ba0d3f4636cc&quot;&gt;mockist&lt;/span&gt; approach, which heavily
relies on injections, the code that initializes &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;0b591aba-b563-4346-af07-778e69fee6ce&quot; id=&quot;981f9353-bdc5-4bd4-b94c-44de68d5c6fa&quot;&gt;class&lt;/span&gt; A also initializes class
B and inject it to class A, and also initializes &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;0b591aba-b563-4346-af07-778e69fee6ce&quot; id=&quot;b5ea7634-ffdd-46ce-8030-c4389f50ae31&quot;&gt;class C&lt;/span&gt; and inject it to class
B. Therefore, it can easily inject a concrete class of interface I into class C. See figure
4 for example. On the other hand, with the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;94ddf075-3040-4379-98e4-f2336e447834&quot; id=&quot;2fbd343f-a66c-411f-bbcf-8351d3af5b0c&quot;&gt;classic&lt;/span&gt; approach, the code that
initialize class A doesn’t have access to the inner classes of the graph (B, C and I) and
therefore its only way to inject a concrete class of interface I into class C is by using some framework of IoC.&lt;b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1qmlycQkP7NFOjiA11GM0Ywn8CNh0uXpGqmQGvHen8sf-m3U51e9k6k-_hMVdnGSMIkyhQ10uxO_nLp26YknTPPWsbld2Ye_jZczfetkg3fXibs0NLRRbwlPxg7Cdi9aBV-ZUbgU3Jdyx/s1600/figure3.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1qmlycQkP7NFOjiA11GM0Ywn8CNh0uXpGqmQGvHen8sf-m3U51e9k6k-_hMVdnGSMIkyhQ10uxO_nLp26YknTPPWsbld2Ye_jZczfetkg3fXibs0NLRRbwlPxg7Cdi9aBV-ZUbgU3Jdyx/s1600/figure3.PNG&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 3&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 0.0001pt 36pt; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVrRj9xkGUaQfh_1uA6ZRSHp1uCnnNaf1QjPUNqf46Wn3sN3MrKEhQpWvfZf-vc49ZNAU48MUr6TVLxE5D3KbqsMa1PDbISykXuwkhVQfvvDNX7AaxT-DN-2KTVwl4jxGBA2plz6Z6T64T/s1600/figure4.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVrRj9xkGUaQfh_1uA6ZRSHp1uCnnNaf1QjPUNqf46Wn3sN3MrKEhQpWvfZf-vc49ZNAU48MUr6TVLxE5D3KbqsMa1PDbISykXuwkhVQfvvDNX7AaxT-DN-2KTVwl4jxGBA2plz6Z6T64T/s1600/figure4.PNG&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 4&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;Cons&lt;o:p&gt;&lt;/o:p&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpFirst&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;1.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;Much more interfaces
and injections &lt;/b&gt;– with the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;9d41c20b-ef9b-4eb5-b8df-f049ab6ec7a4&quot; id=&quot;11a820dc-72f8-4654-a12b-aa48bae2b292&quot;&gt;mockist&lt;/span&gt; approach, for almost every class, you have
at least one interface. In addition, there is some kind of &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;dec64d27-adca-41b5-9982-6cfdefb2b7f7&quot; id=&quot;d13d02ca-870b-471e-97cb-2eb9fc8c2e61&quot;&gt;injections&lt;/span&gt;
inflation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpMiddle&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;2.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;Weaker encapsulation
&lt;/b&gt;– each class exposes its relations with the classes it depends on so that
they can be injected into it and also to allow &lt;i&gt;behavior verification&lt;/i&gt;,
this partly weaken&lt;span class=&quot;apple-converted-space&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;apple-converted-space&quot;&gt;&lt;span style=&quot;background-color: white; background-position: initial initial; background-repeat: initial initial; font-family: Arial, sans-serif; font-size: 11.5pt; line-height: 115%;&quot;&gt; &lt;/span&gt;&lt;/span&gt;the
encapsulation.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoListParagraphCxSpLast&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; margin: 0cm 0cm 10pt 36pt; text-indent: -18pt; unicode-bidi: embed;&quot;&gt;
&lt;!--[if !supportLists]--&gt;&lt;b&gt;3.&lt;span style=&quot;font-size: 7pt; font-weight: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/b&gt;&lt;!--[endif]--&gt;&lt;span dir=&quot;LTR&quot;&gt;&lt;/span&gt;&lt;b&gt;High vulnerability
to refactoring &lt;/b&gt;– with the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;61216b89-263c-4359-9d3a-a293acb6e1fb&quot; id=&quot;d548af25-5c47-4e1b-b17d-6a981ec9a4fb&quot;&gt;mockist&lt;/span&gt; approach, every change in the interaction
between two classes, requires changes in some tests, since tests usually aware of
the interactions between classes (see &lt;i&gt;behavior verification&lt;/i&gt;). With the
classic approach, on the other hand, you usually do &lt;i&gt;state verification &lt;/i&gt;and
thus, the tests are not aware of the interaction between classes.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;Conclusions:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
I personally definitely prefer the &lt;span class=&quot;GINGER_SOFTWARE_mark&quot; ginger_software_uiphraseguid=&quot;1690784a-fbcc-40e1-86dc-5da5de57e08f&quot; id=&quot;2b7b877b-97a5-43a7-a986-0293fbb120d4&quot;&gt;mockist&lt;/span&gt; approach for one main reason –
I cannot see how &lt;b&gt;truly&lt;/b&gt; TDD is possible without it.&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; dir=&quot;LTR&quot; style=&quot;direction: ltr; unicode-bidi: embed;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/1391104938324167701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2013/10/mockist-tdd-vs-classic-tdd.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/1391104938324167701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/1391104938324167701'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2013/10/mockist-tdd-vs-classic-tdd.html' title='Mockist TDD vs Classic TDD'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBj1i9hohuxQUPHBaidinxpnSlLZ_q1TYN3PFlh-aRJVzFVwyGdeKAm6eCo88WJJ23EnFFkC5RGeS2xwIClBZbjH1DFHQAhcmnX83nWojihWKv6rcFugaBljUfUp8_-b1olZZw0l-IWDUU/s72-c/figure1.PNG" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-8812415595097093492</id><published>2013-10-28T07:40:00.001-07:00</published><updated>2013-10-28T07:43:22.723-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Red-Green-Refactor"/><category scheme="http://www.blogger.com/atom/ns#" term="RGR"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="UUT"/><title type='text'>Red-Green-Refactor</title><content type='html'>The most recommended way to implement TDD is to follow the &lt;span style=&quot;color: red;&quot;&gt;Red&lt;/span&gt;-&lt;span style=&quot;color: #38761d;&quot;&gt;Green&lt;/span&gt;-Refactor
path. In this post I would like to talk about the importance of the &lt;span style=&quot;color: red;&quot;&gt;Red-&lt;/span&gt;&lt;span style=&quot;color: #38761d;&quot;&gt;Green&amp;nbsp;&lt;/span&gt;steps.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: 21px; line-height: 24px;&quot;&gt;Good tests&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
A good test is &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;whenever the UUT (&lt;b&gt;U&lt;/b&gt;nit &lt;b&gt;U&lt;/b&gt;nder &lt;b&gt;T&lt;/b&gt;est) is correct
and is &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;whenever the UUT is incorrect.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 115%;&quot;&gt;Bad tests&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
There are 3 types of bad tests:&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -18pt;&quot;&gt;Tests that are &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;when the
UUT is correct and are also &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;when the UUT is incorrect. Obviously, tests of this
type will be discovered immediately.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -18pt;&quot;&gt;Tests that are &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;when the
UUT is correct and are &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;when the UUT is incorrect. This type of tests is
worse than the previous type since it’s not always detectable. And if the UUT
is incorrect (and thus the test is &lt;span style=&quot;color: #38761d;&quot;&gt;green&lt;/span&gt;…), it will provide you a false
confidence that everything is OK.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;text-indent: -18pt;&quot;&gt;Tests that are &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;when the
UUT is correct and are &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;when UUT is incorrect. This type is at least as
bad as the previous type of tests. Tests like this are worthless.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoListParagraphCxSpLast&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -18.0pt;&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The &lt;span style=&quot;color: red;&quot;&gt;Red&lt;/span&gt;-&lt;span style=&quot;color: #38761d;&quot;&gt;Green&lt;/span&gt;-Refactor (RGR) path will most probably lead
you to good tests in most cases. Why? If you follow that path, the first step is the &lt;span style=&quot;color: red;&quot;&gt;Red &lt;/span&gt;step. In that step you should first write your test &lt;b&gt;before&lt;/b&gt; the
UUT is implemented (thus, incorrect). This almost ensures you that your test
will be &lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;when the UUT is incorrect. The second step is the &lt;span style=&quot;color: #38761d;&quot;&gt;Green &lt;/span&gt;step, in which
you implement your UUT correctly and you expect your test to be &lt;span style=&quot;color: #38761d;&quot;&gt;green&lt;/span&gt;. This
almost ensures you that your test will be &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;when the UUT is correct.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Eventually this
leads you, with a high degree of certainty, to a ‘good test’ as described above
(&lt;span style=&quot;color: red;&quot;&gt;red &lt;/span&gt;when the UUT is incorrect and &lt;span style=&quot;color: #38761d;&quot;&gt;green &lt;/span&gt;when the UUT is correct).&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Remember: we’re not talking about pure mathematics here,
there will be times when you will follow the RGR path and still end up with ‘bad
tests’. Yet, following this path will enhance the robustness of your tests
dramatically.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 21px; line-height: 24px;&quot;&gt;Conclusions:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;line-height: 24px;&quot;&gt;Many times, people tend to write their tests only after they have completed the UUT and thus, skipping the &lt;span style=&quot;color: red;&quot;&gt;Red &lt;/span&gt;step. This might lead them to bad tests of type 2 and 3 as mentioned.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;line-height: 24px;&quot;&gt;&lt;b&gt;My conclusion&lt;/b&gt;: follow the RGR path.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/8812415595097093492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2013/10/red-green-refactor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/8812415595097093492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/8812415595097093492'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2013/10/red-green-refactor.html' title='Red-Green-Refactor'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-8379003855300880554</id><published>2013-04-22T00:25:00.000-07:00</published><updated>2013-12-29T04:23:07.911-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AR"/><category scheme="http://www.blogger.com/atom/ns#" term="DDD"/><category scheme="http://www.blogger.com/atom/ns#" term="internal members"/><category scheme="http://www.blogger.com/atom/ns#" term="invariant"/><category scheme="http://www.blogger.com/atom/ns#" term="repository"/><category scheme="http://www.blogger.com/atom/ns#" term="transient"/><category scheme="http://www.blogger.com/atom/ns#" term="validation"/><title type='text'>Referencing the internal members of an aggregate.</title><content type='html'>There is a lot of confusion around the Aggregate pattern [DDD] and especially around the question: whether or not it&#39;s&amp;nbsp;OK for an external object to reference an internal member of an aggregate.&lt;br /&gt;
&lt;br /&gt;
First of all, let&#39;s see what the DDD book has to say about it:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;b&gt;&lt;span style=&quot;background-color: white; color: #222222; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px; text-align: -webkit-auto;&quot;&gt;&lt;i&gt;&quot;Choose one Entity to be the root of each Aggregate, and control all access to the objects inside the boundary through the root. Allow external objects to hold references to the root only. Transient references to internal members&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;i&gt;can be passed out for use within a single operation only. Because the root controls access, it can not be blindsided by changes to the internals.&quot;&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;br /&gt;
This is a little bit confusing. On the one hand, the root&amp;nbsp;&lt;b&gt;&lt;i&gt;controls all access to the internal members&lt;/i&gt;&amp;nbsp;&lt;/b&gt;and&lt;b&gt; &lt;i&gt;it can not be blindsided by changes to the internals&lt;/i&gt;&lt;/b&gt;, but on the other hand, &lt;b&gt;&lt;i&gt;transient references to internal members may be passed out&lt;/i&gt;&lt;/b&gt;. This means that an external object can mess around with the state of the internals and thus, blindside the AR...&lt;br /&gt;
Sounds like a paradox, or is it?&lt;br /&gt;
&lt;br /&gt;
Consider the following example: suppose we have a Travel Agency web site in which users can make flights reservations. A&amp;nbsp;reasonable invariant would be: &lt;i&gt;total reserved sits for a flight can not exceed the total number of sits on the plain.&amp;nbsp;&lt;/i&gt;This rule is a true invariant since breaking it will cause a total chaos on the day of the flight. Imagine 60 people claiming their sits on a plain with 50 sits only...&lt;br /&gt;
&lt;br /&gt;
To enforce this invariant we will probably have the following objects in one aggregate:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMqRlTNBTLk9V7n9oamAN_bt1hGS5aKdkveI0VIvhTYR0inT2pNI3RhLcECCocuFqRpbpAcQoXX-bIjsidwA-bqdpM9o6GfHMbQd6aJgngywADa9yDjWnhM-YpR7yp_2w-ps2pni6qfVn0/s1600/FlightAR.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMqRlTNBTLk9V7n9oamAN_bt1hGS5aKdkveI0VIvhTYR0inT2pNI3RhLcECCocuFqRpbpAcQoXX-bIjsidwA-bqdpM9o6GfHMbQd6aJgngywADa9yDjWnhM-YpR7yp_2w-ps2pni6qfVn0/s1600/FlightAR.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Here &lt;i&gt;Flight is&amp;nbsp;&lt;/i&gt;the AR&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Our mission is to make sure that the state in the DB &lt;b&gt;NEVER(!)&amp;nbsp;&lt;/b&gt;violates this invariant.&lt;br /&gt;
There are several techniques to achieve that.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Tell, don&#39;t ask.&lt;/span&gt;&lt;/h4&gt;
The first technique is to let the AR encapsulate all the internal members and every changes to their states will be done through it. In our example, &lt;i&gt;Flight &lt;/i&gt;(which is the AR) will encapsulate &lt;i&gt;Reservations. &lt;/i&gt;Flight will expose methods like&amp;nbsp;&lt;i&gt;ReserveSits, UpdateReservation, CancelReservation &lt;/i&gt;and thus will be able to enforce the invariant. This technique might work, but only if all the internal members of the aggregate are fully encapsulated.&amp;nbsp;Unfortunately it&amp;nbsp;breaks the rule of:&amp;nbsp;&lt;b&gt;&lt;span style=&quot;background-color: white; color: #222222; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px; text-align: -webkit-auto;&quot;&gt;&lt;i&gt;Transient references to internal members&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;i&gt;can be passed out for use within a single operation only&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
It used to be my favorite technique but it&#39;s quite a pain in the ***. What if the aggregate consists of a dipper graph of objects? Eventually you will end up with an AR that has an endless list of methods which all their purpose is to encapsulate every action on the internal members.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Brute force validation.&lt;/span&gt;&lt;/h4&gt;
We need a different technique, a one that will allow external objects to hold transient references to internal members and at the same time will not blindside the AR. The one i prefer is what I call a &quot;brute force validation&quot; (BFV). With this technique you ask the AR to check all its invariants before &lt;b&gt;each&amp;nbsp;&lt;/b&gt;time&amp;nbsp;you are about change its state in the DB. You will probably have a method in the AR called &lt;i&gt;CheckInvariants&amp;nbsp;&lt;/i&gt;or something like that.&lt;br /&gt;
&lt;br /&gt;
There are a few issues to consider with BFV. First of all, you&amp;nbsp;&lt;b&gt;MUST &lt;/b&gt;not forget to call&amp;nbsp;&lt;i&gt;CheckInvariants&lt;/i&gt; before&amp;nbsp;&lt;b&gt;each&amp;nbsp;&lt;/b&gt;time you are saving the AR to the DB. This means you need to find all the places in code in which you are saving the AR and to invoke this method there. Ouch...&lt;br /&gt;
And what if some developer will add a new place in code that saves the AR to the DB? If this developer will forget to call the&amp;nbsp;&lt;i&gt;CheckInvariants &lt;/i&gt;method&amp;nbsp;- your DB will be corrupted...&lt;br /&gt;
&lt;br /&gt;
Fortunately, the &lt;i&gt;Repository &lt;/i&gt;pattern&amp;nbsp;is coming to the rescue. According to this pattern, each aggregate should have its own repository (usually with the name of the AR as a prefix e.g. FlightRepository). Each AR repository should have a method that saves the AR in&amp;nbsp;the DB along with all its internals and &lt;b&gt;only &lt;/b&gt;them. According to this pattern, the AR repository should be the only place to save the AR to the DB. This sounds like a good place to call the&amp;nbsp;&lt;i&gt;CheckInvariants &lt;/i&gt;method - inside the repository itself, right before the saving action.&lt;br /&gt;
&lt;br /&gt;
But there is another issue: what happens if an external object modifies one of the internals and then tries to save this internal directly to the DB? This will bypass the&amp;nbsp;&lt;i&gt;CheckInvariants &lt;/i&gt;method which is located only at the AR. Actually, if you are following the Repository pattern correctly, you don&#39;t have to worry about it - repositories should only expose methods that save ARs and &lt;b&gt;not &lt;/b&gt;regular entities. Therefore this scenario is not possible.&lt;br /&gt;
&lt;br /&gt;
One last issue to consider. Imagine the following scenario: some AR holds a reference to an internal member of another AR. In our example, let say that another AR, the class&amp;nbsp;&lt;i&gt;User,&amp;nbsp;&lt;/i&gt;is holding a list of all the user&#39;s &lt;i&gt;Reservations&lt;/i&gt;. Those&lt;i&gt; Reservations&lt;/i&gt; are also&amp;nbsp;internal members of some &lt;i&gt;Flights.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs3st5zdKsWP34MY7UNKE-km7vFEXQQjpriwqRMUlQ5kSLFk99X304AufWR1m3L_zymcglSfpiwXKoa9dZ7mrnMaGaO2kT-sA7kheuqIEfvKB2LikNzUCY7Big7zPk4aDFNWWzZzHpgbjc/s1600/FlightAR.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs3st5zdKsWP34MY7UNKE-km7vFEXQQjpriwqRMUlQ5kSLFk99X304AufWR1m3L_zymcglSfpiwXKoa9dZ7mrnMaGaO2kT-sA7kheuqIEfvKB2LikNzUCY7Big7zPk4aDFNWWzZzHpgbjc/s1600/FlightAR.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Is this possible?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;W&lt;/i&gt;hat if some&amp;nbsp;&lt;i&gt;User &lt;/i&gt;object modifies a&amp;nbsp;&lt;i&gt;Reservation &lt;/i&gt;and then this&amp;nbsp;&lt;i&gt;User &lt;/i&gt;object&lt;i&gt;&amp;nbsp;&lt;/i&gt;is sent to &lt;i&gt;UserRepository &lt;/i&gt;to be saved? According to the Repository pattern this is all perfectly legal - a &lt;i&gt;User &lt;/i&gt;is an AR and hence&amp;nbsp;should have a repository to save it.&lt;br /&gt;
But still, we do have a problem here, the modification to the &lt;i&gt;Reservation &lt;/i&gt;object may violate some of the invariants of a &lt;i&gt;Flight&lt;/i&gt; and this &lt;i&gt;Flight&amp;nbsp;&lt;/i&gt;won&#39;t even know about it. Do not worry, if you&#39;re following the Aggregate pattern correctly, this scenario is also not possible. It&#39;s true, at some point, a &lt;i&gt;User &lt;/i&gt;object may hold a reference to some &lt;i&gt;Reservation &lt;/i&gt;of some &lt;i&gt;Flight&lt;/i&gt;, but this reference is &lt;b&gt;Transient&lt;/b&gt;, meaning, the &lt;i&gt;Reservation &lt;/i&gt;is not a member of &lt;i&gt;User. &lt;/i&gt;Therefore, even if some&amp;nbsp;&lt;i&gt;User &lt;/i&gt;object&lt;i&gt;&amp;nbsp;&lt;/i&gt;will modify a&amp;nbsp;&lt;i&gt;Reservation &lt;/i&gt;and then this &lt;i&gt;User &lt;/i&gt;object will be saved to the DB, the&amp;nbsp;&lt;i&gt;Reservation &lt;/i&gt;will not be saved along with it.&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-JNlkKNik7O_YVjs5II9vISwQHuAsTh2nkAueWPDx0L10fNfcj9bYDb_BMWdYzYDJxe4gjvgVNv3lyNY1QSIeeOpSL8Xb4pMKZUcdLoV_HVArXAIj7U0IrK0JTbr5iL_Wvxgx72qqY59C/s1600/FlightAR1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-JNlkKNik7O_YVjs5II9vISwQHuAsTh2nkAueWPDx0L10fNfcj9bYDb_BMWdYzYDJxe4gjvgVNv3lyNY1QSIeeOpSL8Xb4pMKZUcdLoV_HVArXAIj7U0IrK0JTbr5iL_Wvxgx72qqY59C/s1600/FlightAR1.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;An entity can be a member of only one AR&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Conclusion&lt;/span&gt;&lt;/h4&gt;
Brute force validation allows you to expose the AR&#39;s internal members (if needed) and yet, to be&amp;nbsp;confident that even if some of the invariants are violated - these violations will be discovered before saving the AR to the DB.&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/8379003855300880554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2013/04/referencing-internal-members-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/8379003855300880554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/8379003855300880554'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2013/04/referencing-internal-members-of.html' title='Referencing the internal members of an aggregate.'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMqRlTNBTLk9V7n9oamAN_bt1hGS5aKdkveI0VIvhTYR0inT2pNI3RhLcECCocuFqRpbpAcQoXX-bIjsidwA-bqdpM9o6GfHMbQd6aJgngywADa9yDjWnhM-YpR7yp_2w-ps2pni6qfVn0/s72-c/FlightAR.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-7125968428638358056</id><published>2012-06-06T06:55:00.000-07:00</published><updated>2012-06-06T21:49:12.442-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net 4.5"/><category scheme="http://www.blogger.com/atom/ns#" term="APM"/><category scheme="http://www.blogger.com/atom/ns#" term="Async CTP"/><category scheme="http://www.blogger.com/atom/ns#" term="Asynchronous Programming"/><category scheme="http://www.blogger.com/atom/ns#" term="await"/><category scheme="http://www.blogger.com/atom/ns#" term="OpenAsync"/><title type='text'>Asynchronous Programming in .Net 4.5</title><content type='html'>In this post i would like to talk about .net 4.5 and the enhancement made there for the Asynchronous Programming.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Introduction&lt;/span&gt;&lt;br /&gt;
Threads are very expensive - they consume memory (1Mb per thread) and they consume time in their initialization, finalization and context switching. Therefore, threads should be managed carefully by the thread pool. The goal is to create threads no more than needed.&lt;br /&gt;
&lt;br /&gt;
When a thread is executing an I/O operation such as networking, file system, etc., the thread is being blocked by Windows while the hardware device is performing the I/O operation. The thread will continue to run when the device will finish its operation. So far so good since a waiting thread should not waste a precious CPU time.&lt;br /&gt;
But there is a problem though - a blocked thread does not return to the thread pool and thus forcing the thread pool to create new threads for incoming requests, or even worse - reject incoming&amp;nbsp;
requests.&lt;br /&gt;
Not only I/O operations block threads. For example: SqlConnection.Open can block a thread until it will have an available connection to supply.&lt;br /&gt;
&lt;br /&gt;
Consider the following piece of code:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS7aeVDo_j_LMAnLm9wx7SxdHU2qSRKAP2vc3Wgdz7wT5uw-WKolRF7fpewyF_uHAvyuQSGuAj3NnnTROlh4vqIxLU1lRZPfIqZkEnRM_dRZCFPOBGkg5JrnKAfN-gza_fJiM5RqGpuW90/s1600/Capture.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS7aeVDo_j_LMAnLm9wx7SxdHU2qSRKAP2vc3Wgdz7wT5uw-WKolRF7fpewyF_uHAvyuQSGuAj3NnnTROlh4vqIxLU1lRZPfIqZkEnRM_dRZCFPOBGkg5JrnKAfN-gza_fJiM5RqGpuW90/s1600/Capture.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;figure 1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here we have 4 blocking operations which are highlighted in yellow.&lt;br /&gt;
This code is quite problematic for a scalable server. Imagine a server that serves tens, hundreds or even thousands of concurrent requests - this means that while waiting for these operations to finish and thus finally release the thread, new requests are keep coming in and since threads are blocked and are not being released back to the thread pool, the thread pool will produce more and more threads in order to handle the incoming requests. At best, the thread pool will manage to handle all the incoming requests by producing more and more threads which will eventually decrease the performance dramatically (as stated above). At worst, the number of threads will reach the limit of the thread pool and thus, incoming requests will be queued.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Asynchronous Programming&lt;/span&gt;&lt;br /&gt;
Previous versions of .net prior to 4.5 already had a solution (not completed) to the problem stated above.&lt;br /&gt;
The solution was in the form of Asynchronous Programming which includes all the Begin_xxx and End_xxx methods. For example: SqlCommand.BeginExecuteReader, WebRequest.BeginGetResponse and so forth.&lt;br /&gt;
&lt;br /&gt;
Below, is an example code:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAt2fIWinR5cUkQvJGL6nP0rluvupHN3bttQMT7g96h9aXAopxNcX944Vz7aqTkLA4_fG0xWe3bWXKBFYIqq9wwcUK72dTuwT0lBrelM8YtC-nK82poZUaWp1p2JwD_osxDu9cSpmli3EU/s1600/Capture1.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAt2fIWinR5cUkQvJGL6nP0rluvupHN3bttQMT7g96h9aXAopxNcX944Vz7aqTkLA4_fG0xWe3bWXKBFYIqq9wwcUK72dTuwT0lBrelM8YtC-nK82poZUaWp1p2JwD_osxDu9cSpmli3EU/s1600/Capture1.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;figure 2&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Async Programming in general is not the objective of this post so I&#39;m not going to explain in details how SqlCommand.BeginExecuteReader works. But i will say that when the thread is invoking&amp;nbsp;BeginExecuteReader&amp;nbsp;it is not blocked and it is free to continue to the next line of execution. When the SqlCommand finishes to execute the query against the DB, the inline method supplied to&amp;nbsp;BeginExecuteReader&amp;nbsp;will be invoked by some available thread, not necessarily the one who called&amp;nbsp;BeginExecuteReader. And thus, no threads are being blocked like they were if they were invoking&amp;nbsp;SqlCommand.ExecuteReader.&lt;br /&gt;
&lt;br /&gt;
As mentioned, this code belongs to .net versions prior to 4.5 and it has some major drawbacks:&lt;br /&gt;
1 -&amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;using&amp;nbsp;&lt;/span&gt;statements can not be used.&lt;br /&gt;
2 - Inline methods are not so intuitive.&lt;br /&gt;
3 -&amp;nbsp;&amp;nbsp;there are no&amp;nbsp;async&amp;nbsp;executions&amp;nbsp;for&amp;nbsp;DataReader.GetInt32,&amp;nbsp;DataReader.Read and&amp;nbsp;SqlConnection.Open. Therefore, blocking operations are not fully avoided.&lt;br /&gt;
&lt;br /&gt;
Actually,&amp;nbsp;SqlConnection.Open can be a real bottleneck. I made an experiment: I have created an asp.net application with 2 pages: light.aspx and heavy.aspx. The light one should perform a quick and simple operation, say, some simple calculation. The heavy one should perform a heavy and long operation, say, executing some heavy query against the db which might take a few seconds.&lt;br /&gt;
The heavy page will use a connection pool (not a thread pool!) of 30 connections.&lt;br /&gt;
I have implemented the heavy page in 2 versions: a synchronous version which will implement the code from figure 1 and an asynchronous version which will implement the code from figure 2.&lt;br /&gt;
For both versions, a simple client application that i&#39;ve built, sent 1000 requests for the heavy page and then 1000 requests for the light page.&lt;br /&gt;
What I&#39;m interested to see in such an experiment is how the light pages are responding when there are many requests for heavy pages that are consuming threads from the thread pool.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve expected that&amp;nbsp;the results&amp;nbsp;of the asynchronous version will be better since less threads will be blocked by the heavy page and thus less threads will be created by the thread pool.&lt;br /&gt;
I was wrong - at both versions the server became irresponsive at some point for both light and heavy pages.&lt;br /&gt;
I expected this for the synchronous version, but why did it also happened for the asynchronous version?&lt;br /&gt;
The answer is this: the first 30 requests were not blocked since&amp;nbsp;SqlConnection.Open had available connections to supply them. But from the 31th request and forth,&amp;nbsp;SqlConnection.Open blocked all threads until some of the first 30 threads will finish their job and release their connections. Thus, more and more threads became blocked, hence, increasing the load on the thread pool. At some point, new incoming requests, whether they were for heavy pages or light pages could not be handled and thus where queued.&lt;br /&gt;
&lt;br /&gt;
Now we&#39;ll see how .net 4.5 can help us solve this problem.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;.Net 4.5 - Asynchronous Programming&lt;/span&gt;
&lt;br /&gt;
In the code below you can see the new way to implement async operations with .net 4.5:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjbEUwJdxVm_Ov7LM7v1mRJIcqFjrDckBIFV5x40ewSRvi4sBYK2XSylTU0cjwCTeOWRECclb6jnA6xUeopdSuoVIY6kH2gA25f8I7YdAVzNG8v383fit9IA0Dja6RJ6MSBvpV18qWfQ7N/s1600/Capture3.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjbEUwJdxVm_Ov7LM7v1mRJIcqFjrDckBIFV5x40ewSRvi4sBYK2XSylTU0cjwCTeOWRECclb6jnA6xUeopdSuoVIY6kH2gA25f8I7YdAVzNG8v383fit9IA0Dja6RJ6MSBvpV18qWfQ7N/s1600/Capture3.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;figure 3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
The first thing to notice about is two new keywords: &lt;span style=&quot;color: blue;&quot;&gt;await &lt;/span&gt;and &lt;span style=&quot;color: blue;&quot;&gt;async&lt;/span&gt;. To support these 2 new keywords you have 2 options: upgrade VS 2010 by installing&amp;nbsp;&lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=23691&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;&amp;nbsp;and then&amp;nbsp;&lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=9983&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;, or you can start working with higher versions of VS: 2011 or 2012.&lt;br /&gt;
But since we are using features of the async ADO.Net which is part of the .net 4.5 - we cannot use VS 2010 which doesn&#39;t support them anyway (as far as i know).&lt;br /&gt;
&lt;br /&gt;
OK, now let&#39;s analyze it.&lt;br /&gt;
In figure 4 you can see the control flow of the thread that will execute the method shown in figure 3. There you can see that thread &lt;i&gt;t1 &lt;/i&gt;is the executing thread and it is the one who calls&amp;nbsp;&lt;i&gt;SqlConnect &lt;/i&gt;from within &lt;i&gt;Foo&lt;/i&gt;.&lt;br /&gt;
When the thread is executing the line: &amp;nbsp;&lt;i&gt;await con.OpenAsync(); &lt;/i&gt;ado.net is trying to allocate a free and available connection in the connection pool. If all connections are taken (and the limit is reached), the thread will skip all the code below that line and will return back to the point in which it entered&amp;nbsp;&lt;i&gt;SqlConnect &lt;/i&gt;and will continue to execute the &lt;i&gt;Foo &lt;/i&gt;method. The code below&amp;nbsp;&lt;i&gt;await con.OpenAsync(); &lt;/i&gt;will be executed when some connection will become available and it will be executed by a&amp;nbsp;thread which most likely won&#39;t be&amp;nbsp;&lt;i&gt;t1 &lt;/i&gt;(&lt;i&gt;t2 &lt;/i&gt;in figure 4).&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdiDrKQpX6xP-jZTAHaY9GAhjjhEw-kYXNv3gO35_os3SuUosUpRH5r1N9hnb2eLE-cS_0c-csuEe8nTu6Czm9D6QHoDgZd4bLS65B7ioNT8Oe6fYdtgFy_nWJFYKsPSEJmtRcIDB1ZZpt/s1600/AsyncFlow.PNG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;193&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdiDrKQpX6xP-jZTAHaY9GAhjjhEw-kYXNv3gO35_os3SuUosUpRH5r1N9hnb2eLE-cS_0c-csuEe8nTu6Czm9D6QHoDgZd4bLS65B7ioNT8Oe6fYdtgFy_nWJFYKsPSEJmtRcIDB1ZZpt/s320/AsyncFlow.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;figure 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
Of course, the same goes for all the other lines involving the&amp;nbsp;&lt;i&gt;await &lt;/i&gt;keyword, meaning that when the new thread (&lt;i&gt;t2&lt;/i&gt;), which will execute the rest of the code, will reach a line 99 in figure 3, it will skip all the lines below it and return back to the thread pool.&lt;br /&gt;
&lt;br /&gt;
This ensures us that&amp;nbsp;&lt;i&gt;SqlConnect&lt;/i&gt;&amp;nbsp;does not involve any blocking points and thus, no thread will be blocked by&amp;nbsp;&lt;i&gt;SqlConnect&lt;/i&gt;&amp;nbsp;and this will increase the overall availability of the thread pool&#39;s threads.&lt;br /&gt;
&lt;br /&gt;
I went back to my experiment and changed the heavy page to implement the code from figure 3.&lt;br /&gt;
Just to remind you, what&amp;nbsp;
I&#39;m interested to see in such an experiment is how the light pages are responding when there are many requests for heavy pages that are consuming threads from the thread pool.&lt;br /&gt;
I run my test again and... good news! for the new version, the responsiveness of the server for light pages was the same whether heavy pages were running in the background or whether not. It means that the heavy pages did not add any significant load on the thread pool.&lt;br /&gt;
By monitoring the thread pool this came up to be true - the thread pool hardly needed new threads to handle the requests for both heavy and light pages.</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/7125968428638358056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2012/06/asynchronous-programming-in-net-45.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/7125968428638358056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/7125968428638358056'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2012/06/asynchronous-programming-in-net-45.html' title='Asynchronous Programming in .Net 4.5'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS7aeVDo_j_LMAnLm9wx7SxdHU2qSRKAP2vc3Wgdz7wT5uw-WKolRF7fpewyF_uHAvyuQSGuAj3NnnTROlh4vqIxLU1lRZPfIqZkEnRM_dRZCFPOBGkg5JrnKAfN-gza_fJiM5RqGpuW90/s72-c/Capture.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-4458645268770632547</id><published>2012-03-08T05:26:00.000-08:00</published><updated>2013-05-06T03:42:35.227-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Aggregate"/><category scheme="http://www.blogger.com/atom/ns#" term="concurrent users"/><category scheme="http://www.blogger.com/atom/ns#" term="db lock"/><category scheme="http://www.blogger.com/atom/ns#" term="DDD"/><category scheme="http://www.blogger.com/atom/ns#" term="invariant"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><category scheme="http://www.blogger.com/atom/ns#" term="root"/><title type='text'>Aggregate [DDD] - boosting the performance.</title><content type='html'>In this post I would like to tell you about some experiment I&#39;ve made - put to the test the &lt;b style=&quot;font-style: italic;&quot;&gt;Aggregate &lt;/b&gt;[DDD]&lt;b style=&quot;font-style: italic;&quot;&gt;&amp;nbsp;&lt;/b&gt;pattern.&lt;br /&gt;
&lt;br /&gt;
From Eric Evan&#39;s book:&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px;&quot;&gt;&lt;i&gt;It is difficult to guarantee the consistency of changes to objects in a model with complex associations. Invariants need to be maintained that apply to closely related groups of objects, not just discrete objects. Yet cautious locking schemes cause multiple users to interfere pointlessly with each other and make a system unusable. [DDD, p. 126]&amp;nbsp;&lt;/i&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px;&quot;&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;
&lt;span style=&quot;background-color: white; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px;&quot;&gt;According to this, the&amp;nbsp;&lt;/span&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;Aggregate &lt;/i&gt;pattern should provide a more efficient way to enforce invariants in a multiple users&amp;nbsp;environment&amp;nbsp;by&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; text-align: left;&quot;&gt;significantly&lt;/span&gt;&amp;nbsp;&lt;/span&gt;reducing DB locks.&lt;br /&gt;
OK, so I&#39;ve put this to the test.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve simulated&amp;nbsp;an&amp;nbsp;eCommerce&amp;nbsp;store with 80,000 concurrent users which try to add/edit different OrderLines of 1000 different Orders. One or more users can work&amp;nbsp;&lt;span style=&quot;background-color: white; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;simultaneously on the same Order.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;&lt;u&gt;Invariant&lt;/u&gt;&lt;/b&gt;: each Order has a MaximumTotal that cannot be exceeded by the sum of the Amount of all of its OrderLines.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;I&#39;ve used SQL Server 2005 +&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: inherit; text-align: left;&quot;&gt;NHibernate 3.1.0.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;So first I tried to enforce this invariant without the &lt;/span&gt;&lt;b style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;Aggregate &lt;/i&gt;&lt;/b&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;pattern&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;. I&#39;ve created an OrderLineService with 2 methods:&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj377S9mqyuo7w71OJToGsuIbukwy81gbMdRVSfnaKv-6DZuOQKoF6mtXfKbHWo7C4D807KWOnfE5uDqGIIdCJY6zLlEZxdXnk7wdmyStlYVUvEz8iraXACUO_buaykSYbBq3Dk8N4yH_t3/s1600/update_no_aggr.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj377S9mqyuo7w71OJToGsuIbukwy81gbMdRVSfnaKv-6DZuOQKoF6mtXfKbHWo7C4D807KWOnfE5uDqGIIdCJY6zLlEZxdXnk7wdmyStlYVUvEz8iraXACUO_buaykSYbBq3Dk8N4yH_t3/s1600/update_no_aggr.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
This method gets an &lt;i&gt;orderId &lt;/i&gt;and an &lt;i&gt;amount&lt;/i&gt;. It fetches the Order eagerly with its OrderLines, find the first OrderLine and tries to update its Amount with the &lt;i&gt;amount &lt;/i&gt;passed as parameter. Before updating the amount, we must check that the invariant is not going to be violated, so we calculate the sum of all of the OrderLines of the given Order.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
But what if right after we found out that the invariant is not going to be violated and right before committing the changes - a second concurrent user has added a new OrderLine that might violate the invariant?&lt;br /&gt;
For example:&lt;br /&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Order #123 has a MaxTotal of 100$. It has 2 OrderLines with 40$ each.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Two requests (r1 and r2) are arriving to the server simultaneously - r1 wants to update the first OrderLine to 50$ and r2 wants to add a new OrderLine with an amount of 20$. If both will succeed the invariant will be violated.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 fetches Order #123.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2 fetches&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;Order #123.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 checks the invariant, find it to be ok and updates the amount (but yet to commit).&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;checks the invariant, find it to be ok and adds a new OrderLine.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2 commits.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Now in the db we have 3 OrderLines to Order #123: 40$, 40$, 20$ - invariant is kept.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 commits.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Now in the db we have 3 OrderLines to Order #123: 50$, 40$, 20$ - invariant is violated&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp;and we don&#39;t even know about it.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
To prevent this we must lock the table with RepeatableRead isolation (in MSSQL 2005 this isolation level also prevents the &lt;a href=&quot;http://michaeljswart.com/2010/03/transaction-phenomena-part-3-the-phantom-read/&quot; target=&quot;_blank&quot;&gt;phantom reads&lt;/a&gt;). This means that until that transaction is not committed - &lt;b&gt;NO OTHER USER CAN INSERT A NEW ORDERLINE, NOT EVEN IF THIS NEW ORDERLINE BELONGS TO ANOTHER ORDER!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The next Method:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqNekwQsAIn1W_zZmwvANgxgtJ8jvRqTU2WgP82iX6LBrS9TO8QbVrOsOtDsRCFwdJIKnnsFGKvvGagxRtLYJJtcvuo4EKqLmlqByL3NgkoXd9cz7uEPTrOAdENmffpfFU2FmRqC_0RyD1/s1600/insert_no_aggr.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqNekwQsAIn1W_zZmwvANgxgtJ8jvRqTU2WgP82iX6LBrS9TO8QbVrOsOtDsRCFwdJIKnnsFGKvvGagxRtLYJJtcvuo4EKqLmlqByL3NgkoXd9cz7uEPTrOAdENmffpfFU2FmRqC_0RyD1/s1600/insert_no_aggr.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
This method gets an &lt;i&gt;orderId &lt;/i&gt;and an &lt;i&gt;amount&lt;/i&gt;. It fetches the Order eagerly with its OrderLines and tries to add a new OrderLine with the &lt;i&gt;amount &lt;/i&gt;passed as a parameter. Before adding the new OrderLine, we must check that the invariant is not going to be violated, so we calculate the sum of all of the OrderLines of the given Order.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
Again, for the same reason as stated above, we must lock the table with RepeatableRead isolation.&lt;br /&gt;
&lt;br /&gt;
Here is the code that simulates 80,000 concurrent users, all are trying to add/edit different OrderLines with different amounts.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5uj6DvC-7NPsXmqnbEKj1-r3sSqBXw-TQZ0x4QJ8cMM9CZUEZbfvSxHAIrK0ObW1k3Rdg4yPivQSPopoMGe88KX6fCgqZmTA3x0eruvBe-yB_q00UUyoygZfToEbf-Caz9tfTdqtM4b_C/s1600/program.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5uj6DvC-7NPsXmqnbEKj1-r3sSqBXw-TQZ0x4QJ8cMM9CZUEZbfvSxHAIrK0ObW1k3Rdg4yPivQSPopoMGe88KX6fCgqZmTA3x0eruvBe-yB_q00UUyoygZfToEbf-Caz9tfTdqtM4b_C/s1600/program.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
By not using the Aggregate pattern it took ~&lt;b&gt;200,000&lt;/b&gt;&amp;nbsp;milliseconds&amp;nbsp;to process 80,000 concurrent requests.&lt;br /&gt;
&lt;br /&gt;
Now let&#39;s simulate a scenario in which we do use the&amp;nbsp;Aggregate pattern.&lt;br /&gt;
First I&#39;ve added two new methods to class&amp;nbsp;&lt;span style=&quot;background-color: white;&quot;&gt;Order:&amp;nbsp;&lt;/span&gt;UpdateFirstOrderLine and&amp;nbsp;AddOrderLine.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpCTNjfRE6l37GV6koakN6O0uQuPqeMJ1X0LxOhI0kqZdL6cCT2-w1If7MIvUwuT6f6ETQH6wEbiLwtBkd8Z1tHKRS1WVp2if-8pOwRvCWWcAeQuVdx7pPqScO9d-7nLo0woUVUxA_JjHF/s1600/OrderClass.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpCTNjfRE6l37GV6koakN6O0uQuPqeMJ1X0LxOhI0kqZdL6cCT2-w1If7MIvUwuT6f6ETQH6wEbiLwtBkd8Z1tHKRS1WVp2if-8pOwRvCWWcAeQuVdx7pPqScO9d-7nLo0woUVUxA_JjHF/s1600/OrderClass.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;Next I&#39;ve also add 2 new methods to&amp;nbsp;OrderLineService:&amp;nbsp;&lt;/span&gt;UpdateFirstOrderLineWithAggr and&amp;nbsp;InsertNewOrderLineWithAggr:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzou0e1fAHknwdKzjJkWOu7eQO-ErMO69rFJdozjwQLa-XV_lswCrJ64i1irhUKS7mtgqyUoVZ1XYDf9wQg7jA1xhbKR-jpx21bknZP37eOeGuDrprK5No91kw4U-zNw9-wlEUg0kMr9lC/s1600/InsertUpdateAggr.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzou0e1fAHknwdKzjJkWOu7eQO-ErMO69rFJdozjwQLa-XV_lswCrJ64i1irhUKS7mtgqyUoVZ1XYDf9wQg7jA1xhbKR-jpx21bknZP37eOeGuDrprK5No91kw4U-zNw9-wlEUg0kMr9lC/s1600/InsertUpdateAggr.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
As you can see, in these 2 methods I haven&#39;t used the RepeatableRead isolation level for none of the transactions, meaning 2 concurrent users can&amp;nbsp;&lt;span style=&quot;background-color: white;&quot;&gt;simultaneously&lt;/span&gt;&amp;nbsp;add 2 different OrderLines to the same Order and&amp;nbsp;potentially&amp;nbsp;violate the invariant.&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;So how can we&amp;nbsp;tolerate&amp;nbsp;this?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
Let&#39;s look at the pattern&#39;s definition again:
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px; text-align: -webkit-auto;&quot;&gt;&lt;i&gt;Choose one Entity to be the root of each Aggregate, and control all access to the objects inside the boundary through the root.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Any changes to Order.OrderLines list, whether if it&#39;s adding a new OrderLine or&amp;nbsp;modifying&amp;nbsp;an existing one, will be done through the root (Order) and will increase the root&#39;s Version (&lt;i&gt;optimistic-lock&lt;/i&gt;). Therefore, if two concurrent users will try to add two different OrderLines to the same Order - one will succeed and the other will fail for trying to update an out-of-date instance of Order.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;With this mechanism, I don&#39;t have to lock the whole OrderLines table any more - i can prevent&amp;nbsp;simultaneous modifications through the root object.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Let&#39;s simulate this.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Order #123 has a MaxTotal of 100$ and Version 2. It has 2 OrderLines with 40$ each.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Two requests (r1 and r2) are arriving to the server simultaneously - r1 wants to update the first OrderLine to 50$ and r2 wants to add a new OrderLine with an amount of 20$. If both will succeed the invariant will be violated.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 fetches Order #123. Version is 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2 fetches&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;Order #123.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;Version is 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 checks the invariant, find it to be ok and updates the amount (but yet to commit).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;checks the invariant, find it to be ok and adds a new OrderLine.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r2 commits.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;Now in the db we have 3 OrderLines to Order #123: 40$, 40$, 20$ - invariant is kept. Also, the Version is now 3.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;r1 tries to commit but with Version 2 and fails.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;For that mechanism to work properly, we need to be 100% sure that any changes to one of the &lt;i&gt;Aggregate&#39;s &lt;/i&gt;members will increase the root&#39;s version. As Evan says:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;background-color: white; font-family: Verdana, sans-serif; font-size: 12px; line-height: 20px; text-align: -webkit-auto;&quot;&gt;&lt;i&gt;Because the root controls access, it cannot be blindsided by changes to the internals&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;&amp;nbsp;(&lt;/span&gt;&lt;a href=&quot;http://itziksaban.blogspot.co.il/2013/04/referencing-internal-members-of.html&quot; style=&quot;line-height: 20px;&quot; target=&quot;_blank&quot;&gt;see also&lt;/a&gt;&lt;span style=&quot;line-height: 20px;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;line-height: 20px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
Here is the code that simulates 80,000 concurrent users, all are trying to add/edit different OrderLines with different amounts:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3EmdRGvzwhRNi6QTF0yKwHQhWn_FDpQOahVI923MrpdFiJQmqQZBg4r3e_dxg8cDuKSW7mQE0WCMDOuXm_FAdZSE4ihIaqO5E8IpbxRiLv9iTt5mBhkeTHBFkwHIQL7B0ieiD1r_HXeaJ/s1600/program_aggr.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3EmdRGvzwhRNi6QTF0yKwHQhWn_FDpQOahVI923MrpdFiJQmqQZBg4r3e_dxg8cDuKSW7mQE0WCMDOuXm_FAdZSE4ihIaqO5E8IpbxRiLv9iTt5mBhkeTHBFkwHIQL7B0ieiD1r_HXeaJ/s1600/program_aggr.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
By using the Aggregate pattern it took ~&lt;b&gt;54,000&lt;/b&gt;&amp;nbsp;milliseconds&amp;nbsp;to process 80,000 concurrent requests.&lt;br /&gt;
&lt;br /&gt;
Around &lt;b&gt;4 times faster!!!&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
All source files can be found&amp;nbsp;&lt;a href=&quot;http://i.minus.com/1337150835/SomcCyLRqwmtWZLXoTOtFw/dbav1pW1nNJUJ1.rar&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/4458645268770632547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2012/03/aggregate-ddd-boosting-performance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/4458645268770632547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/4458645268770632547'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2012/03/aggregate-ddd-boosting-performance.html' title='Aggregate [DDD] - boosting the performance.'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj377S9mqyuo7w71OJToGsuIbukwy81gbMdRVSfnaKv-6DZuOQKoF6mtXfKbHWo7C4D807KWOnfE5uDqGIIdCJY6zLlEZxdXnk7wdmyStlYVUvEz8iraXACUO_buaykSYbBq3Dk8N4yH_t3/s72-c/update_no_aggr.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-3815014914965930227</id><published>2012-01-17T05:48:00.000-08:00</published><updated>2012-06-07T03:44:18.236-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cross cutting"/><category scheme="http://www.blogger.com/atom/ns#" term="DTO"/><category scheme="http://www.blogger.com/atom/ns#" term="hbm files"/><category scheme="http://www.blogger.com/atom/ns#" term="hbm2net"/><category scheme="http://www.blogger.com/atom/ns#" term="POCO"/><category scheme="http://www.blogger.com/atom/ns#" term="T4"/><category scheme="http://www.blogger.com/atom/ns#" term="Velocity"/><title type='text'>hbm2net - c# instead of T4</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
I&#39;m still mapping my entities to NHibernate by using hbm files. I still do this for several reasons, but i won&#39;t detail them now.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
Since I&#39;m using hbm files, I want&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp;to exploit one of their huge advantage - auto generating lot&#39;s of code that can be derived from the hbm files by using the hbm2net tool.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;for example:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;- Auto generate my POCO entities.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
- Auto generate my DTO entities.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
- Auto generate my server side validations and their equivalent client side validations&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
- Implementing cross cutting behaviors like overriding GetHashCode(), Equals(), or invoking &amp;nbsp; &amp;nbsp; &amp;nbsp;NotifyPropertyChanged etc.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
In it&#39;s earliest versions, hbm2net was expecting a Velocity script to auto generate code. Recent versions can also work with T4 scripts.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
hbm2net is&amp;nbsp;great and it&#39;s hard to imagine how to work with out it.&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; font-size: 15px;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Unfortunately&lt;/span&gt;,&lt;/span&gt;&amp;nbsp;&lt;/span&gt;Velocity is not that user-friendly and&amp;nbsp;neither T4.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
My&amp;nbsp;preferred&amp;nbsp;way is to implement my own generator written in c#, which can be plugged into hbm2net instead of working with T4 or Velocity.&lt;br /&gt;
&lt;br /&gt;
And why would i prefer c#...? Well, i guess that&#39;s obvious...&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
So, lets get to work.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
First of all, download the latest version of hbm2net from&amp;nbsp;&lt;a href=&quot;http://sourceforge.net/projects/nhcontrib/files/NHibernate.Hbm2Net/hbm2net-3.0.0.0-beta.zip/download&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&amp;nbsp;and extract it to wherever you like.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
Next, create a Class Library project in Visual Studio and call it MyHbm2NetGenerator.&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
Add a reference to NHibernate.Tool.hbm2net.dll (should be located where you&#39;ve extracted the zip file).&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
Add a class to this project and call it POCOGenerator. This class should be derived from&amp;nbsp;NHibernate.Tool.hbm2net.AbstractRenderer and implement&amp;nbsp;NHibernate.Tool.hbm2net.ICanProvideStream:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjA70bxZwBbYgA_Qlf1OKj52bW87msxFBOzWpdMNp_t4JM3IlW238S-ZhjArUiaVaxX4x_QZQF5rHAXQw_gfCZOL0ebTrqTnnxKAAlf-9yTljV9c7iIsaib8tG247XPKCHoqFkBPAnbAp/s1600/hbm2net1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjA70bxZwBbYgA_Qlf1OKj52bW87msxFBOzWpdMNp_t4JM3IlW238S-ZhjArUiaVaxX4x_QZQF5rHAXQw_gfCZOL0ebTrqTnnxKAAlf-9yTljV9c7iIsaib8tG247XPKCHoqFkBPAnbAp/s1600/hbm2net1.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
the hbm2net will create a single instance of this class and will use it to generate the derived code for all hbm files.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
Next, implement &amp;nbsp;ICanProvideStream.CheckIfSourceIsNewer:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFsX9wz1KV5eho2vthhSsnnlFl9EwveBOcyTRAJrd6rgB69_tdyy13ic8ehe6cmCFHZyvISx7wDQw8TFwbdb9PIkRSigMgGMYvAqR6r8-SfweU42k-FkSJo2Am0jhw4HMpF52wSzEveBw6/s1600/hbm2net2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFsX9wz1KV5eho2vthhSsnnlFl9EwveBOcyTRAJrd6rgB69_tdyy13ic8ehe6cmCFHZyvISx7wDQw8TFwbdb9PIkRSigMgGMYvAqR6r8-SfweU42k-FkSJo2Am0jhw4HMpF52wSzEveBw6/s1600/hbm2net2.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
The hbm2net will invoke CheckIfSourceIsNewer for each hbm file. The &lt;i&gt;source &lt;/i&gt;parameter will be the LastWriteTimeUtc of the current hbm file. The&amp;nbsp;&lt;i&gt;directory &lt;/i&gt;parameter&amp;nbsp;will be the path for the output directory in which the generated files will be stored. This method should return &lt;i&gt;true &lt;/i&gt;if &lt;i&gt;source &lt;/i&gt;is greater than the&amp;nbsp;LastWriteTimeUtc&amp;nbsp;of the generated file, meaning - if there were changes in the hbm file since the last generation of the POCO file.&lt;br /&gt;
&lt;br /&gt;
The method GetFileName is receiving the&amp;nbsp;parameter&amp;nbsp;&lt;i&gt;clazz &lt;/i&gt;which&amp;nbsp;is holding&lt;i&gt;&amp;nbsp;&lt;/i&gt;almost all the details about the POCO entity that is going to be generated. I&#39;ll give more details about this class soon, but for now, all we need in this method is the POCO entity name which can be found at &lt;i&gt;clazz.GeneratedName.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;
Next, implement &amp;nbsp;ICanProvideStream.GetStream:
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggcqY3qMJC1C2XatkUKeF4k_AC9Goi49d9EhMnI-NgLsOkmDNG79wFXP2qDBQs8VHG8T3c4YUSAUv08aK_3ySJCpw64L9__wzsSK2DM8BT1Jv97vUDPTd9pQuEqyNEF13JT34SK6IAhotU/s1600/hbm2net3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggcqY3qMJC1C2XatkUKeF4k_AC9Goi49d9EhMnI-NgLsOkmDNG79wFXP2qDBQs8VHG8T3c4YUSAUv08aK_3ySJCpw64L9__wzsSK2DM8BT1Jv97vUDPTd9pQuEqyNEF13JT34SK6IAhotU/s1600/hbm2net3.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
The hbm2net will invoke this method to get a stream to flush the content of the current generated POCO entity.&lt;br /&gt;
&lt;br /&gt;
Next, you need to override the method Render. This is actually the main method where you generate the content of the POCO entity and flush it (save it).&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf05ThJnnoMF91FxvFME47A04EcPQUBgHLMx0H7vGj4Yx8lS2nC3irtReJFKsvvl_mjInOeNM6GdM1BPLfpZh_PV9a1ZNx8i-OyEcRW2bwLkae9q_QA3IwebjCAGQYGZ9Svsz97EOLoA2t/s1600/hbm2net4.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf05ThJnnoMF91FxvFME47A04EcPQUBgHLMx0H7vGj4Yx8lS2nC3irtReJFKsvvl_mjInOeNM6GdM1BPLfpZh_PV9a1ZNx8i-OyEcRW2bwLkae9q_QA3IwebjCAGQYGZ9Svsz97EOLoA2t/s1600/hbm2net4.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now, implement a method that will generate the POCO&#39;s content (&lt;i&gt;GeneratePOCO &lt;/i&gt;is the name i gave it).&lt;br /&gt;
Of course you should be using&amp;nbsp;&amp;nbsp;the&amp;nbsp;&lt;i&gt;ClassMapping&amp;nbsp;&lt;/i&gt;object to get all the POCO&#39;s details e.g. class name, class modifiers, base class, properties, fields etc.&lt;br /&gt;
In the next post i will show you in more details what can be done with ClassMapping in order to generate the desired POCO content.&lt;br /&gt;
&lt;br /&gt;
OK, we&#39;re getting there: compile your&amp;nbsp;MyHbm2NetGenerator project and then copy&amp;nbsp;MyHbm2NetGenerator.dll to the directory where you&#39;ve extracted hbm2net.&lt;br /&gt;
&lt;br /&gt;
Next, create an xml file, call it config.xml (or whatever...) and put it wherever you like. config.xml should look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixVuUQUNi-hW84R2JVm9Jse2KuQ9WC1fNsvnuQfcx2Q-IdsRLwotQ4bG-RD9hT0uWEh6za-vLXzObvsVRXJcfQMVUhUx-vBdUQLCeLsyi6gWKK_lbh_oG_n3NL28mZfYFD7wJce7q8Je96/s1600/hbm2net5.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixVuUQUNi-hW84R2JVm9Jse2KuQ9WC1fNsvnuQfcx2Q-IdsRLwotQ4bG-RD9hT0uWEh6za-vLXzObvsVRXJcfQMVUhUx-vBdUQLCeLsyi6gWKK_lbh_oG_n3NL28mZfYFD7wJce7q8Je96/s1600/hbm2net5.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;i&gt;renderer &lt;/i&gt;is the FullyQualifiedName of your POCOGenerator class. &lt;i&gt;package &lt;/i&gt;is the namespace for your POCO entities - you will receive it in the&amp;nbsp;POCOGenerator.Render as the &lt;i&gt;savedToPackage &lt;/i&gt;parameter.&lt;br /&gt;
&lt;br /&gt;
Now, execute the following command in the command shell:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;lt;hbm2net dir&amp;gt;\hbm2net.exe --config=&amp;lt;config dir&amp;gt;\config.xml --output=&amp;lt;output dir&amp;gt; &amp;lt;hbm files dir&amp;gt;\*.hbm.xml&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;And that&#39;s it! Go to&amp;nbsp;&amp;lt;output dir&amp;gt; to see your generated files.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
To make hbm2net auto generate your code on every build of your domain/DTO/validations project, you can make a pre/post build event in your project settings with the command line I just showed you.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://i.minus.com/1339152137/7LwxnJgPT5iv2W1CJk9Lvw/dbd3donv2CYPB1/MyHbm2NetGenerator.rar&quot; target=&quot;_blank&quot;&gt;download code example&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/3815014914965930227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2012/01/hbm2net-c-instead-of-t4.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3815014914965930227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3815014914965930227'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2012/01/hbm2net-c-instead-of-t4.html' title='hbm2net - c# instead of T4'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjA70bxZwBbYgA_Qlf1OKj52bW87msxFBOzWpdMNp_t4JM3IlW238S-ZhjArUiaVaxX4x_QZQF5rHAXQw_gfCZOL0ebTrqTnnxKAAlf-9yTljV9c7iIsaib8tG247XPKCHoqFkBPAnbAp/s72-c/hbm2net1.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-3199629832980957949</id><published>2011-11-30T05:49:00.001-08:00</published><updated>2011-12-06T06:14:11.408-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Binding"/><category scheme="http://www.blogger.com/atom/ns#" term="Dependency"/><category scheme="http://www.blogger.com/atom/ns#" term="NotifyProperyChanged"/><category scheme="http://www.blogger.com/atom/ns#" term="Object Graph"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>P2PMapper</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
If you&#39;re working with MVVM, you&#39;re probably familiar with the case in which one property depends on another property.&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
For instance, consider the following &#39;User Registration&#39; form.&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHmmxWTv5bzYQO7RqmVURirL2sLFtNQepvUnnexcRVKhBwU9A_S7qQlNA8OFVNLHzqkUeLxOudFv4WP7zkBZPVitv9gIlUiVdqCZBgF8gjsVpSldpUjENaW4-winJr212QuGnBTsVyRbuN/s1600/user_details.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;340&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHmmxWTv5bzYQO7RqmVURirL2sLFtNQepvUnnexcRVKhBwU9A_S7qQlNA8OFVNLHzqkUeLxOudFv4WP7zkBZPVitv9gIlUiVdqCZBgF8gjsVpSldpUjENaW4-winJr212QuGnBTsVyRbuN/s400/user_details.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
In this registration form, the &#39;SMS&#39; checkbox is enabled only if the user entered a phone number and checked the &#39;Receive Messages&#39; checkbox. The same goes for the &#39;Mail&#39; checkbox - it is enabled only if the user entered an email address and checked the &#39;Receive Messages&#39; checkbox.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
To implement the above behavior you&#39;ll probably create the following properties in the ViewModel and bind them to the &#39;IsEnabled&#39; of the &#39;SMS&#39; and &#39;Mail&#39; checkboxes:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; EnableSMS
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; ReceiveMessages &amp;amp;&amp;amp; !&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrEmpty(Phone);
            }
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; EnableMail
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; ReceiveMessages &amp;amp;&amp;amp; !&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrEmpty(Mail);
            }
        }
&lt;/pre&gt;
&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
But now, &#39;EnableSMS&#39; depends on 2 other properties - &#39;ReceiveMessage&#39; and &#39;Phone&#39;. Whenever these 2 properties are changing - the UI needs to be notified that the &#39;EnableSMS&#39; has changed too. The same goes for &#39;EnableMail&#39;.&lt;br /&gt;
So, to support that, you probably have the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Phone
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; _phone;
            }

            set
            {
                _phone = &lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt;;
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;Phone&quot;&lt;/span&gt;);
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableSMS&quot;&lt;/span&gt;);
            }
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Mail
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; _mail;
            }

            set
            {
                _mail = &lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt;;
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;Mail&quot;&lt;/span&gt;);
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableMail&quot;&lt;/span&gt;);
            }
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; ReceiveMessages
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; _receiveMessages;
            }

            set
            {
                _receiveMessages = &lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt;;
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;ReceiveMessages&quot;&lt;/span&gt;);
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableSMS&quot;&lt;/span&gt;);
                NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableMail&quot;&lt;/span&gt;);
            }
        }
&lt;/pre&gt;
&lt;br /&gt;
I guess you will agree with me that the code is starting to get messy...&lt;br /&gt;
&lt;br /&gt;
Now, there are several tools that can handle this situation, like U&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: blue;&quot;&gt;&lt;a href=&quot;http://updatecontrols.codeplex.com/&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: blue;&quot;&gt;pdate Control&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;http://code.google.com/p/notifypropertyweaver/&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: blue;&quot;&gt;NotifyPropertyWeaver&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/span&gt;or&amp;nbsp;&lt;a href=&quot;http://www.codewrecks.com/blog/index.php/2010/12/03/wpf-mvvm-and-calculated-properties/&quot; style=&quot;color: blue;&quot; target=&quot;_blank&quot;&gt;this one&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: blue;&quot;&gt;&amp;nbsp;&lt;/span&gt;and some of them are doing it quite well.&lt;br /&gt;
&lt;br /&gt;
But as far as i know, none of the above tools supports the case in which one property depends on a&amp;nbsp;graph of&amp;nbsp;objects.&lt;br /&gt;
For example: the company&#39;s total salaries would be the sum of all Company.Employees.Salary.Amount.&lt;br /&gt;
For instance, consider the following &#39;Edit Salaries&#39; screen:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2w6zgPr-EfArbMHheyKgf_9PZtj5n60sgV0GHr0BK2ymN7_khKlWSzCxJQR-_xZQpq4BGSlqjnaqOnioLrzq8x3KkX4ppT4nuQ53XK0e2S46Dsp324bqzwrAk53gyQeka_W1U8p60AH1y/s1600/salaries.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;246&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2w6zgPr-EfArbMHheyKgf_9PZtj5n60sgV0GHr0BK2ymN7_khKlWSzCxJQR-_xZQpq4BGSlqjnaqOnioLrzq8x3KkX4ppT4nuQ53XK0e2S46Dsp324bqzwrAk53gyQeka_W1U8p60AH1y/s400/salaries.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The ViewModel of this screen has a &#39;Company&#39; property. The grid is bound to Company.Employees and the Salary column is bound to &#39;Employee.Salary.Amount&#39;.&lt;br /&gt;
The &lt;i&gt;Total Salaries&lt;/i&gt; field in the bottom of the screen would be bound to a property called &#39;TotalSalaries&#39; on the ViewModel and it will look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; TotalSalaires 
        {
            get
            {
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Company.Employees.Sum(x =&amp;gt; x.Salary.Amount);
            }
        }
&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;
&lt;br /&gt;
Now, if&amp;nbsp;for some reason&amp;nbsp;the &#39;Company&#39; property would change&amp;nbsp;-&amp;nbsp;&#39;TotalSalaries&#39; would change as well. But the UI wouldn&#39;t know about it because it has no way to know that &#39;TotalSalaries&#39;&amp;nbsp;depends on&amp;nbsp;&#39;Company&#39;.&lt;br /&gt;
And what if &#39;Company.Employess&#39; would change? What if the &#39;Salary&#39; of an employee would change, or the &#39;Amount&#39; of a salary would change? The UI wouldn&#39;t know that&amp;nbsp;&#39;TotalSalaries&#39; needs to be re-invoked.&lt;br /&gt;
&lt;br /&gt;
For this&amp;nbsp;I&#39;ve came with a solution called: &lt;i style=&quot;font-weight: bold;&quot;&gt;P2PMapper&amp;nbsp;&lt;/i&gt;which stands for: &lt;i style=&quot;font-weight: bold;&quot;&gt;Property to Property Mapper&lt;/i&gt;.&lt;br /&gt;
Let&#39;s see how it works.&lt;br /&gt;
In the first example above i would use it like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;            P2PMapper&amp;lt;UserRegViewModel&amp;gt;.Init(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;)
                .Couple(x =&amp;gt; x.EnableSMS)
                .With(x =&amp;gt; x.ReceiveMessages)
                .With(x =&amp;gt; x.Phone)
                .Couple(x =&amp;gt; x.EnableMail)
                .With(x =&amp;gt; x.ReceiveMessages)
                .With(x =&amp;gt; x.Mail);
&lt;/pre&gt;
&lt;br /&gt;
This code can be set in the ViewModel&#39;s&amp;nbsp;constructor.&lt;br /&gt;
I pass the&amp;nbsp;class of the&amp;nbsp;ViewModel as a generics parameter.&lt;br /&gt;
Then i pass the instance of the ViewModel to the &lt;i style=&quot;font-weight: bold;&quot;&gt;Init&lt;/i&gt;&amp;nbsp;method.&lt;br /&gt;
Then i &lt;i style=&quot;font-weight: bold;&quot;&gt;Couple &lt;/i&gt;the &#39;EnablePhone&#39; property (of the ViewModel) &lt;i style=&quot;font-weight: bold;&quot;&gt;With &lt;/i&gt;the &#39;ReceiveMessage&#39; and &#39;Phone&#39; properties and so forth.&lt;br /&gt;
&lt;br /&gt;
Of course that, &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableSMS&quot;&lt;/span&gt;);&lt;/pre&gt;
and &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;NotifyPropertyChanged(&lt;span class=&quot;str&quot;&gt;&quot;EnableMail&quot;&lt;/span&gt;);&lt;/pre&gt;
can now be removed from anywhere in the code.
&lt;br /&gt;
&lt;br /&gt;
In the second example above i would use it like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;            P2PMapper&amp;lt;CompanyDetailsViewModel&amp;gt;.Init(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;)
                .Couple(x =&amp;gt; x.TotalSalaires)
                .With(x =&amp;gt; x.Company.Employees[0].Salary.Amount);
&lt;/pre&gt;
Now, whenever there is a change down the path of Company.Employees.Salary.Amount - the P2PMapper will track it down and notify the UI about it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NOTE: x.Company.Employees[0] &lt;/b&gt;is only a&amp;nbsp;syntactic way to get down the path, it doesn&#39;t really mean &#39;&lt;i&gt;the first employee&#39;.&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NOTE:&amp;nbsp;&lt;/b&gt;each object down the path, including the ViewModel itself, needs to implement the interface&amp;nbsp;&lt;i&gt;P2PMapper.INotifier.&amp;nbsp;&lt;/i&gt;Also, each property down the path must call&amp;nbsp;&lt;i&gt;NotifiyPropertyChanged&amp;nbsp;&lt;/i&gt;when ever it is changing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The sample code, including the P2PMapper.dll can be found&amp;nbsp;&lt;a href=&quot;https://sourceforge.net/projects/p2pmapper/&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: blue;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/3199629832980957949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2011/11/p2pmapper.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3199629832980957949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/3199629832980957949'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2011/11/p2pmapper.html' title='P2PMapper'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHmmxWTv5bzYQO7RqmVURirL2sLFtNQepvUnnexcRVKhBwU9A_S7qQlNA8OFVNLHzqkUeLxOudFv4WP7zkBZPVitv9gIlUiVdqCZBgF8gjsVpSldpUjENaW4-winJr212QuGnBTsVyRbuN/s72-c/user_details.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-2444699324885497303</id><published>2011-11-13T08:09:00.001-08:00</published><updated>2011-11-15T08:24:14.444-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bi-directional"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>NHibernate bi-directional - use it carefully (Part II)</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
In the &lt;a href=&quot;http://itziksaban.blogspot.com/2011/11/nhibernate-cascade-use-it-carefully.html&quot;&gt;previous&lt;/a&gt;&amp;nbsp;post I&#39;ve showed you one reason to be very careful when using bi-directional
        associations in NHibernate.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
In this post I&#39;ll show you another reason. Again, for the example, I will use Customer
        with many Orders.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
We will create a one-to-many association from Customer to Orders:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Orders&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;all-delete-orphan&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;CUSTOMER_ID&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;one-to-many&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Order&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;not-found&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ignore&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
and we will create a many-to-one from Order to Customer:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;many-to-one&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;CUSTOMER_ID&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
Now consider&amp;nbsp;the following scenario:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;someCustomer.Orders.Add(someNewOrder);

...query the db &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; HQL

...

someNewOrder.OrderDate = DateTime.Now;

....

CustomerRepository.SaveOrUpdate(someCustomer);
transaction.Commit();&lt;/pre&gt;
&lt;br /&gt;
If you&#39;ll take a look at table &#39;ORDERS&#39; right after the commit, you&#39;ll
        find out that the CUSTOMER_ID field in the new record created for &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder&lt;/span&gt; is... NULL.&lt;br /&gt;
&lt;br /&gt;
And why is that?
        &lt;br /&gt;
let&#39;s see what NHibernate is doing a step by step:&lt;br /&gt;
1 - Right before querying the DB by using HQL, NHibernate is flushing all the changes
        to the DB, and that includes creating a new record for&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder&lt;/span&gt; At this
        stage the record in the DB is perfectly well.&lt;br /&gt;
&lt;br /&gt;
2 - By changing &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder.OrderDate&lt;/span&gt; NHIbernate considers &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder&lt;/span&gt; as &#39;dirty&#39; and it will
        flushed it to the DB later on when the transaction will be commited.&lt;br /&gt;
&lt;br /&gt;
3 - Finally, when the transaction is commited, again NHibernate is flushing all the
        changes but this time it&#39;s generating an &#39;UPDATE&#39; statement for &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder &lt;/span&gt;since
        it&#39;s no longer a new object - it has a record in the DB.&lt;br /&gt;
&lt;br /&gt;
And here is the problem - as we saw in the last step, an &#39;UPDATE&#39; statement for
        &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder&lt;/span&gt;&lt;br /&gt;
is executed. But since &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder.Customer&lt;/span&gt; is null (nowhere in the code
        we&#39;ve ever changed it) - the &#39;UPDATE&#39; statement looks something like this:&lt;br /&gt;
&quot;UPDATE ORDERS SET ...CUSTOMER_ID=NULL... WHERE...&quot;.
        &lt;br /&gt;
&lt;br /&gt;
OK, now you have a few options to solve it:&lt;br /&gt;
1 - do not use HQL - use session.Get() instead (only if you can...). This doesn&#39;t
        enforce NHibernate to flush like HQL does.
        &lt;br /&gt;
&lt;br /&gt;
2 - You can make sure that &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;someNewOrder.Customer&lt;/span&gt; actually does hold the Customer before&amp;nbsp;committing.&lt;br /&gt;
&lt;br /&gt;
3 - You can go to Order.hbm.xml and add update=&quot;false&quot;
            to the many-to-one association. like this:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;many-to-one&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;CUSTOMER_ID&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;attr&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
this tells NHibernate not to include the Customer when generating an &#39;UPDATE&#39; statement for an Order.&lt;br /&gt;
But this also means that you can not update the Order&#39;s Customer like this:
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;someOrder.Customer = someCustomer;
OrderRepository.SaveOrUpdate(someOrder);&lt;/pre&gt;
it won&#39;t work if you chose option No. 3...
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/2444699324885497303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2011/11/nhibernate-bi-directional-use-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2444699324885497303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2444699324885497303'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2011/11/nhibernate-bi-directional-use-it.html' title='NHibernate bi-directional - use it carefully (Part II)'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-2525302457566405364</id><published>2011-11-10T03:14:00.000-08:00</published><updated>2011-11-15T08:19:59.227-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bi-directional"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>NHibernate bi-directional - use it carefully (Part I)</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
A few days ago we&#39;ve&amp;nbsp;experienced&amp;nbsp;a very strange behavior with NHibernate. Or so we thought...&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
For the demonstration i will use a Customer that has many Orders.&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
And so we did that:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;customer.Orders.Remove(order);
CustomerRepository.SaveOrUpdate(customer);&lt;/pre&gt;
&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
The &quot;strange&quot;&amp;nbsp;behavior&amp;nbsp;was that the Customer itself has been deleted from the DB along with &lt;b&gt;all &lt;/b&gt;of&lt;b&gt;&amp;nbsp;&lt;/b&gt;its other Orders.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
the mappings were like this:&lt;br /&gt;
&lt;br /&gt;
Customer.hbm.xml:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Orders&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;lazy&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;all-delete-orphan&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;CUSTOMER_ID&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;one-to-many&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Order&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;not-found&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ignore&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;
Order.hbm.xml:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;many-to-one&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Customer&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;CUSTOMER_ID&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;all-delete-orphan&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;
&lt;br /&gt;
So, what went wrong? Why did NHibernate delete the customer when all we did was removing one order? the reason was:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Times New Roman&#39;;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
When we removed one Order from the Customer.Orders list, NHibernate deleted this Order from the DB since we have&amp;nbsp;&lt;span class=&quot;attr&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;kwrd&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;=&quot;all-delete-orphan&quot; &lt;/span&gt;&lt;span class=&quot;kwrd&quot; style=&quot;font-family: inherit; white-space: pre;&quot;&gt;on Customer.Orders.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kwrd&quot; style=&quot;font-family: inherit; white-space: pre;&quot;&gt;But while deleting an Order, NHibernate also is deleting its Customer. Why? Because we have&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;attr&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;kwrd&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;=&quot;all-delete-orphan&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot; style=&quot;font-family: inherit; white-space: pre;&quot;&gt; on Order.Customer, meaning - we actually tell NHibernate to delete a Customer whenever one of its Orders is being deleted. And that&#39;s usually a stupid thing to do.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kwrd&quot; style=&quot;font-family: inherit; white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;kwrd&quot; style=&quot;font-family: inherit; white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/2525302457566405364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2011/11/nhibernate-cascade-use-it-carefully.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2525302457566405364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2525302457566405364'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2011/11/nhibernate-cascade-use-it-carefully.html' title='NHibernate bi-directional - use it carefully (Part I)'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-181958640060148562</id><published>2011-11-01T13:52:00.000-07:00</published><updated>2012-06-06T22:39:23.077-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LINQ"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>Strongly Typed HQL</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot;&gt;
If you&#39;re using NHibernate, you have 3 main options to execute a query against the DB:&amp;nbsp;Criteria API, HQL and SQL. The last one won&#39;t be relevant to our discussion.&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
For a long time, the names of the properties were a weakness point since they were represented by strings. For example:&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var crit = Session.CreateCriteria(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Person));
crit.Add(NHibernate.Criterion.Expression.Eq(&lt;span class=&quot;str&quot;&gt;&quot;ID&quot;&lt;/span&gt;, someVal));
&lt;/pre&gt;
&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot;&gt;
Lately, Criteria API has an extension to support Lambda expressions and therefore can be strongly typed:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;var crit = Session.CreateCriteria(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(Person));
crit.Add&amp;lt;Person&amp;gt;(p =&amp;gt; p.ID ==&amp;nbsp;someVal)&lt;/pre&gt;
&lt;br /&gt;
But in some complicated cases - HQL is inevitable, and since HQL is represented by string - refactoring can be very&amp;nbsp;painful. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; hql = &lt;span class=&quot;str&quot;&gt;&quot;select p from Person p where p.ID=:someVal&quot;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
To avoid this problem, I&#39;ve created 2 methods. To use these methods, simply locate them in the base class of all the classes that build HQL quries. In our case it was BaseRepository which is the base class for all the Repositories (if you&#39;re following DDD). These 2 methods are:&lt;br /&gt;
&lt;br /&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;Class&amp;lt;T&amp;gt;();
Prop&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;&amp;gt;&amp;gt; property);&lt;/pre&gt;
&lt;div&gt;
&lt;span class=&quot;str&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
I will show the implementation soon, but first an example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; hql = &lt;span class=&quot;str&quot;&gt;&quot;select p from &quot;&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;+ Class&amp;lt;Person&amp;gt;() + &lt;span class=&quot;str&quot;&gt;&quot; p where p.&quot;&lt;/span&gt; + Prop&amp;lt;Person&amp;gt;(x =&amp;gt; x.ID) + &lt;span class=&quot;str&quot;&gt;&quot;=:someVal&quot;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
And the implementation:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Class&amp;lt;T&amp;gt;()
{
&lt;span class=&quot;kwrd&quot;&gt;    return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(T).ToString();
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Prop&amp;lt;T&amp;gt;(Expression&amp;lt;Func&amp;lt;T, &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;&amp;gt;&amp;gt; property)
{
&lt;span class=&quot;kwrd&quot;&gt;    if&lt;/span&gt; (property.Body.NodeType == ExpressionType.MemberAccess)
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (property.Body &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; MemberExpression).Member.Name;
    }
    &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (property.Body.NodeType == ExpressionType.Convert
        &amp;amp;&amp;amp; (property.Body &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; UnaryExpression).Operand.NodeType&amp;nbsp;== ExpressionType.MemberAccess)&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;{
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; ((property.Body &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; UnaryExpression).Operand&amp;nbsp;&lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; MemberExpression).Member.Name;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;}

    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;&quot;&lt;/span&gt;;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/181958640060148562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2011/11/strongly-typed-hql.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/181958640060148562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/181958640060148562'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2011/11/strongly-typed-hql.html' title='Strongly Typed HQL'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8714281344164032543.post-2623383157939999115</id><published>2011-11-01T07:15:00.000-07:00</published><updated>2011-11-01T07:25:02.652-07:00</updated><title type='text'>WCF - a performance issue</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;A few weeks ago I&#39;ve encountered an&amp;nbsp;annoying performance problem with WCF.&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;We were working on some Client/Server application, which should work only inside a local network, meaning - all the clients will&amp;nbsp;be connected to&amp;nbsp;the server via the &lt;b&gt;Intranet&lt;/b&gt;. We were using WCF of&amp;nbsp;curse.&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;While doing QA we&#39;ve faced a problem - one client worked really fast and the other was a bit slow. They both had the same server and they both had the same hardware, OS, installations etc.&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;After smashing my head against the wall a few times I&#39;ve found the problem: the slower one wasn&#39;t configure to bypass proxy for local addresses and that caused an overhead.&lt;br /&gt;
&lt;br /&gt;
To find out your configuration - open Internet Explorer-&amp;gt;Tools-&amp;gt;Internet Options-&amp;gt;Connections-&amp;gt;LAN Settings&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUqNmbwr-B575bwve7vRr8e5uSlb4mmoQ9PgGmRhOUA82hV9tN9pLHC1EpZBn7MYPlgmRF_Ru8U48SSBjhTkdGKqcE3nlx6iF5MCjwqbO-33kzyy5jNIV-LEAXivP1LUMicNhUha0S6U3n/s1600/IEOpt.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUqNmbwr-B575bwve7vRr8e5uSlb4mmoQ9PgGmRhOUA82hV9tN9pLHC1EpZBn7MYPlgmRF_Ru8U48SSBjhTkdGKqcE3nlx6iF5MCjwqbO-33kzyy5jNIV-LEAXivP1LUMicNhUha0S6U3n/s1600/IEOpt.JPG&quot; /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;So, instinctively, the first solution that came to my mind was to re-configure the machine to bypass proxy. But then i thought - it doesn&#39;t make any&amp;nbsp;sense&amp;nbsp;- i cannot enforce the users on the field to change their configuration. And so I&#39;ve found a better solution - on the client side configure the binding as follow:&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;csharpcode&quot;&gt;binding.UseDefaultWebProxy = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
    &lt;/pre&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;or on the App.config file:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;binding&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;httpBind&quot;&lt;/span&gt; .... &lt;span class=&quot;attr&quot;&gt;bypassProxyOnLocal&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;Since the system was planed to work inside the Intranet - we don&#39;t need to use proxy anyway.&lt;br /&gt;
&lt;br /&gt;
Bye.&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://itziksaban.blogspot.com/feeds/2623383157939999115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://itziksaban.blogspot.com/2011/11/wcf-performance-issue.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2623383157939999115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8714281344164032543/posts/default/2623383157939999115'/><link rel='alternate' type='text/html' href='http://itziksaban.blogspot.com/2011/11/wcf-performance-issue.html' title='WCF - a performance issue'/><author><name>Itzik Saban</name><uri>http://www.blogger.com/profile/10945558437728680457</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUqNmbwr-B575bwve7vRr8e5uSlb4mmoQ9PgGmRhOUA82hV9tN9pLHC1EpZBn7MYPlgmRF_Ru8U48SSBjhTkdGKqcE3nlx6iF5MCjwqbO-33kzyy5jNIV-LEAXivP1LUMicNhUha0S6U3n/s72-c/IEOpt.JPG" height="72" width="72"/><thr:total>0</thr:total></entry></feed>