<?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-8872538558551624494</id><updated>2024-09-22T01:12:05.308+02:00</updated><category term="NHibernate"/><category term="DDD"/><category term="ALT.NET"/><category term="Trac"/><category term="VisualSVN"/><category term="agile"/><category term="VAB"/><category term="blogging"/><category term="open source"/><category term="unit testing"/><title type='text'>Miroslav&#39;s Code Mind</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-4358532998585423527</id><published>2012-06-12T16:25:00.000+02:00</published><updated>2012-06-12T16:26:15.238+02:00</updated><title type='text'>Moving on...</title><content type='html'>To anyone interested, I have decided to move my blog to my own domain and change the blogging platform. My new blog is now based on &lt;a href=&quot;http://www.funnelweblog.com/&quot;&gt;FunnelWeb&lt;/a&gt; and the address is: &lt;a href=&quot;http://blog.miroslavpopovic.com/&quot;&gt;http://blog.miroslavpopovic.com&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Also, there is a new feed for it, so please redirect your feed readers to it: &lt;a href=&quot;http://feeds.feedburner.com/miroslavpopovic/blog&quot;&gt;http://feeds.feedburner.com/miroslavpopovic/blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks!</content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/4358532998585423527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/4358532998585423527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/4358532998585423527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/4358532998585423527'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2012/06/to-anyone-interested-i-have-decided-to.html' title='Moving on...'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-2138583855093454956</id><published>2011-02-18T00:00:00.001+01:00</published><updated>2011-02-18T00:00:59.992+01:00</updated><title type='text'>Materials and links from my INETA talk on Thursday</title><content type='html'>&lt;p&gt;Below are the links for downloading PowerPoint presentation and samples from my talk titled: &lt;strong&gt;&lt;em&gt;Design Patterns for developing WPF, Silverlight and Windows Phone 7 applications; MVVM and Caliburn.Micro&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href=&quot;http://codemind.info/presentations/caliburn/MvvmAndCaliburn.Micro.ppt&quot;&gt;MVVM and Caliburn.Micro presentation&lt;/a&gt; (The slides are on my native language)&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://codemind.info/presentations/caliburn/Examples.zip&quot;&gt;MVVM and Caliburn.Micro examples&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Other links from the presentation:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href=&quot;http://caliburnmicro.codeplex.com&quot;&gt;http://caliburnmicro.codeplex.com&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.caliburnproject.org&quot;&gt;http://www.caliburnproject.org&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://devlicio.us/blogs/rob_eisenberg&quot;&gt;http://devlicio.us/blogs/rob_eisenberg&lt;/a&gt; - Rob Eisenberg’s blog&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://live.visitmix.com/Archive&quot;&gt;http://live.visitmix.com/Archive&lt;/a&gt; – Archive of all video materials from MIX conference. Look for “Build your own MVVM Framework” from MIX 2010&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx&quot;&gt;http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx&lt;/a&gt; – First publishing of MVVM &lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://martinfowler.com&quot;&gt;http://martinfowler.com&lt;/a&gt; - Martin Fowler&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://codebetter.com/jeremymiller&quot;&gt;http://codebetter.com/jeremymiller&lt;/a&gt; - Jeremy Miller’s blog&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/MVVM&quot;&gt;http://en.wikipedia.org/wiki/MVVM&lt;/a&gt; – contains links to all MVVM frameworks currently available&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://delicious.com/miroslav.popovic/mvvm&quot;&gt;http://delicious.com/miroslav.popovic/mvvm&lt;/a&gt; – My MVVM bookmarks tag&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hope I wasn’t too boring&amp;#160; &lt;img style=&quot;border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; alt=&quot;Smile&quot; src=&quot;http://lh5.ggpht.com/_gWtXEJM_JDY/TV2oqhph8UI/AAAAAAAAAGI/ufcbrCO9J0U/wlEmoticon-smile%5B2%5D.png?imgmax=800&quot; /&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/2138583855093454956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/2138583855093454956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/2138583855093454956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/2138583855093454956'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2011/02/materials-and-links-from-my-ineta-talk.html' title='Materials and links from my INETA talk on Thursday'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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="http://lh5.ggpht.com/_gWtXEJM_JDY/TV2oqhph8UI/AAAAAAAAAGI/ufcbrCO9J0U/s72-c/wlEmoticon-smile%5B2%5D.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-460822121782581970</id><published>2009-02-09T20:32:00.001+01:00</published><updated>2009-02-09T20:32:23.344+01:00</updated><title type='text'>New Silverlight blog</title><content type='html'>&lt;p&gt;My good friend &lt;a href=&quot;http://www.linkedin.com/in/radenkozec&quot; target=&quot;_blank&quot;&gt;Radenko Zec&lt;/a&gt; started &lt;a href=&quot;http://blog.developers.ba/&quot; target=&quot;_blank&quot;&gt;blogging&lt;/a&gt; about Silverlight. Considering he has won 3rd place on &lt;a href=&quot;http://www.silverlightchallenge.eu/&quot; target=&quot;_blank&quot;&gt;European Silverlight Challenge&lt;/a&gt;, he’ll surely have something to say about it.&lt;/p&gt;  &lt;p&gt;Visit him at: &lt;a title=&quot;http://blog.developers.ba/&quot; href=&quot;http://blog.developers.ba/&quot;&gt;http://blog.developers.ba/&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/460822121782581970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/460822121782581970' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/460822121782581970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/460822121782581970'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2009/02/new-silverlight-blog.html' title='New Silverlight blog'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-7221454738263865946</id><published>2009-02-01T19:30:00.001+01:00</published><updated>2009-02-01T19:30:24.064+01:00</updated><title type='text'>Implement Firefox-like search in WPF application using M-V-VM</title><content type='html'>&lt;p&gt;I have just submitted my first &lt;a href=&quot;http://www.codeproject.com&quot; target=&quot;_blank&quot;&gt;CodeProject&lt;/a&gt; article. You can find it &lt;a href=&quot;http://www.codeproject.com/KB/WPF/FirefoxLikeSearchWithMVVM.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Although I had several article ideas over the years, my laziness prevent me from posting them :) &lt;/p&gt;  &lt;p&gt;Hopefully this one will come in handy for those learning and using M-V-VM.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/7221454738263865946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/7221454738263865946' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7221454738263865946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7221454738263865946'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2009/02/implement-firefox-like-search-in-wpf.html' title='Implement Firefox-like search in WPF application using M-V-VM'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-4642686508578599547</id><published>2008-10-20T02:58:00.001+02:00</published><updated>2008-10-20T02:58:19.831+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>A good deed</title><content type='html'>&lt;p&gt;Looks like I did a &lt;a href=&quot;http://unhandled-exceptions.com/blog/index.php/2008/10/19/a-user-contribution-saved-my-ugly-site/&quot; target=&quot;_blank&quot;&gt;good deed&lt;/a&gt; today :)&lt;/p&gt;  &lt;p&gt;And despite Stephen&#39;s words, I did it out of gratitude, not out of pity :)&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/4642686508578599547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/4642686508578599547' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/4642686508578599547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/4642686508578599547'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/10/good-deed.html' title='A good deed'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-3854956330692571789</id><published>2008-10-16T11:49:00.001+02:00</published><updated>2008-10-16T11:50:49.683+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>Repository implementation</title><content type='html'>&lt;p&gt;Along with &lt;a href=&quot;http://codemind.blogspot.com/2008/10/mapping-entities-with-nhibernate.html&quot; target=&quot;_blank&quot;&gt;NHibernate mappings&lt;/a&gt;, Peniko.DataLayer project contains &lt;a href=&quot;http://martinfowler.com/eaaCatalog/repository.html&quot; target=&quot;_blank&quot;&gt;Repository&lt;/a&gt; implementations. Repository interfaces are in Peniko.Domain project, as mentioned &lt;a href=&quot;http://codemind.blogspot.com/2008/08/core-of-all-applications.html&quot; target=&quot;_blank&quot;&gt;before&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;All communication with &lt;a href=&quot;http://www.nhforge.org&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt; is done through ISession instance. Session is basically a &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot; target=&quot;_blank&quot;&gt;Unit of Work&lt;/a&gt; for NHibernate. We have a standard NHibernateHelper static class for encapsulating ISessionFactory and for creating / opening the session:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;NHibernateHelper&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ISessionFactory&lt;/span&gt; _sessionFactory;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ISessionFactory&lt;/span&gt; SessionFactory&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (_sessionFactory == &lt;span style=&quot;color: blue&quot;&gt;null&lt;/span&gt;)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; configuration = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Configuration&lt;/span&gt;();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; configuration.Configure();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; configuration.AddAssembly(&lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt;(&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;).Assembly);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _sessionFactory = configuration.BuildSessionFactory();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; _sessionFactory;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ISession&lt;/span&gt; OpenSession()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; SessionFactory.OpenSession();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;SessionFactory is created from the NHibernate configuration the first time its accessed. Configuration comes from hibernate.cfg.xml file defined in UI and test projects:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;xml&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;encoding&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; ?&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;hibernate-configuration&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;xmlns&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;urn:nhibernate-configuration-2.2&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;session-factory&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;connection.provider&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;NHibernate.Connection.DriverConnectionProvider&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;dialect&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;NHibernate.Dialect.MsSql2005Dialect&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;connection.driver_class&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;NHibernate.Driver.SqlClientDriver&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;connection.connection_string&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;...&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;show_sql&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;true&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;mapping&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;assembly&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Peniko.DataLayer&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;session-factory&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;hibernate-configuration&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;In Peniko.DataLayer, every Repository method uses its own session, so we can&#39;t use NHibernate&#39;s lazy loading feature. Better option would be session-per-conversation pattern mentioned &lt;a href=&quot;http://ayende.com/Blog/archive/2007/02/03/iBatis-better-than-Hibernate-for-GUI-applications.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, but we&#39;ll leave it as is for now.&lt;/p&gt;  &lt;p&gt;The most important class in Repository implementation is Repository&amp;lt;T&amp;gt; implementing our IRepository&amp;lt;T&amp;gt; interface:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;IRepository&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style=&quot;color: blue&quot;&gt;where&lt;/span&gt; T : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Save(T entity);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Delete(T entity);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; T GetById(&lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt; id);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt; GetAll();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt; &lt;/div&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;abstract&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Repository&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;IRepository&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style=&quot;color: blue&quot;&gt;where&lt;/span&gt; T : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ILog&lt;/span&gt; _log = &lt;span style=&quot;color: #2b91af&quot;&gt;LogManager&lt;/span&gt;.GetLogger(&lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;Repository&lt;/span&gt;&amp;lt;T&amp;gt;));&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ILog&lt;/span&gt; Log { &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt; { &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; _log; } }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Save(T entity) { ... }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Delete(T entity) { ... }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; T GetById(&lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt; id) { ... }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt; GetAll() { ...&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;It&#39;s defined as abstract class and provides inherited classes with basic strongly typed methods for saving, deleting and retrieving all entities or a single entity by id and also an &lt;a href=&quot;http://logging.apache.org/log4net/index.html&quot; target=&quot;_blank&quot;&gt;log4net&lt;/a&gt;&#39;s ILog instance . Inherited class is defined like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ProductRepository&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Repository&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;&amp;gt;, &lt;span style=&quot;color: #2b91af&quot;&gt;IProductRepository &lt;/span&gt;{ ... }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is a Save method from Repository&amp;lt;T&amp;gt;:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Save(T entity)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (!entity.IsValid) &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ValidationException&lt;/span&gt;(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Entity is invalid&amp;quot;&lt;/span&gt;);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; session = &lt;span style=&quot;color: #2b91af&quot;&gt;NHibernateHelper&lt;/span&gt;.OpenSession())&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; transaction = session.BeginTransaction())&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Log.DebugFormat(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Saving entity Id: {0}&amp;quot;&lt;/span&gt;, entity.Id);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;try&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; session.SaveOrUpdate(entity); &lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AfterSaveEntity(session, entity); &lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; transaction.Commit();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;StaleObjectStateException&lt;/span&gt; ex)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; transaction.Rollback();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Log.Error(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Error saving entity&amp;quot;&lt;/span&gt;, ex);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ConcurrencyException&lt;/span&gt;(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;The data has been modified by another user&amp;quot;&lt;/span&gt;, ex);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;HibernateException&lt;/span&gt; ex)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; transaction.Rollback();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Log.Error(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Error saving entity&amp;quot;&lt;/span&gt;, ex);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt;;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;First thing it does is to check if entity &lt;a href=&quot;http://codemind.blogspot.com/2008/08/are-you-valid.html&quot; target=&quot;_blank&quot;&gt;is valid&lt;/a&gt;. Then it opens a session and begins a new transaction on it. As of NHibernate 2.0, all Saves, Updates and Deletes must be encapsulated in transaction. Save method calls session.SaveOrUpdate() which does both insert and update operations based on the value of entity.Id. In our case, if Id is Guid.Empty, it will do Insert, otherwise Update.&lt;/p&gt;  &lt;p&gt;AfterSaveEntity call allows inherited class to do some action after the entity is saved successfully. I.e. to save some other, unrelated entity.&lt;/p&gt;  &lt;p&gt;Note that we catch StaleObjectStateException. That exception is thrown when there is a concurrency problem. We encapsulate it in our ConcurrencyException and throw that instead. That way it&#39;s easy to catch it in UI code without dependency on NHibernate.&lt;/p&gt;  &lt;p&gt;Delete method is more or less the same. The only difference is that it calls session.Delete() instead of session.SaveOrUpdate().&lt;/p&gt;  &lt;p&gt;GetById looks like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; T GetById(&lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt; id)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; session = &lt;span style=&quot;color: #2b91af&quot;&gt;NHibernateHelper&lt;/span&gt;.OpenSession())&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Log.DebugFormat(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Getting entities with Id: {0}&amp;quot;&lt;/span&gt;, id);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;try&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; entity = session.Get&amp;lt;T&amp;gt;(id); &lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AfterGetEntity(session, entity); &lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; entity;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;HibernateException&lt;/span&gt; ex)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Log.Error(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Error getting entities by id&amp;quot;&lt;/span&gt;, ex);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt;;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This method is very simple. session.Get&amp;lt;T&amp;gt;(id) returns a single entity with the given id. GetAll method is similar, but it uses NHibernate Criteria API and returns session.CreateCriteria(typeof (T)).List&amp;lt;T&amp;gt;() as a result.&lt;/p&gt;  &lt;p&gt;In another project I&#39;m currently involved, Repository also has FindAll and FindOne methods that accept DetachedCriteria as a parameter. The idea came from &lt;a href=&quot;http://unhandled-exceptions.com/blog/index.php/2008/09/04/summer-of-nhibernate-session-12-detached-objects-detached-criteria-and-working-without-a-session-is-available/&quot; target=&quot;_blank&quot;&gt;12. episode&lt;/a&gt; of &lt;a href=&quot;http://www.summerofnhibernate.com/&quot; target=&quot;_blank&quot;&gt;Summer of NHibernate&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Other Repository classes inherited from Repository&amp;lt;T&amp;gt; have its own methods for retrieving entities. These methods are mostly using Criteria API. More on Criteria API and HQL in &lt;a href=&quot;http://codemind.blogspot.com/2008/08/nhibernate-learning-material.html&quot; target=&quot;_blank&quot;&gt;NHibernate learning material&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/3854956330692571789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/3854956330692571789' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3854956330692571789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3854956330692571789'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/10/repository-implementation.html' title='Repository implementation'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-1940141297771338028</id><published>2008-10-16T01:55:00.001+02:00</published><updated>2008-10-16T11:54:45.285+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>Mapping entities with NHibernate</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/miroslav.popovic/SPaC_i-CrLI/AAAAAAAAACU/VUvfNAC2uBw/s1600-h/Mappings%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 0px 10px; border-right-width: 0px&quot; height=&quot;244&quot; alt=&quot;Mappings&quot; src=&quot;http://lh5.ggpht.com/miroslav.popovic/SPaDA6InsdI/AAAAAAAAACY/9UaO6vxdWek/Mappings_thumb%5B1%5D.jpg?imgmax=800&quot; width=&quot;170&quot; align=&quot;right&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;The &lt;a href=&quot;http://codemind.blogspot.com/2008/10/unit-testing-domain.html&quot; target=&quot;_blank&quot;&gt;next thing&lt;/a&gt; to be done was &lt;a href=&quot;http://www.nhforge.org&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt; mapping. Mappings are defined in Peniko.DataLayer project.&lt;/p&gt;  &lt;p&gt;Every entity class has its own mapping file. Mapping file is named after a class, so if class name is Category, the mapping file is &lt;em&gt;Category.hbm.xml&lt;/em&gt;. hbm stands for Hibernate mapping. Having this naming scheme is not required, but NHibernate will try to look for these names automatically when mapping. If you want to name your mappings differently, then you&#39;ll need to tell that to NHibernate.&lt;/p&gt;  &lt;p&gt;Mapping file must have Embedded Resource build action. That&#39;s the thing that gets easily forgotten, so double check all your mapping files.&lt;/p&gt;  &lt;p&gt;Writing a mapping file can be tedious and error-prone, but there is a cure for that. NHibernate comes with two XML schema files (nhibernate-configuration.xsd and nhibernate-mapping.xsd) that you can copy to Program Files\Microsoft Visual Studio 9.0\Xml\Schemas. Once there, they&#39;ll provide you with Intelli-sense when writing NHibernate mappings and configuration in Visual Studio.&lt;/p&gt;  &lt;p&gt;If you are &lt;a href=&quot;http://www.jetbrains.com/resharper/&quot; target=&quot;_blank&quot;&gt;ReSharper&lt;/a&gt; user, there is also a nice &lt;a href=&quot;http://code.google.com/p/nhplugin/&quot; target=&quot;_blank&quot;&gt;ReSharper NHibernate plugin&lt;/a&gt;. It checks type, assembly and property names and allows navigation to mapped classes with Ctrl+Click on class or property name. Also, any renames are reflected in mapping file.&lt;/p&gt;  &lt;p&gt;Below is an example of a very simple mapping:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;xml&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;encoding&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; ?&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;hibernate-mapping&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;xmlns&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;urn:nhibernate-mapping-2.2&lt;/span&gt;&amp;quot;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;assembly&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Peniko.Domain&lt;/span&gt;&amp;quot;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;BLDotNet.Peniko.Domain&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Category&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;table&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Categories&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Id&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;CategoryId&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;generator&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;guid&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Name&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;Name&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;50&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;not-null&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;unique&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;hibernate-mapping&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;You must fully qualify type names in mapping files (&amp;quot;Namespace.Class, Assembly&amp;quot;), or you can define assembly and namespace attributes on root tag.&lt;/p&gt;  &lt;p&gt;If the table name differs from the class name, there has to be a table attribute on &amp;lt;class&amp;gt; tag. In our case, all table names are plural.&lt;/p&gt;  &lt;p&gt;id must be defined for all mapped classes. There are different id generators in NHibernate, but you&#39;ll most likely choose between &amp;quot;guid&amp;quot; and &amp;quot;native&amp;quot;. When &amp;quot;native&amp;quot; generator is selected, NHibernate will use database generated value - this is an identity field in SQL Server. NHibernate maintains ids itself, so you don&#39;t have to ever assign values to them (unless you are using &amp;quot;assigned&amp;quot; generator).&lt;/p&gt;  &lt;p&gt;All simple properties are mapped with &amp;lt;property&amp;gt; tag. There are also &amp;lt;many-to-one&amp;gt;, &amp;lt;one-to-one&amp;gt; and &amp;lt;one-to-many&amp;gt; tags for relations with other mapped classes; &amp;lt;subclass&amp;gt; and &amp;lt;joined-subclass&amp;gt; for inheritance mapping; &amp;lt;map&amp;gt;, &amp;lt;set&amp;gt;, &amp;lt;list&amp;gt; and &amp;lt;bag&amp;gt; for collection mapping and even more tags. &lt;/p&gt;  &lt;p&gt;This should be enough to get you started with NHibernate mapping. For more details see &lt;a href=&quot;http://codemind.blogspot.com/2008/08/nhibernate-learning-material.html&quot; target=&quot;_blank&quot;&gt;NHibernate learning material&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/1940141297771338028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/1940141297771338028' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/1940141297771338028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/1940141297771338028'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/10/mapping-entities-with-nhibernate.html' title='Mapping entities with NHibernate'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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="http://lh5.ggpht.com/miroslav.popovic/SPaDA6InsdI/AAAAAAAAACY/9UaO6vxdWek/s72-c/Mappings_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-529851473159425993</id><published>2008-10-16T00:30:00.001+02:00</published><updated>2008-10-16T00:30:44.764+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="unit testing"/><title type='text'>Unit Testing the Domain</title><content type='html'>&lt;p&gt;This post is a follow-up to &lt;a href=&quot;http://codemind.blogspot.com/2008/08/are-you-valid.html&quot; target=&quot;_blank&quot;&gt;Are you valid?&lt;/a&gt;. Last time I tried to explain how the validation is done in our Domain project. &lt;/p&gt;  &lt;p&gt;Peniko.Domain.Tests project contains Unit Tests for our Entity classes. The tests are written using &lt;a href=&quot;http://www.nunit.org/&quot; target=&quot;_blank&quot;&gt;NUnit&lt;/a&gt; library. Every entity class has its own test fixture. Below is a sample fixture for Category entity:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;namespace&lt;/span&gt; BLDotNet.Peniko.Domain.Tests&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;CategoryFixture&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; NameMaxLength = 50;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Category&lt;/span&gt; _category;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;SetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; SetUp()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _category = &lt;span style=&quot;color: #2b91af&quot;&gt;TestGlobals&lt;/span&gt;.GetValidCategory();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; CanCreateCategory()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.IsTrue(_category.IsValid);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;NewCategory&amp;quot;&lt;/span&gt;, _category.Name);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; CannotHaveNullName()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _category.Name = &lt;span style=&quot;color: blue&quot;&gt;null&lt;/span&gt;;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.IsFalse(_category.IsValid);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; CannotHaveEmptyName()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _category.Name = &lt;span style=&quot;color: #2b91af&quot;&gt;String&lt;/span&gt;.Empty;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.IsFalse(_category.IsValid);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; CanHaveMaxLengthName()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _category.Name = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;String&lt;/span&gt;(&lt;span style=&quot;color: #a31515&quot;&gt;&#39;A&#39;&lt;/span&gt;, NameMaxLength);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.IsTrue(_category.IsValid);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; CannotHaveTooBigName()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _category.Name = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;String&lt;/span&gt;(&lt;span style=&quot;color: #a31515&quot;&gt;&#39;A&#39;&lt;/span&gt;, NameMaxLength + 1);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Assert&lt;/span&gt;.IsFalse(_category.IsValid);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;And here is how the Category class looks like:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;namespace&lt;/span&gt; BLDotNet.Peniko.Domain&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Category&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;Category&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;NotNullValidator&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;StringLengthValidator&lt;/span&gt;(1, 50, &lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceName = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;CategoryNameLength&amp;quot;&lt;/span&gt;,&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceType = &lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;Category&lt;/span&gt;))]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; Name { &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue&quot;&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This case is very simple. Category has only one property - Name, apart from Id inherited from Entity class. The fixture only tests if the Category object can be created and if the validation is OK. Name property is tested for null and upper and lower length boundaries. &lt;/p&gt;  &lt;p&gt;You&#39;ll notice that there is a &lt;font face=&quot;Consolas&quot;&gt;SetUp()&lt;/font&gt; method that uses &lt;font face=&quot;conso&quot;&gt;TestGlobals.GetValidCategory()&lt;/font&gt; method to create the Category to test. &lt;font face=&quot;consol&quot;&gt;TestGlobals&lt;/font&gt; is a static class containing methods to create valid entities. We extracted entity creation from our test classes so we can reuse some entities as properties of other entities. &lt;/p&gt;  &lt;p&gt;I.e. Project object has a Category property. &lt;font face=&quot;consola&quot;&gt;TestGlobals.GetValidProject()&lt;/font&gt; calls &lt;font face=&quot;consol&quot;&gt;TestGlobals.GetValidCategory()&lt;/font&gt; to assign to Category property. Some of you may ask now: &lt;em&gt;Hey, what about &lt;a href=&quot;http://en.wikipedia.org/wiki/Mock_object&quot; target=&quot;_blank&quot;&gt;mocking&lt;/a&gt;? Shouldn&#39;t you assign the mock Category to Project?&lt;/em&gt; Well, we are going one step at a time, no mocking frameworks learned yet :)&lt;/p&gt;  &lt;p&gt;Most of our Domain tests looks like this. Some of the classes like OutputInvoiceDetail and InputInvoiceDetail have encapsulated calculations, so their tests are little more complicated, but not worth mentioning.&lt;/p&gt;  &lt;p&gt;There are no Repository tests in Peniko.Domain.Tests project. Repositories are tested in separated DataLayer.Tests project. More on that later.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/529851473159425993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/529851473159425993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/529851473159425993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/529851473159425993'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/10/unit-testing-domain.html' title='Unit Testing the Domain'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-336329854904035091</id><published>2008-10-06T14:37:00.001+02:00</published><updated>2008-10-06T14:37:46.081+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><category scheme="http://www.blogger.com/atom/ns#" term="ALT.NET"/><title type='text'>You are an idiot!</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/miroslav.popovic/SOoGkqKbNvI/AAAAAAAAACM/X142okMPTRY/s1600-h/idiot%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 0px 2px 15px; border-right-width: 0px&quot; height=&quot;172&quot; alt=&quot;idiot&quot; src=&quot;http://lh5.ggpht.com/miroslav.popovic/SOoGlojgT6I/AAAAAAAAACQ/07YH74oYYkc/idiot_thumb%5B1%5D.jpg?imgmax=800&quot; width=&quot;214&quot; align=&quot;right&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;I just had an interesting conversation with a friend of mine. He recently started to learn NHibernate, in fact we are working together on one application.&amp;#160; &lt;/p&gt;  &lt;p&gt;Apparently, he got into an argument with his co-worker about &lt;a href=&quot;http://www.hibernate.org/343.html&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-relational_mapping&quot; target=&quot;_blank&quot;&gt;O/RM&lt;/a&gt; in general. The co-worker of his is an experienced developer, the kind of people whose advice you would appreciate. And he had an advice. Don&#39;t use O/RM! It&#39;s slow, unnecessary complication which favors Java style of architecture. Oh, and it&#39;s extremely hard for debugging and maintenance! He used an O/RM in ONE project, and it&#39;s bad. Let&#39;s all avoid it.&lt;/p&gt;  &lt;p&gt;Needles to say, but these arguments made my friend feel bad. Was it a bad decision to start learning NHibernate and to use it in an application?&lt;/p&gt;  &lt;p&gt;The title of this post is a little harsh, but whenever I have an argument like this I always feel that the other person is trying to say to me that I&#39;m an idiot. &amp;quot;Yes, you are!&amp;quot;, you might said, &amp;quot;Why should it bother you. Don&#39;t take it to the heart.&amp;quot; Well, what can I say ... It does bother me, so let me have my own arguments here.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;It&#39;s slow&lt;/strong&gt; - He&#39;s right. O/RM is slower than plain ADO.NET code. Several percents or tens of percents. Hell, it&#39;s another abstraction layer, it has to be. .NET Framework applications are slower than C++ ones, and C++ applications are slower than assembler ones. Does this mean that we should ditch .NET in favor of assembler? Maybe, for a tiny performance critical application or parts of code, but for an enterprise application...? The benefits of an O/RM outweighs the performance impact in most situations. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Unnecessary complication&lt;/strong&gt; - I shouldn&#39;t even comment this, because I&#39;m not sure what he meant or how was his application structured. In most cases I encountered, the developers (myself included) were more responsible for complicated applications than frameworks or tools. We often start using something just after looking at Hello World sample. Don&#39;t get me wrong, this can work, we learn as we go, but we should take a time to at least find and learn best practices.       &lt;br /&gt;I still remember what came out of my first CSLA application. Boy, was it a mess.       &lt;br /&gt;Or my first relational database application. It should have stored daily entries with details, plain master-detail case. I remember creating a table per day in code (Entry_10_05_99, Entry_10_06_99...), so each day details had it&#39;s own table. The case for &lt;a href=&quot;http://thedailywtf.com/&quot; target=&quot;_blank&quot;&gt;The Daily WTF&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Java style architecture&lt;/strong&gt; - WTF?!? What&#39;s wrong with Java? I&#39;ve never used it professionally, but still appreciate all ideas borrowed from it in .NET Framework and third-party libraries and tools. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Hard for maintenance and debugging&lt;/strong&gt; - Really? I wonder what O/RM has he been using. NHibernate uses &lt;a href=&quot;http://logging.apache.org/log4net/index.html&quot; target=&quot;_blank&quot;&gt;log4net&lt;/a&gt; for logging and has option to log ALL generated SQL code. If that&#39;s not enough for you, it&#39;s Open Source, so you can attach the debugger to it and step thru the code if necessary.       &lt;br /&gt;Hard to maintain? Let me tell you about the big enterprise application I had worked on several years ago and still have to maintain it... We did some bad design decisions and end up with business code in both .NET application and SQL Server stored procedures. Whenever we have to change something we make a change in stored procedure, than in .NET application, then deploy it, fix bugs, etc. Those changes in two places are rather tedious. Not to mention we don&#39;t have stored procedures under source control for obvious reasons. In other, NHibernate powered application, we have to only refactor and deploy. All our code is in one place, and under source control. That&#39;s why I favor &amp;quot;stored procedure&amp;quot;-less databases lately.       &lt;br /&gt;And one more thing... Ever tried Unit / Integration Tests? You&#39;ll definitely have less bugs to cope with later on. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Final words. Don&#39;t let anyone kill your desire to learn new things just because he/she had tried it once and consider it bad. Try it for yourself, at least on a small test project. Learn more, don&#39;t limit yourself to one technology / framework / tool. Oh, and take your time to learn best practices :)&lt;/p&gt;  &lt;p&gt;That&#39;s what &lt;a href=&quot;http://altdotnet.org/&quot; target=&quot;_blank&quot;&gt;ALT.NET&lt;/a&gt; tries to teach us.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/336329854904035091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/336329854904035091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/336329854904035091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/336329854904035091'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/10/you-are-idiot.html' title='You are an idiot!'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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="http://lh5.ggpht.com/miroslav.popovic/SOoGlojgT6I/AAAAAAAAACQ/07YH74oYYkc/s72-c/idiot_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-3584064441356936857</id><published>2008-08-16T20:13:00.001+02:00</published><updated>2008-08-16T20:14:00.002+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="VAB"/><title type='text'>Are you valid?</title><content type='html'>&lt;p&gt;The next thing we wanted to implement to our &lt;a href=&quot;http://codemind.blogspot.com/2008/08/core-of-all-applications.html&quot; target=&quot;_blank&quot;&gt;Core&lt;/a&gt; project was a business object validation. There are several paths we could take:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;To use &lt;a href=&quot;http://www.codeplex.com/entlib&quot; target=&quot;_blank&quot;&gt;Enterprise Library&lt;/a&gt;&#39;s VAB (&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc511802.aspx&quot; target=&quot;_blank&quot;&gt;Validation Application Block&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;To use some other open source validation library&lt;/li&gt;    &lt;li&gt;To roll out our own validation and implement &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo.aspx&quot; target=&quot;_blank&quot;&gt;IDataErrorInfo&lt;/a&gt; interface for UI to use&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Because we qualified this application as a learning project, and we haven&#39;t used VAB before, we decided to try it. VAB enables developers to attach validation rules to properties in declarative way, by using attributes. Rules can also be defined in config file, allowing the simple rules change after the application is deployed, but that wasn&#39;t a requirement for this project.&lt;/p&gt;  &lt;p&gt;Most of our entity classes now have properties that look like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;[&lt;span style=&quot;color: #2b91af&quot;&gt;NotNullValidator&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;[&lt;span style=&quot;color: #2b91af&quot;&gt;StringLengthValidator&lt;/span&gt;(3, 15,&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceName = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;ProductCodeLength&amp;quot;&lt;/span&gt;,&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceType = &lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;))]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; Code { &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue&quot;&gt;set&lt;/span&gt;; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;[&lt;span style=&quot;color: #2b91af&quot;&gt;NotNullValidator&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;[&lt;span style=&quot;color: #2b91af&quot;&gt;StringLengthValidator&lt;/span&gt;(1, 50,&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceName = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;ProductNameLength&amp;quot;&lt;/span&gt;,&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; MessageTemplateResourceType = &lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt; (&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;))]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; Name { &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue&quot;&gt;set&lt;/span&gt;; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;In order to avoid cluttering of code with localized error messages, they are moved to project resources, hence the MessageTemplateResourceName and MessageTemplateResourceType arguments.&lt;/p&gt;  &lt;p&gt;And now the big thing... In order to check the object validity, IsValid() method is added to &lt;a href=&quot;http://codemind.blogspot.com/2008/08/core-of-all-applications.html&quot; target=&quot;_blank&quot;&gt;Entity&amp;lt;T&amp;gt;&lt;/a&gt; class (base class for all our entity objects, defined as Entity&amp;lt;T&amp;gt; where T: Entity&amp;lt;T&amp;gt;). IsValid is calling VAB Validator to check the property values on the object and returns true if object is valid. The first version looked like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; IsValid()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: #2b91af&quot;&gt;Validation&lt;/span&gt;.Validate((T)&lt;span style=&quot;color: blue&quot;&gt;this&lt;/span&gt;);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Validation class is a fa&amp;#231;ade. It creates a Validator object and tests for validity in a single line of code. Validate method is actually generic - &lt;span style=&quot;color: #2b91af&quot;&gt;Validation&lt;/span&gt;.Validate&amp;lt;T&amp;gt;((T)&lt;span style=&quot;color: blue&quot;&gt;this&lt;/span&gt;), but T argument is redundant. &lt;/p&gt;  &lt;p&gt;The cast to type T was necessary, because the Validator isn&#39;t smart enough to go down the inheritance hierarchy. If we call Validate(this), it would try to find validation rules on the current class (Entity&amp;lt;T&amp;gt;), but not on inheriting classes. I.e. &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;&amp;gt;. By having a cast to T (Product in this case), we ensure that the rules are checked on the Product class.&lt;/p&gt;  &lt;p&gt;This worked fine up until recently, when our entity model became more advanced:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Warehouse&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;Warehouse&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;...&lt;/p&gt; &lt;/div&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;CommissionerWarehouse&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Warehouse&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;...&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;IsValid method couldn&#39;t handle the CommissionerWarehouse class. The cast to T in Validate method gave it only a Warehouse type to check. CommissionerWarehouse rules were ignored. In order to handle this case, IsValid was rewritten to use the Validator object directly:&lt;/p&gt;  &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; IsValid()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; entityValidator = &lt;span style=&quot;color: #2b91af&quot;&gt;ValidationFactory&lt;/span&gt;.CreateValidator(GetType());&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; entityValidator.Validate(&lt;span style=&quot;color: blue&quot;&gt;this&lt;/span&gt;).IsValid;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The code is twice as long as before, but I can live with it :)&lt;/p&gt;  &lt;p&gt;The magic of this method allows easier Unit Testing (more on that later) and validation calls from the client without the reference to Validation Application Block assemblies. We could add some method to return error messages too, but that&#39;s not necessary, since we are using &lt;a href=&quot;http://www.bennedik.de/&quot; target=&quot;_blank&quot;&gt;Martin Bennedik&lt;/a&gt;&#39;s &lt;a href=&quot;http://www.bennedik.de/2008/05/wpf-integration-for-vab-update-for.html&quot; target=&quot;_blank&quot;&gt;WPF Integration for VAB&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/3584064441356936857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/3584064441356936857' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3584064441356936857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3584064441356936857'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/08/are-you-valid.html' title='Are you valid?'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-7779396896299625766</id><published>2008-08-09T16:36:00.001+02:00</published><updated>2008-08-09T16:36:11.545+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD"/><title type='text'>The core of all applications</title><content type='html'>&lt;p&gt;Today, I&#39;ll talk a little about the core of &lt;a href=&quot;http://codemind.blogspot.com/2008/07/i-want-to-be-like-uncle-karl.html&quot; target=&quot;_blank&quot;&gt;our application&lt;/a&gt;. There are many terms to describe it: business layer/model, entity layer/model, domain layer/model, middle layer... Whatever you want to call it, it still represents the problem you are trying to solve. &lt;/p&gt;  &lt;p&gt;Being highly influenced by &lt;a href=&quot;http://codemind.blogspot.com/2008/08/nhibernate-learning-material.html&quot; target=&quot;_blank&quot;&gt;some articles we read&lt;/a&gt;, we mostly use &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-driven_design&quot; target=&quot;_blank&quot;&gt;Domain-Driven Design&lt;/a&gt; terms. So, our core project is called Peniko.Domain (&lt;a href=&quot;http://www.peniko.com/&quot; target=&quot;_blank&quot;&gt;Peniko&lt;/a&gt; is the name of my friends&#39; company). This project started as a collection of &lt;a href=&quot;http://en.wikipedia.org/wiki/Plain_Old_CLR_Object&quot; target=&quot;_blank&quot;&gt;POCO&lt;/a&gt; classes without much behavior, just enough to accommodate NHibernate&#39;s needs, but as we moving toward the higher layers of the application, it&#39;s getting more &amp;quot;intelligent&amp;quot;. Below is the current class diagram.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/miroslav.popovic/SJ2rLCbF_nI/AAAAAAAAACA/-vsFFZ4m6Ts/s1600-h/Model7.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;463&quot; alt=&quot;Peniko.Domain class diagram&quot; src=&quot;http://lh3.ggpht.com/miroslav.popovic/SJ2rVhsrOJI/AAAAAAAAACI/Czf6jqxFed0/Model_thumb6.png?imgmax=800&quot; width=&quot;660&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;All class names are in English, except for PdvRate class. It should be VatRate (PDV = &lt;a href=&quot;http://en.wikipedia.org/wiki/Value_added_tax&quot; target=&quot;_blank&quot;&gt;VAT&lt;/a&gt;), but we prefer our local acronym. You&#39;ll notice that all classes inherit from Entity&amp;lt;T&amp;gt; and below is how this class looked when it&#39;s created. The class is copied from &lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/04/identity-field-equality-and-hash-code.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and renamed to Entity.&lt;/p&gt;  &lt;div style=&quot;font-size: 8pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;div style=&quot;font-size: 8pt; background: white; color: black; font-family: consolas&quot;&gt;     &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;abstract&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style=&quot;color: blue&quot;&gt;where&lt;/span&gt; T : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt;? _oldHashCode;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; Gets or sets the object Id.&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;virtual&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt; Id { &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;; &lt;span style=&quot;color: blue&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;set&lt;/span&gt;; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160; &lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; ..&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;.&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: gray&quot;&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; Equals(&lt;span style=&quot;color: blue&quot;&gt;object&lt;/span&gt; obj)&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; other = obj &lt;span style=&quot;color: blue&quot;&gt;as&lt;/span&gt; T;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (other == &lt;span style=&quot;color: blue&quot;&gt;null&lt;/span&gt;) &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: green&quot;&gt;// Handle the case of comparing two NEW objects&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; otherIsTransient = Equals(other.Id, &lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt;.Empty);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; thisIsTransient = Equals(Id, &lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt;.Empty);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (otherIsTransient &amp;amp;&amp;amp; thisIsTransient)&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; ReferenceEquals(other, &lt;span style=&quot;color: blue&quot;&gt;this&lt;/span&gt;);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; other.Id.Equals(Id);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; ... &lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: gray&quot;&gt;///&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: gray&quot;&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; GetHashCode()&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: green&quot;&gt;// Once we have a hash code we&#39;ll never change it&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (_oldHashCode.HasValue) &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; _oldHashCode.Value;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; thisIsTransient = Equals(Id, &lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt;.Empty);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: green&quot;&gt;// When this instance is transient, we use the base GetHashCode()&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: green&quot;&gt;// and remember it, so an instance can NEVER change its hash code.&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt; (thisIsTransient)&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _oldHashCode = &lt;span style=&quot;color: blue&quot;&gt;base&lt;/span&gt;.GetHashCode();&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; _oldHashCode.Value;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; Id.GetHashCode();&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;operator&lt;/span&gt; ==(&lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt; x, &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt; y)&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; Equals(x, y);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;operator&lt;/span&gt; !=(&lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt; x, &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt; y)&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; !(x == y);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;There is one more important concept added to Domain project. &lt;a href=&quot;http://martinfowler.com/eaaCatalog/repository.html&quot; target=&quot;_blank&quot;&gt;Repository pattern&lt;/a&gt; interfaces. We are reevaluating the decision to have the repository interfaces in domain layer, but for now they are there. The purpose of repositories is to communicate with the mapping layer (load entities, save and delete them). Because CRUD operations are common for all our repositories, we created a base IRepository&amp;lt;T&amp;gt; interface. It looks like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 8pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;IRepository&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style=&quot;color: blue&quot;&gt;where&lt;/span&gt; T : &lt;span style=&quot;color: #2b91af&quot;&gt;Entity&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Add(T entity);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Update(T entity);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Delete(T entity);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; T GetById(&lt;span style=&quot;color: #2b91af&quot;&gt;Guid&lt;/span&gt; id);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt; GetAll();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Other interfaces inherit IRepository&amp;lt;T&amp;gt;, and add more methods if necessary. I.e. IProductRepository looks like this:&lt;/p&gt;  &lt;div style=&quot;font-size: 8pt; background: white; color: black; font-family: consolas&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;IProductRepository&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;IRepository&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt; GetProductByCode(&lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; code);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Product&lt;/span&gt; GetProductByBarCode(&lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; barCode);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The classes implementing Repository interfaces are located in Peniko.DataAccess project. I&#39;ll talk more about them more in one of the following posts.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/7779396896299625766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/7779396896299625766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7779396896299625766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7779396896299625766'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/08/core-of-all-applications.html' title='The core of all applications'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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="http://lh3.ggpht.com/miroslav.popovic/SJ2rVhsrOJI/AAAAAAAAACI/Czf6jqxFed0/s72-c/Model_thumb6.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-5882891786406406634</id><published>2008-08-01T14:38:00.001+02:00</published><updated>2008-08-01T14:41:19.165+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD"/><category scheme="http://www.blogger.com/atom/ns#" term="NHibernate"/><title type='text'>NHibernate learning material</title><content type='html'>&lt;p&gt;We &lt;a href=&quot;http://codemind.blogspot.com/2008/07/i-want-to-be-like-uncle-karl.html&quot; target=&quot;_blank&quot;&gt;started off&lt;/a&gt; by learning &lt;a href=&quot;http://www.hibernate.org/343.html&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt;. Up until then I didn&#39;t use any OR/M (I don&#39;t consider LINQ 2 SQL to be a full OR/M). Most of the time, the code I wrote used ADO.NET DataReaders, alone or inside &lt;a href=&quot;http://www.lhotka.net/cslanet/&quot; target=&quot;_blank&quot;&gt;CSLA.NET&lt;/a&gt; DataPortal_xxx methods.&lt;/p&gt;  &lt;p&gt;Since there is a lot of &lt;a href=&quot;http://weblogs.asp.net/fbouma/archive/2008/05/19/why-use-the-entity-framework-yeah-why-exactly.aspx&quot; target=&quot;_blank&quot;&gt;buzz&lt;/a&gt; lately about OR/Ms, &lt;a href=&quot;http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework&quot; target=&quot;_blank&quot;&gt;Entity Framework&lt;/a&gt; is about to be released, it already got a &lt;a href=&quot;http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/&quot; target=&quot;_blank&quot;&gt;vote of no confidence&lt;/a&gt; from &lt;a href=&quot;http://altdotnet.org/&quot; target=&quot;_blank&quot;&gt;ALT.NET&lt;/a&gt; group, etc, the good learning material isn&#39;t so hard to find. When I&#39;m learning something new, I&#39;m trying to find and use &lt;strike&gt;best&lt;/strike&gt; good practices, established by the people who have been used that technology for a longer time. The following posts/articles/screencasts really helped me and my team to get on the right track.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/Default.aspx&quot; target=&quot;_blank&quot;&gt;The NHibernate FAQ&lt;/a&gt; by Gabriel Schenker is a great starting point:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/03/31/prepare-your-system-for-nhibernate.aspx&quot;&gt;Prepare your system for NHibernate&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/01/your-first-nhibernate-based-application.aspx&quot;&gt;Your first NHibernate based application&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/03/lazy-loading---eager-loading.aspx&quot;&gt;Lazy Loading - Eager Loading&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/04/identity-field-equality-and-hash-code.aspx&quot;&gt;Identity Field, Equality and Hash Code&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/06/how-to-setup-a-new-solution.aspx&quot;&gt;How to setup a new solution&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/06/eager-loading-aggregate-with-many-child-collections.aspx&quot;&gt;Eager loading aggregate with many child collections&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/08/soft-deletes.aspx&quot;&gt;Soft Deletes&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/10/nhibernate-and-the-unit-of-work-pattern.aspx&quot;&gt;NHibernate and the Unit of Work Pattern&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/13/nhibernate-and-the-unit-of-work-pattern-part-2.aspx&quot;&gt;NHibernate and the Unit of Work Pattern (Part 2)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/26/nhibernate-and-the-unit-of-work-pattern-part-3.aspx&quot;&gt;NHibernate and the Unit of Work pattern (Part 3)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/26/nhibernate-and-castle-active-record-part-1.aspx&quot;&gt;NHibernate and Castle Active Record (Part 1)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/28/create-and-update-database-schema.aspx&quot;&gt;Create and Update Database Schema&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/06/loading-a-complex-object-graph.aspx&quot;&gt;Loading a complex object graph&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/14/how-to-map-a-tree-in-nhibernate.aspx&quot;&gt;How to map a tree in NHibernate&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/06/12/mapping-collections-in-nhibernate-part-1.aspx&quot;&gt;Mapping Collections in NHibernate (Part 1)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/07/01/how-to-configure-log4net-for-use-with-nhibernate.aspx&quot;&gt;How to configure Log4Net for use with NHibernate&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href=&quot;http://www.unhandled-exceptions.com/blog/&quot; target=&quot;_blank&quot;&gt;Steve Bohlen&lt;/a&gt;&#39;s excellent screencast series &lt;a href=&quot;http://www.summerofnhibernate.com/&quot; target=&quot;_blank&quot;&gt;Summer of NHibernate&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.flux88.com/&quot; target=&quot;_blank&quot;&gt;Ben Scheirman&lt;/a&gt;&#39;s series of articles about NHibernate and Domain Driven Design:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/07/05/A+Journey+With+NHibernate++Part+1.aspx&quot;&gt;A Journey with NHibernate - Part 1&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/07/10/A+Journey+With+NHibernate++Part+2.aspx&quot;&gt;A Journey With NHibernate - Part 2&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/07/20/A+Journey+With+NHibernate+And+DDD++Part+3.aspx&quot;&gt;A Journey With NHibernate (and DDD) - Part 3&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/07/23/A+Journey+With+Domain+Driven+Design+And+NHibernate++Part+4.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 4&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/08/24/A+Journey+With+Domain+Driven+Design+And+NHibernate++Part+5.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 5&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/09/02/A+Journey+With+Domain+Driven+Design+And+NHibernate++Part+6.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 6&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.flux88.com/2006/11/14/A+Journey+With+Domain+Driven+Design+And+NHibernate++Part+7.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 7&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://flux88.com/AJourneyWithDomainDrivenDesignAndNHibernatePart8.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 8&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://flux88.com/AJourneyWithDomainDrivenDesignAndNHibernatePart9.aspx&quot;&gt;A Journey with Domain Driven Design (and NHibernate) - Part 9&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href=&quot;http://davybrion.com/blog/&quot; target=&quot;_blank&quot;&gt;Davy Brion&lt;/a&gt;&#39;s &lt;a href=&quot;http://davybrion.com/blog/category/nhibernate/&quot; target=&quot;_blank&quot;&gt;NHibernate posts&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;THE article &lt;a href=&quot;http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx&quot; target=&quot;_blank&quot;&gt;NHibernate Best Practices with ASP.NET&lt;/a&gt; by &lt;a href=&quot;http://devlicio.us/blogs/billy_mccafferty/default.aspx&quot;&gt;Billy McCafferty&lt;/a&gt;. I&#39;m looking forward for a chance to try his &lt;a href=&quot;http://www.codeplex.com/SharpArchitecture&quot; target=&quot;_blank&quot;&gt;S#arp Architecture&lt;/a&gt; on a real project.&lt;/p&gt;  &lt;p&gt;David Veeneman&#39;s &lt;a href=&quot;http://www.codeproject.com/KB/database/Nhibernate_Made_Simple.aspx&quot; target=&quot;_blank&quot;&gt;NHibernate Made Simple&lt;/a&gt; article.&lt;/p&gt;  &lt;p&gt;All of the above links will not only teach you how to use NHibernate, but also give you a start with Domain Driven Design, Unit Testing, Integration Testing, logging etc. Enjoy!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/5882891786406406634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/5882891786406406634' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/5882891786406406634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/5882891786406406634'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/08/nhibernate-learning-material.html' title='NHibernate learning material'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-3827127113396778525</id><published>2008-07-31T20:01:00.001+02:00</published><updated>2008-07-31T20:01:36.542+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ALT.NET"/><title type='text'>I want to be like uncle Karl</title><content type='html'>&lt;p&gt;In my &lt;a href=&quot;http://codemind.blogspot.com/2008/07/second-life-of-this-blog.html&quot;&gt;previous post&lt;/a&gt;, I mentioned that I&#39;m learning a lot of new stuff lately. So, what is it?&lt;/p&gt;  &lt;p&gt;Actually, I&#39;m trying to learn tools from &lt;a href=&quot;http://altdotnet.org/&quot; target=&quot;_blank&quot;&gt;ALT.NET&lt;/a&gt; toolbox. While I was always leaning towards software architecture, following &lt;a href=&quot;http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756&quot; target=&quot;_blank&quot;&gt;Framework Design Guidelines&lt;/a&gt; and &amp;quot;best practices&amp;quot;, reading and learning about new things in .NET community, somehow I&#39;ve managed to avoid using things like &lt;a href=&quot;http://en.wikipedia.org/wiki/Unit_testing&quot; target=&quot;_blank&quot;&gt;Unit Testing&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Object-relational_mapping&quot; target=&quot;_blank&quot;&gt;O/RM&lt;/a&gt; (I&#39;m &lt;a href=&quot;http://www.lhotka.net/cslanet/&quot; target=&quot;_blank&quot;&gt;CSLA.NET&lt;/a&gt; guy :) and other I consider to be invaluable to software developer. Reading blogs like &lt;a href=&quot;http://www.ayende.com/Blog/&quot; target=&quot;_blank&quot;&gt;Ayende&lt;/a&gt;&#39;s, &lt;a href=&quot;http://weblogs.asp.net/rosherove/&quot; target=&quot;_blank&quot;&gt;Roy&lt;/a&gt;&#39;s or &lt;a href=&quot;http://codebetter.com/blogs/jeremy.miller/&quot; target=&quot;_blank&quot;&gt;Jeremy&lt;/a&gt;&#39;s, just to mention a few, always made me feel inferior, and that was a good thing. The first step to knowledge is acknowledging that &lt;a href=&quot;http://en.wikipedia.org/wiki/I_know_that_I_know_nothing&quot; target=&quot;_blank&quot;&gt;&amp;quot;I know that I know nothing&amp;quot;&lt;/a&gt; :)&lt;/p&gt;  &lt;p&gt;The series of posts that really inspired me was &lt;a href=&quot;http://codebetter.com/blogs/karlseguin/default.aspx&quot; target=&quot;_blank&quot;&gt;Karl Seguin&lt;/a&gt;&#39;s &lt;a href=&quot;http://codebetter.com/blogs/karlseguin/archive/tags/Foundations/default.aspx&quot; target=&quot;_blank&quot;&gt;Foundation of Programming&lt;/a&gt;, also available as an &lt;a href=&quot;http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx&quot; target=&quot;_blank&quot;&gt;ebook&lt;/a&gt;. I even made a New Year (2008) resolution to &amp;quot;be like uncle Karl&amp;quot; :)&lt;/p&gt;  &lt;p&gt;Few months have passed without pursuing my goals, because of work / school obligations, and finally a month ago, I was asked to do a business application for my friend Branko&#39;s family business. It was a great, no time pressure, opportunity to learn, so I accepted.&lt;/p&gt;  &lt;p&gt;Together with my friends Boris and Branko (yeah, the same Branko from above :) I started the journey. We have prepared application requirements, started learning &lt;a href=&quot;http://www.hibernate.org/343.html&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt;, Unit Testing (&lt;a href=&quot;http://www.nunit.org/index.php&quot; target=&quot;_blank&quot;&gt;NUnit&lt;/a&gt;), validation (&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc511802.aspx&quot; target=&quot;_blank&quot;&gt;VAB&lt;/a&gt;), improving our WPF and of course implementing all that to the application.&lt;/p&gt;  &lt;p&gt;The application is going along nicely. I&#39;ll try to post more about it in the following posts.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/3827127113396778525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/3827127113396778525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3827127113396778525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3827127113396778525'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/07/i-want-to-be-like-uncle-karl.html' title='I want to be like uncle Karl'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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-8872538558551624494.post-3786253905672718579</id><published>2008-07-31T00:18:00.002+02:00</published><updated>2008-07-31T18:21:32.037+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Trac"/><category scheme="http://www.blogger.com/atom/ns#" term="VisualSVN"/><title type='text'>VisualSVN Server / Trac tips</title><content type='html'>&lt;p&gt;Here are few tips I return to when installing or creating a new Trac environment:&lt;/p&gt;  &lt;h4&gt;VisualSVN Server Trac installation&lt;/h4&gt;  &lt;p&gt;VisualSVN Server failed to start once I&#39;ve installed the &lt;a href=&quot;http://visualsvn.com/server/trac/&quot;&gt;Trac integration&lt;/a&gt;. Apache&#39;s log had an entry saying it cannot find mod_python.so file, although it was on the right place. After a bit of googling, I&#39;ve managed to solve the problem by adding msvcr71.dll and msvcp71.dll to my Windows System folder. I can&#39;t give a credit to a person who found the solution, because I don&#39;t remember the page where I found it.&lt;/p&gt;  &lt;h4&gt;Creating Trac environment&lt;/h4&gt;  &lt;p&gt;Before you start, make sure there you have SVN repository prepared. Also, you should have at least one user that will get TRAC_ADMIN rights. Use VisualSVN Server Manager to create SVN repository and user(s).&lt;/p&gt;  &lt;p&gt;If you have used defaults from &lt;a href=&quot;http://visualsvn.com/server/trac/&quot;&gt;Trac integration&lt;/a&gt; page, your SVN repositories will be in C:\Repositories\ and Trac environments in C:\Trac\.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Run a console and go to: C:\Program Files\VisualSVN Server\bin\python\Scripts &lt;/li&gt;    &lt;li&gt;Run: &lt;code&gt;trac-admin C:\Trac\&amp;lt;ProjectName&amp;gt; initenv&lt;/code&gt;       &lt;ul&gt;       &lt;li&gt;trac-admin will ask you a few questions, answer as below &lt;/li&gt;        &lt;li&gt;enter project name (used for Trac page title and description) &lt;/li&gt;        &lt;li&gt;database connection string (press Enter for default) &lt;/li&gt;        &lt;li&gt;repository type (Enter for default) &lt;/li&gt;        &lt;li&gt;path to repository: C:\Repositories\&amp;lt;ProjectName&amp;gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;To make a single user an administrator run: &lt;code&gt;trac-admin C:\Trac\&amp;lt;ProjectName&amp;gt; permission add &amp;lt;UserName&amp;gt; TRAC_ADMIN&lt;/code&gt; &lt;/li&gt;    &lt;li&gt;Permissions for other users can be set in Trac itself, through the Admin interface &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Additional settings&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Change the Trac environment logo      &lt;ul&gt;       &lt;li&gt;Copy new image to: C:\Program Files\VisualSVN Server\bin\python\Lib\site-packages\trac\htdocs &lt;/li&gt;        &lt;li&gt;Edit C:\Trac\&amp;lt;ProjectName&amp;gt;\conf\trac.ini, and find [header_logo] section &lt;/li&gt;        &lt;li&gt;Change src to: &lt;code&gt;src = common/image.jpg&lt;/code&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Change the default attachment size      &lt;ul&gt;       &lt;li&gt;Edit C:\Trac\&amp;lt;ProjectName&amp;gt;\conf\trac.ini, and find [attachment] section &lt;/li&gt;        &lt;li&gt;Change &lt;code&gt;max_size = 262144&lt;/code&gt; to &lt;code&gt;max_size = 2097152&lt;/code&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Use drop-down field instead of text box when defining ticket owner      &lt;ul&gt;       &lt;li&gt;This is very useful setting for smaller teams - to display all team members in a drop-down instead of typing the name in text box &lt;/li&gt;        &lt;li&gt;Edit C:\Trac\&amp;lt;ProjectName&amp;gt;\conf\trac.ini, and find [ticket] section &lt;/li&gt;        &lt;li&gt;Change &lt;code&gt;restrict_owner = false&lt;/code&gt; to &lt;code&gt;restrict_owner = true&lt;/code&gt; &lt;/li&gt;        &lt;li&gt;Note that the user will not be displayed in the drop-down until he got a session on the server. The easiest way to get the session is to log in and change user preferences. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;This post is more a note to myself. Other configuration options for Trac can be found in &lt;a href=&quot;http://trac.edgewall.org/wiki/TracGuide&quot;&gt;TracGuide&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/3786253905672718579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/3786253905672718579' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3786253905672718579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3786253905672718579'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/07/visualsvn-server-trac-tips.html' title='VisualSVN Server / Trac tips'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-7962894961618338513</id><published>2008-07-31T00:16:00.002+02:00</published><updated>2008-07-31T18:22:25.547+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Trac"/><category scheme="http://www.blogger.com/atom/ns#" term="VisualSVN"/><title type='text'>Second life (of this blog)</title><content type='html'>&lt;p&gt;It&#39;s been a long long time since my first and last post on this blog. I&#39;m learning some pretty interesting stuff lately, and I&#39;ve decided to write about them here. We&#39;ll see how long it will last this time. Hopefully more than a few posts.&lt;/p&gt;  &lt;p&gt;But first of all, let me write a follow-up to my previous post called &lt;a href=&quot;http://codemind.blogspot.com/2006/12/open-source-troubles.html&quot;&gt;Open Source troubles&lt;/a&gt;. Few months ago, I&#39;ve decided to take another shot on installing &lt;a href=&quot;http://trac.edgewall.org/&quot;&gt;Trac&lt;/a&gt;, together with two colleagues of mine. We spent almost two working days on it, but managed to get it working on one PC with all expected features (&lt;a href=&quot;http://httpd.apache.org/&quot;&gt;Apache&lt;/a&gt; server, &lt;a href=&quot;http://en.wikipedia.org/wiki/Https&quot;&gt;HTTPS&lt;/a&gt;, integrated with &lt;a href=&quot;http://subversion.tigris.org/&quot;&gt;Subversion&lt;/a&gt;...). When we tried to repeat the process on our server, new problems aroused. Just few minutes before loosing our mind, we managed to find a lifesaver: &lt;a href=&quot;http://visualsvn.com/server/trac/&quot;&gt;VisualSVN Server Trac Integration&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;We had already used &lt;a href=&quot;http://visualsvn.com/server/&quot;&gt;VisualSVN Server&lt;/a&gt; as our Subversion server for quite some time. It&#39;s extremely easy to install and use, has a nice management console and can be configured to use HTTPS during installation. The Trac Integration package they prepared, makes the Trac installation smooth and painless. With the help of &lt;a href=&quot;http://visualsvn.com/server/trac/&quot;&gt;integration page&lt;/a&gt;, Trac + SVN server can be installed in a matter of minutes instead of days. &lt;/p&gt;  &lt;p&gt;One thing keeps bothering me. There is no link to this integration page anywhere on VisualSVN &lt;a href=&quot;http://visualsvn.com/&quot;&gt;site&lt;/a&gt;. I&#39;m sure it deserves at least a small link on the bottom of VisualSVN Server page, saying &quot;if you use Trac, take a look here for an integration option&quot;, or something like that. Instead, there are few discussions on &lt;a href=&quot;http://groups.google.com/group/visualsvn&quot;&gt;VisualSVN Google Group&lt;/a&gt; mentioning it.&lt;/p&gt;  &lt;p&gt;So, if you do like Trac or use VisualSVN Server, try &lt;a href=&quot;http://visualsvn.com/server/trac/&quot;&gt;this integration&lt;/a&gt;. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/7962894961618338513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/7962894961618338513' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7962894961618338513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/7962894961618338513'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2008/07/second-life-of-this-blog.html' title='Second life (of this blog)'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-3422039548900711411</id><published>2006-12-02T23:58:00.000+01:00</published><updated>2006-12-03T00:51:43.641+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><title type='text'>Open Source troubles</title><content type='html'>I&#39;m using &lt;a href=&quot;http://subversion.tigris.org/&quot;&gt;Subversion&lt;/a&gt; for a few months now (along with &lt;a href=&quot;http://tortoisesvn.tigris.org/&quot;&gt;TortoiseSVN&lt;/a&gt; and &lt;a href=&quot;http://ankhsvn.tigris.org/&quot;&gt;AnkhSVN&lt;/a&gt;), and I&#39;m very happy with it. I think it&#39;s a very good product with excellent features. It has improved my development process a lot, and I feel much safer having all my code in the repository.&lt;br /&gt;&lt;br /&gt;But, this post is not about Subversion. After successfully using Subversion, I&#39;ve decided that it&#39;ll be good to have some kind of bug tracker / wiki to improve the internal communication inside the team I work with. Actually, I&#39;ve decided that after reading &lt;a href=&quot;http://www.ayende.com/Blog/&quot;&gt;Ayende&lt;/a&gt;&#39;s &lt;a href=&quot;http://www.ayende.com/Blog/BugTrackingRoundII.aspx&quot;&gt;posts&lt;/a&gt;, and having few dozen mails a day between my team members (we are all scattered around the globe).&lt;br /&gt;&lt;br /&gt;Yesterday, I&#39;ve tried to follow Ayende&#39;s &lt;a href=&quot;http://www.ayende.com/Blog/ILoveTrac.aspx&quot;&gt;steps&lt;/a&gt;, and install &lt;a href=&quot;http://trac.edgewall.org/&quot;&gt;Trac&lt;/a&gt;. After few hours of trying different versions of Trac and required components, I&#39;ve finally managed to install it. I didn&#39;t configure it to integrate with Subversion yet ... Must leave it for a few days, to cool my head down a little :)&lt;br /&gt;&lt;br /&gt;Many people are avoiding Open Source software because of different reasons. One of the reasons is that many of OSS products are so damn hard to install and configure. I consider my self to be a power user, but this kind of staff really freaks me out. I don&#39;t want to spend two or three days just to install and configure some software, yet alone to use it. I don&#39;t have that much time to spend on something I&#39;m not quite sure I&#39;ll even use.&lt;br /&gt;&lt;br /&gt;The number of users for a software product is a very important. The more, the better. Especially for the Open Source software. More users = more bugs reported = better software. At least in my book. This is one thing where most of OSS products lack. They don&#39;t try to ease up for the user. It&#39;s not that hard to create an installation procedure. It needs to be Open Source ... Sure. Use &lt;a href=&quot;http://nsis.sourceforge.net/&quot;&gt;NSIS&lt;/a&gt;. Yeah, I know what some of you are thinking now ... &quot;Make it yourself if you need it. It&#39;s Open Source, after all.&quot; :)&lt;br /&gt;&lt;br /&gt;I&#39;ll try Trac eventually and post my opinions here. Until then, good luck with it ...</content><link rel='replies' type='application/atom+xml' href='http://codemind.blogspot.com/feeds/3422039548900711411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8872538558551624494/3422039548900711411' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3422039548900711411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/3422039548900711411'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2006/12/open-source-troubles.html' title='Open Source troubles'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8872538558551624494.post-1511406726806944115</id><published>2006-11-25T20:52:00.000+01:00</published><updated>2006-11-25T21:09:31.145+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blogging"/><title type='text'>Warming up ...</title><content type='html'>This is my first message on this new blog, so I should probably say something smart to make you come here often or even subscribe to it ...&lt;br /&gt;...&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;OK. Let&#39;s just skip the &quot;smart&quot; part. I&#39;ll give you a few warnings about my postings:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Most of my posts will be about software development (primarily .NET)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I probably won&#39;t have many posts, because I&#39;m too lazy for writing&lt;/li&gt;&lt;li&gt;You&#39;ll have to live with my terrible English&lt;/li&gt;&lt;/ol&gt;If you can live with these, then you&#39;re welcome!</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/1511406726806944115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8872538558551624494/posts/default/1511406726806944115'/><link rel='alternate' type='text/html' href='http://codemind.blogspot.com/2006/11/warming-up.html' title='Warming up ...'/><author><name>Miroslav Popovic</name><uri>http://www.blogger.com/profile/14510157338579085870</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></entry></feed>