<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://codebetter.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Ian Cooper</title><subtitle type="html" /><id>http://codebetter.com/blogs/ian_cooper/atom.aspx</id><link rel="alternate" type="text/html" href="http://codebetter.com/blogs/ian_cooper/default.aspx" /><link rel="self" type="application/atom+xml" href="http://codebetter.com/blogs/ian_cooper/atom.aspx" /><generator uri="http://communityserver.org" version="4.1.31106.3070">Community Server</generator><updated>2009-01-21T22:20:00Z</updated><entry><title>Making your code easier to understand context/specification style unit tests</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/06/29/making-your-code-easier-to-understand-context-specification-style-unit-tests.aspx" /><id>/blogs/ian_cooper/archive/2009/06/29/making-your-code-easier-to-understand-context-specification-style-unit-tests.aspx</id><published>2009-06-29T04:08:00Z</published><updated>2009-06-29T04:08:00Z</updated><content type="html">&lt;p&gt;When we started our current project we did not use &lt;a href="http://stevenharman.net/blog/archive/2009/05/27/toward-a-better-use-of-context-specification.aspx"&gt;context/specification style testing&lt;/a&gt;, instead we used &lt;a href="http://xunitpatterns.com/Testcase%20Class%20per%20Class.html"&gt;testcase-per-class&lt;/a&gt; with a &lt;a href="http://xunitpatterns.com/Four%20Phase%20Test.html"&gt;four-phase test model&lt;/a&gt; (also known as &lt;a href="http://c2.com/cgi/wiki?ArrangeActAssert"&gt;arrange-act-assert&lt;/a&gt;). Although we followed &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2009/03/31/seizing-the-bdd-nettle.aspx"&gt;story-test driven development&lt;/a&gt; (STDD) we were not explicitly Behavior-Driven Development &lt;a href="http://dannorth.net/introducing-bdd"&gt;BDD &lt;/a&gt;when we set out. Over time I began to see the path between STDD and BDD we shifted toward a BDD approach.&lt;/p&gt;
&lt;p&gt;That is really background for what comes next. As part of this shift we started writing more context/specification style tests. We did not re-write our existing testcase-per-class fixtures (then and still now I would see the possibility of using multiple &lt;a href="http://xunitpatterns.com/Test%20Organization.html"&gt;test organisational patterns&lt;/a&gt; within a project; some of our tests still seem better with testcase-per-class). Recently we have had new developers join the team. One interesting, if anecdotal, observation has been that those developers find it easier to use tests as a source of documentation for what the software is doing when they are in the context/specification style. This is a useful observation, because the rest of the team is able to supply much of the context for testcase-per-class fixtures by virtue of having worked on the codebase and so do not see the lack so easily.&lt;/p&gt;
&lt;p&gt;To build a maintainable system you have to build one where the behavior can be understood. Tests offer this promise, but often we have found that tests failed us, because the tests were no easier to comprehend than the code under test. Context/specification style tests seem to be better on this account. Of course there is no silver bullet in software. You still have to put the effort into making your context/specification tests readable, but the form seems helpful toward achieving that goal.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ll try to post more on my experiences with BDD style approaches as they come out. I would also recommend that anyone interested in the topic look at the&lt;a href="http://www.pragprog.com/titles/achbd/the-rspec-book"&gt; RSpec book&lt;/a&gt; from the Pragmatic Programmers which offers a great overview of the topic.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=249314" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="TDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/TDD/default.aspx" /><category term="xUnit" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/xUnit/default.aspx" /><category term="BDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/BDD/default.aspx" /><category term="Behavior Specification" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Behavior+Specification/default.aspx" /><category term="ATDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/ATDD/default.aspx" /><category term="STDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/STDD/default.aspx" /></entry><entry><title>Should you learn frameworks or principles</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/06/11/should-you-learn-frameworks-or-principles.aspx" /><id>/blogs/ian_cooper/archive/2009/06/11/should-you-learn-frameworks-or-principles.aspx</id><published>2009-06-11T02:12:00Z</published><updated>2009-06-11T02:12:00Z</updated><content type="html">&lt;p&gt;







&lt;/p&gt;

 
  Normal
  0
  
  
  
  
  false
  false
  false
  
  EN-GB
  X-NONE
  X-NONE
  
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4
  
   
   
   
   
   
   
   
   
   
   
   
  

 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 

&lt;p&gt;

&lt;/p&gt;



&lt;p&gt;There was a comment on the &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2009/04/14/on-learning-boo.aspx"&gt;On
Learning Boo&lt;/a&gt; post along the lines of : &lt;i&gt;I only focus on learning
frameworks, because they increase my marketability, learning new languages,
ideas like DSLs just takes time away from that effort&lt;/i&gt;. It is a fairly
common attitude. I have spoken to people who have told me that their focus is
on &lt;i&gt;learning the Microsoft .NET toolset&lt;/i&gt;, commenting that they feel that
is enough of a challenge and one that translates best into career
opportunities. I have seen recruiters and companies assessed with statements
like&lt;i&gt; 2 years of ASP.NET MVC&lt;/i&gt; as some means to indicate the competence of
a developer to join a team.&lt;/p&gt;
&lt;p&gt;At the same time for many developers the number of new frameworks tumbling
out of Redmond makes it seems like a struggle to keep up. Those who feel that they
must keep up, naturally feel overwhelmed. Restricting their focus to just what
comes out of Redmond seems like a good strategy to manage the problem.
Unfortunately, focusing on learning vendor frameworks is a trap. There will
always be another new framework to learn to do what you were doing yesterday.
Look at the churn in data access frameworks in the Microsoft space. Knowledge
gained is quickly outdated. You end up on a treadmill, learning one vendor
framework after another. You fall into the trap of appraising your next job
solely on the criteria of what frameworks your prospective employer is using, just
so that you can gain some experience using that new framework and keep your
C.V. up to date.&lt;/p&gt;
&lt;p&gt;Assessing developers by their knowledge of them, especially through
certifications is an equally bad trap for employers to fall into. At best it is
deceptive about what skills developers actually need. At worst it is a prison
because the investment of knowledge in a particular technology becomes a
ball-and-chain that makes individuals and corporations resistant to change.
Having hired all those skilled Webforms developers and learnt all those vendor
control kits, how could you rationally adopt ASP.NET MVC for your next project?
After all you don&amp;#39;t have any experience with it. Should you now dismiss your
entire team and hire experienced ASP.NET developers? Or if you do change, what
good did it do you to recruit people based on their understanding of the
ASP.NET page lifecycle. Would it not have been better to hire people who had
the skills to learn new frameworks?&lt;/p&gt;
&lt;p&gt;When I was younger, I used to focus on learning the latest toolkit because I
saw that as the best way to improve my marketability.&amp;nbsp; I spent ages poring
over the internals of MFC, ATL etc. I could talk about the details of the STL,
Boost, Loki with the best of them. I wanted to be an expert on those libraries.
I looked for new jobs when old ones did not offer me the opportunity to use the
latest and greatest frameworks. Did it make me better developer? Maybe, but not
in the way I expected. What I gained from poring over those frameworks
eventually was an appreciation of the common underlying patterns. I might have
learned something from understanding how the internals were implemented too,
but it was pattern recognition of ideas like iterators, factories, template
methods that gave me the most benefit. The next time I tried to learn a
library, seeing how it solved problems I understood, seeing how it use patterns
and principles I recognized, meant that I was able to being working with the
framework faster. But I did this hard way, not by recognizing patterns I was
aware of and seeing where they were implemented, but by discovering them seeing
them repeated.&lt;/p&gt;
&lt;p&gt;The reason so many of us get excited by books like Fowler&amp;#39;s &lt;a href="http://martinfowler.com/eaaCatalog/"&gt;Patterns of Enterprise
Application Architecture&lt;/a&gt;, his work on &lt;a href="http://martinfowler.com/eaaDev/uiArchs.html"&gt;GUI Architectures&lt;/a&gt; of
&lt;a href="http://www.martinfowler.com/bliki/DomainSpecificLanguage.html"&gt;DSLs&lt;/a&gt;
(and the work of others) is that they capture those patterns and principles.&amp;nbsp;
A solid knowledge of the principles relating models, views, and controllers
would enable you to learn a range of web frameworks ore quickly because you
look to see how they solve problems. &lt;/p&gt;
&lt;p&gt;Learning new skills such as how to write a DSL in Boo will give you the breadth of aproaches that enable you to deliver better architected applications. The burden of maintenance is greater than the burden of writing, so a better architected application is always a good investment for a company. Far more than squeezing some obscure feature out of your latest framework is.&lt;/p&gt;
&lt;p&gt;If anything the industry has moved on from those nuts and bots frameworks,
and the abstractions have gotten better. Less and less do you need to
understand the how and more and more the why? Knowledge of the patterns and
principles provide continuing value to you as frameworks change. It also helps
you understand how to use the frameworks, how to judge their quality against
some kind of best practice yardstick and how to manipulate them when they fall
short of best practice&lt;br /&gt;
&lt;br /&gt;
As someone who interviews people I look more for understanding of the
principles than the minutiae. The problem is that there will always be a new
&amp;#39;better&amp;#39; framework, a new popular paradigm. There is always the possibility
that a new language comes along that we want to use instead for a given
project. People who understand the principles can adapt. People who focus on
the detail are intransigent to change, because they have too much invested in
the framework that they have become an expert in.&lt;/p&gt;
&lt;p&gt;Now before someone suggests otherwise I am not implying that people do not
need to know how to use their tools to get the best out of them. Of course they
do. But you will find a more efficient path to assessing and learning new
frameworks through understanding the principles behind them than through
learning each one in isolation.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=248069" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry><entry><title>Introduction to NHibernate, pt. 7</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/06/04/introduction-to-nhibernate-pt-7.aspx" /><id>/blogs/ian_cooper/archive/2009/06/04/introduction-to-nhibernate-pt-7.aspx</id><published>2009-06-04T03:56:00Z</published><updated>2009-06-04T03:56:00Z</updated><content type="html">&lt;p&gt;In earlier parts of this series we looked at &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/12/12/introduction-to-nhibernate-part-2.aspx"&gt;mapping via XML mapping files&lt;/a&gt;. I wanted to look at some alternatives to the angle bracket tax. First up is the Castle project&amp;#39;s Active Record. Next time we will look at Fluent NHibernate.&lt;/p&gt;
&lt;h2&gt;Active Record Support for Attribute Based Mapping&lt;/h2&gt;
&lt;p&gt;While mapping via an xml file allows access to the full range of options that NHibernate gives us, it can be slow, because it forces us to context switch between C# and XML. Both NHibernate and Castle have attribute mapping options. NNHibernate.Mapping.Attributes is an add-in for NHibernate contributed by Pierre Henri Kuat&amp;eacute;. Active Record is part of the Castle project, originally intended to support the Active Record pattern favored by Ruby On Rails.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;We&amp;#39;ll just discuss how to use Active Record&amp;#39;s Attribute Support here. Essentially ActiveRecord contains attributes that are the equivalent of elements from the mapping file. For example to map the Customer class we mark it up as follows.&lt;/p&gt;
&lt;h3&gt;Adding the required references&lt;br /&gt;&lt;/h3&gt;
&lt;p&gt;We need to reference a number of assemblies to get ActiveRecord support:&lt;br /&gt;Castle.ActiveRecord.dll&lt;br /&gt;Castle.Core.dll&lt;br /&gt;Castle.Components.Validator.dll&lt;br /&gt;Castle.DynamicProxy.dll&lt;br /&gt;NHibernate.dll&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;We also need to change our configuration file to configure ActiveRecord instead of NHibernate (ActiveRecord configures NHibernate from this information). We an configure either by a stand-alone xml file or through the app.config. For simplicity we configure through the app.config file here. &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;We need to add a config section handler for the active record section of our configuration file:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;configSections&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;section name=&amp;quot;activerecord&amp;quot; type=&amp;quot;Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/configSections&amp;gt;&lt;br /&gt;&lt;br /&gt;The configuration mainly tells NHibernate how to access the Db. There are two key attributes of the &amp;lt;activerecord&amp;gt; element. We need to set the IsWeb attribute to true if we are an asp.net web application. We need to set the IsDebug attribute to true, if we want to see the generated mapping files (see below).&lt;/p&gt;
&lt;p&gt;Note that when working with NHibernate 2.0+ the sample code given on the Castle site for Active Record uses incorrect key values that are prefixed with NHibernate. You need to change these to omit the &amp;quot;hibernate.&amp;quot; from the name. If you forget to do this you will get messages about invalid key from log4net. This is because the hibernate.* keys are no longer in the schema.&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;configSections&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;section name=&amp;quot;activerecord&amp;quot; type=&amp;quot;Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;section name=&amp;quot;log4net&amp;quot; type=&amp;quot;log4net.Config.Log4NetConfigurationSectionHandler, log4net&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/configSections&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;activerecord isWeb=&amp;quot;false&amp;quot; isDebug=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;config&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key=&amp;quot;connection.driver_class&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;NHibernate.Driver.SqlClientDriver&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key=&amp;quot;dialect&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;NHibernate.Dialect.MsSql2000Dialect&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key=&amp;quot;connection.provider&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;NHibernate.Connection.DriverConnectionProvider&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key=&amp;quot;connection.connection_string&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;Data Source=.;Initial Catalog=nhibernate;Integrated Security=SSPI&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/config&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/activerecord&amp;gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;lt;log4net&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;appender name=&amp;quot;ConsoleAppender&amp;quot; type=&amp;quot;log4net.Appender.ConsoleAppender, log4net&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;layout type=&amp;quot;log4net.Layout.PatternLayout, log4net&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%m&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/layout&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/appender&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;root&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;priority value=&amp;quot;DEBUG&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;appender-ref ref=&amp;quot;ConsoleAppender&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/root&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/log4net&amp;gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Using attributes to peform our mapping&lt;/h3&gt;
&lt;p&gt;We mark the entity with an [ActiveRecord] attribute to indicate that we want NHibernate to persist it. We can add the table name if it does not match the entity name [ActiveRecord(&amp;quot;MyTableName&amp;quot;)]. We can indicate that we want the entity to be loaded, by adding the Lazy attribute as in [ActiveRecord(Lazy=true)].&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;We can declare that our class inherits from ActiveRecordBase if we want Active Record pattern semantics, i.e. the entity knows how to retrieve and persist itself. We want true seperation of concerns, so we do not intend to mix CRUD mechanics with our entity. For this reason we do not derive our class from ActiveRecordBase.&lt;/p&gt;
&lt;p&gt;We mark up the identity of our entity using the [PrimaryKey] attribute. The default primary key type is native, so we do not need to mark this up, but if we have a different strategy then we have to explicitly indicate that. For example to use a GUID we would use: PrimaryKey(PrimaryKeyType.UuidHex, Params=&amp;quot;format=D,seperator=-&amp;quot;)]&lt;/p&gt;
&lt;p&gt;We can mark up a property using the [Property] attribute. In addition, we can use [Field] if we want to map a private member of the class. If we need to map to a column with a different name to the property then we can pass it as a parameter to the attribute [Property(&amp;quot;MyColumnName&amp;quot;)]. If we have a large object then we can set the column type - see the the Active Record documentation.&lt;/p&gt;
&lt;p&gt;We use a [HasMany] attribute to represent a one-to-many relationship, attributing the collection on the parent class i.e. [HasMany(typeof(Post), Table=&amp;quot;Posts&amp;quot;, ColumnKey=&amp;quot;blogid&amp;quot;)]. We use the RelationType enumerated value to specify the type of the relationship i.e. RelationshipType.Set. We also set the Inverse parameter as part of the HasMany attribute if this is a bi-directional relationship to avoid generating the insert and update statement, and creating an insert only. We can indicate if this relationship should be lazy-loaded using the Lazy parameter on the HasMany attribute. As with XML mapping we can also set the action NHibernate should take when we update or delete the parent using the Cascade option. In addition, we can set the index if we use one of the ordered types for our relationship or the sort order.&lt;br /&gt;We use a [BelongsTo] attribute on the reverse side of the relationship to indicate a Many-To-One relationship. We need to pass the name of the foreign key column as a parameter to the attribute. Again there are options that reflect those available from the xml mapping file.&lt;/p&gt;
&lt;p&gt;ActiveRecord also provides support for more advanced scenarios that are outside the scope of this article (it is meant to be an introduction and most of this is documented elsewhere):&lt;/p&gt;
&lt;p&gt;HasAndBelongsToMany&lt;br /&gt;OneToOne&lt;br /&gt;Any and HasManyToAny&lt;/p&gt;
&lt;p&gt;ActiveRecord also supports inheritance, supporting both the table Table-per-class hierarchy and Table-per-subclass strategies. &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Mapping the Table-per-class hierachy strategy is straightforward, just set the parameters on the superclass ActiveRecord attribute to indicate the discriminator column to use i.e. [ActiveRecord(&amp;quot;companies&amp;quot;, DiscriminatorColumn=&amp;quot;type&amp;quot;, DiscriminatorType=&amp;quot;String&amp;quot;, DiscriminatorValue=&amp;quot;company&amp;quot;)] and then indicate the value for each of the sub-classes i.e. [ActiveRecord(DiscriminatorValue=&amp;quot;firm&amp;quot;)].&lt;br /&gt;Mapping the Table-per-subclass strategy requires us to use the JoinedBase attribute on the superclass ActiveRecord attribute i.e. [ActiveRecord(&amp;quot;entity&amp;quot;), JoinedBase] and then use the [JoinedKey] attribute on the shared key value of the sub-classes.&lt;/p&gt;
&lt;p&gt;ActiveRecord also provides support for fine grained object models. We declare the [Nested] attribute on the property declaration in the containing entity, and then only mark up the component class with [Property] attributes i.e. not with [ActiveRecord] or [PrimaryKey] attributes.&lt;/p&gt;
&lt;h3&gt;Configuring Active Record&lt;/h3&gt;
&lt;p&gt;Before using ActiveRecord we must invoke the method Initialize on ActiveRecordStarter to configure NHibernate for us.There are a range of options to use when configuring, depending on where your configuration information is found. Because we added our configuration to the app.config file we can use the ActiveRecordSectionHandler to retrieve our configuration information.&lt;br /&gt;ActiveRecordStarter also provides the functionality to generate our schema from our code.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log4net.Config.XmlConfigurator.Configure();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IConfigurationSource config = ActiveRecordSectionHandler.Instance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordStarter.Initialize(typeof(Company).Assembly, config);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordStarter.CreateSchema();&lt;/p&gt;
&lt;h2&gt;Switching from attributes to mapping files&lt;/h2&gt;
&lt;p&gt;Active Record generates XML mapping files at run-time from your attributes, so this is using the same mechanism as the XML configuration, the complexity is just hidden from you. If you want to see the mapping then you can set the Debug value to true on the active record configuration (see above). This will tell NHibernate to keep the files around when your application ends, instead of deleting them. &lt;br /&gt;This allows you to pursue a strategy of beginning development by using attributes, and then switching to .hbm.xml files later to fully utilize all options and keep your domain model clean of mapping information.&lt;br /&gt;&lt;/p&gt;
&lt;h2&gt;Active Record support for Session Management&lt;/h2&gt;
&lt;p&gt;Active Record removes the need to initialize a session factory explicitly, instead we use the ActiveRecordStarter.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IConfigurationSource config = ActiveRecordSectionHandler.Instance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordStarter.Initialize(typeof(Company).Assembly, config);&lt;/p&gt;
&lt;p&gt;For a web based application best practice is that we initialize within the Application_Start method of the global HttpApplication object.&lt;/p&gt;
&lt;p&gt;Active Record operations try to get a session from the current thread, but create one if it is not extant, perform the operation and then release the session. So by default Active Record is session per operation. Active Record also gives us the ability to use a SessionScope to keep the session alive for the scope of our business transaction. Best practice is always to use a SessionScope.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (new SessionScope())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; const string COMPANY_NAME = &amp;quot;CompanyOfWolves&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InsertNewCompany(COMPANY_NAME);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int companyId = FindInsertedCompany(COMPANY_NAME);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;For a web application the usual pattern is to create a &lt;a href="http://www.castleproject.org/activerecord/documentation/trunk/usersguide/web.html."&gt;SessionScope with request affinity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Active Record and Repositories&lt;/h2&gt;
&lt;p&gt;The problem with the Active Record pattern, where the entity exposes CRUD methods is that it does not enforce a clean separation of concerns. (We have not shown this but to get Active Record working this way we need our entities to derive from ActiveRecordBase). Knowledge about persistence is coupled with knowledge about domain responsibilities. This increases complexity and thus makes maintenance harder. So good design strives for persistence ignorance within its domain model. The repository lives within the domain model and represents a collection of entities from an aggregate root.&lt;/p&gt;
&lt;p&gt; &lt;br /&gt;We call the repository from our domain level service to persist the object graph.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Support for Repository within Active Record&lt;/h3&gt;
&lt;p&gt;Active Record provides ActiveRecordMediator to allow you to use ActiveRecord to implement a repository.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; public class CompanyRepository&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected ActiveRecordMediator&amp;lt;Company&amp;gt; mediator;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Add(Company item)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordMediator&amp;lt;Company&amp;gt;.Save(item);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public virtual this[ int id]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; get { return ActiveRecordMediator&amp;lt;Company&amp;gt;.FindByPrimaryKey(id); }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Company[] Find(IActiveRecordQuery query)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (Company[])ActiveRecordMediator&amp;lt;Company&amp;gt;.ExecuteQuery(query);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Company[] Items()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ActiveRecordMediator&amp;lt;Company&amp;gt;.FindAll();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public virtual int Count()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ActiveRecordMediator&amp;lt;Company&amp;gt;.Count();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;A quick example of using this repository (domain services etc. elided to remove complexity) would be:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main(string[] args)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log4net.Config.XmlConfigurator.Configure();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IConfigurationSource config = ActiveRecordSectionHandler.Instance;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordStarter.Initialize(typeof(Company).Assembly, config);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ActiveRecordStarter.CreateSchema();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Comment out the session scope to see lazy load lack of scope issues&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (new SessionScope())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; const string COMPANY_NAME = &amp;quot;CompanyOfWolves&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InsertNewCompany(COMPANY_NAME);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int companyId = FindInsertedCompany(COMPANY_NAME);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static int FindInsertedCompany(string companyName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IActiveRecordQuery query = new SimpleQuery&amp;lt;Company&amp;gt;(&amp;quot;from Company org where Name = ?&amp;quot;, companyName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CompanyRepository companyRepository = new CompanyRepository();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Company[] companies = companyRepository.Find(query);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Company company = companies[0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.WriteLine(company.Name);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (Customer customer in company.Customers)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.WriteLine();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.Write(&amp;quot;First Name: &amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.WriteLine(customer.Name.FirstName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.Write(&amp;quot;Surname: &amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Out.WriteLine(customer.Name.Surname);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return company.Id;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void InsertNewCompany(string companyName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Company company = new Company();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; company.Name = companyName;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer customer = new Customer();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.Name.FirstName = &amp;quot;Neil&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.Name.Surname = &amp;quot;Jordan&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.DateOfBirth = new DateTime(1950, 2, 25);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; customer.Company = company;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; company.Customers.Add(customer);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CompanyRepository companyRepository = new CompanyRepository();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; companyRepository.Add(company); &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=248066" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="NHibernate" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/NHibernate/default.aspx" /><category term=".Net" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/.Net/default.aspx" /><category term="DDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/DDD/default.aspx" /><category term="Castle" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Castle/default.aspx" /></entry><entry><title>AltNetConf UK London August 2009</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/05/15/altnetconf-uk-london-august-2009.aspx" /><id>/blogs/ian_cooper/archive/2009/05/15/altnetconf-uk-london-august-2009.aspx</id><published>2009-05-15T07:02:00Z</published><updated>2009-05-15T07:02:00Z</updated><content type="html">&lt;p&gt;It feels as though sufficient water has passed under-the-bridge for us to have another &lt;a href="http://altnetuk.com/"&gt;altnetconf&lt;/a&gt; in London. We tend to organize them when the &amp;#39;mood&amp;#39; seems right in the community. That usually means that we think folks have something to discuss. This time we are planning on the weekend of 1 August (31 JUL to 2 AUG). Registration should open on 12 May. Don&amp;#39;t be alarmed if you see an old version of the site before then.&lt;/p&gt;
&lt;p&gt;Numbers are still limited. The wider economy means that we are unlikely to get the sponsorship for a bigger venue this year. We&amp;#39;ll keep trying though. &lt;/p&gt;
&lt;p&gt;That said&amp;nbsp;&lt;a href="http://thoughtpad.net/alan-dean.html"&gt;Alan Dean&lt;/a&gt;, &lt;a href="http://blog.benhall.me.uk/"&gt;Ben Hall&lt;/a&gt;, and myself have been plotting in secret, and roped in &lt;a href="http://serialseb.blogspot.com/"&gt;Sebastian Lambla&lt;/a&gt; and &lt;a href="http://serialseb.blogspot.com/"&gt;Michelle Flynne&lt;/a&gt; to help so that we can hold a bigger event in terms of the amount we do. So this time the plan is:&lt;/p&gt;
&lt;p&gt;31 JUL Evening: Alt.Net Beers: Yes we are integrating Seb&amp;#39;s alt.net event to warm you up with a chance to relax with like-minded individuals&lt;/p&gt;
&lt;p&gt;1 AUG Day: Open Space Coding: Alan Dean&amp;#39;s &lt;a href="http://openspacecode.com/home.en.xhtml"&gt;Open Space Coding Day&lt;/a&gt; event joins our weekend. the emphasis is on writing code over jawing.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2 AUG Day: AltNetConf: Open Space discussion about the topics that have grabbed you today. Be prepare to be&amp;nbsp;surprised.&lt;/p&gt;
&lt;p&gt;UPDATE: We had a request from attendees at &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-exchange"&gt;Progressive .NET&lt;/a&gt; to delay registration, as they are a key attendance group. I&amp;#39;ll update with the new time, likely to be Thursday lunchtime or evening.&lt;/p&gt;
&lt;p&gt;UPDATE: We have now opened registration: http://www.altnetuk.com/registration.en.html&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m looking forward to this one. It feels as though it has been long enough that we ought to have some things to talk about, not just re-hashing the old saws.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=222182" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="altnetconf" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/altnetconf/default.aspx" /><category term="AltNetUK" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/AltNetUK/default.aspx" /></entry><entry><title>Finding out about London .NET events</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/05/06/finding-out-about-london-net-events.aspx" /><id>/blogs/ian_cooper/archive/2009/05/06/finding-out-about-london-net-events.aspx</id><published>2009-05-06T08:47:00Z</published><updated>2009-05-06T08:47:00Z</updated><content type="html">&lt;p&gt;We have a rich .NET development scene in London and the organizers of a number of communities and events are going to try and make sure everyone knows how to get the best out of the community.&lt;/p&gt;
&lt;p&gt;The first question for most people would be how to find out what is happening. For now the key site for you to bookmark is the &lt;a href="http://ukdotnet.ning.com/"&gt;UK .NET event site&lt;/a&gt;. The London communities are going to make sure that we all&amp;nbsp;advertise&amp;nbsp;our events their so that you can go to one place and see what is coming up.&lt;/p&gt;
&lt;p&gt;As some quick examples of what is happening there I wanted to show you two events that you can find there which I am involved in. &amp;nbsp;One is the &lt;a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-exchange/wd-4"&gt;Progressive .NET tutorials&lt;/a&gt;, which you can find on the calendar &lt;a href="http://ukdotnet.ning.com/events/event/listByDate?date=2009-05-11"&gt;here&lt;/a&gt;. For those of you who can&amp;#39;t fly out to events like Alt.NET Seattle it is a great opportunity to catch people like Ayende, Hammet, Bellware (and me).&lt;/p&gt;
&lt;p&gt;On the 12th you can catch up with a lot of the same people down the pub as Seb has cunningly arranged the next &lt;a href="http://ukdotnet.ning.com/events/london-altnetbeers-8"&gt;Alt.NET beers&lt;/a&gt; to coincide with so many people being in town.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=215563" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="AltNetUK" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/AltNetUK/default.aspx" /></entry><entry><title>On Learning Boo</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/04/14/on-learning-boo.aspx" /><id>/blogs/ian_cooper/archive/2009/04/14/on-learning-boo.aspx</id><published>2009-04-14T03:18:00Z</published><updated>2009-04-14T03:18:00Z</updated><content type="html">&lt;h2&gt;Learning Boo&lt;/h2&gt;
&lt;p&gt;As part of my commitment to The Pragmatic Programmer&amp;#39;s exhortation to learn a new language every year, I decided to tackle &lt;a href="http://boo.codehaus.org/"&gt;Boo&lt;/a&gt;. My interest has been piqued by the work &lt;a href="http://manning.com/rahien/"&gt;Oren is doing in DSLs with Boo&lt;/a&gt;. Learning Boo seemed to be an important first step to getting to grips with that.&lt;/p&gt;
&lt;p&gt;The first step was to get an environment in which I could write and compile Boo programs. Now this is possible using a decent text editor like Vim, and command line tools like booc and booish, but it is also possible to use an IDE for this. I downloaded &lt;a&gt;SharpDevelop&lt;/a&gt; which has support for authoring, building and debugging Boo projects.&lt;/p&gt;
&lt;p&gt;To give myself a starting point I have decided to work through the &lt;a href="http://boo.codehaus.org/Boo+Primer"&gt;Boo Primer&lt;/a&gt; as a way of getting to know the language&lt;/p&gt;
&lt;p&gt;One aspect that jumps out is why Boo is called &amp;#39;wrist-friendly&amp;#39;. There is a lot of effort expended on giving you less to type. Although it is a statically typed language, Boo does away with the need to declare types before use. Instead Boo infers the type. C# programmers will find this similar to te use of var, without the need for the var keyword.&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;greeting = &amp;quot;Hello World&amp;quot; //This declares a string&lt;br /&gt;houseNumber = 42 //This declares an integer&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;I&amp;#39;m always typing code of the form:&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;var myString = string.Format(&amp;quot;Hello {0}&amp;quot;, name);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;in C#. Boo makes this a lot easier with string interning. I get to skip the string format statement, along with the seperation of placeholder and variable for&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;myString = &amp;quot;Hello ${name}&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;The use of whitespace (Boo has a Python inspired syntax) to indicate a block is one of the early aspects of the language that strikes me. It makes for great natural language syntax, because it requires no block markers, but coming from a curly brace language &amp;quot;{}&amp;quot; like C# it takes a little for the fingers to get used to.  I also seem to keep missing the colon off the end of the conditional&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;i = 5&lt;br /&gt;if i &amp;gt; 0:&lt;br /&gt;	print &amp;quot;i is greater than 0&amp;quot;&lt;br /&gt;	if (i &amp;lt; 10):&lt;br /&gt;		print &amp;quot;i is less than 10&amp;quot;&lt;br /&gt;		if (i==5):&lt;br /&gt;		      print &amp;quot;i equals 5&amp;quot;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;One issue that hit me when working through the Boo Primer was that SharpDevelop disliked me trying to declare a list as follows:&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;L = List(range(5))&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;which gave me the error&lt;/p&gt;
&lt;p&gt;
ERROR: Generic types without all generic parameters defined cannot be instantiated.
&lt;/p&gt;
&lt;p&gt;Some digging on the &lt;a href="http://groups.google.com/group/boolang"&gt;Boo Programming Language mailing list&lt;/a&gt; established that &lt;a href="http://groups.google.com/group/boolang/browse_thread/thread/ff5a4fa8166adc82/bbb42c9405e75e75?lnk=gst&amp;amp;q=generics#bbb42c9405e75e75"&gt;Boo now has generics&lt;/a&gt; and it looks like the Boo interpreter in SharpDevelop uses that type over the non-generic type. Switching to use the generic collection instead, removed the error messages&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;L = List[of int](range(5))&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;The built in list initializer syntax seems to work in SharpDevelop though:&lt;/p&gt;
&lt;pre name="code" class="c-sharp"&gt;barfoo = [&amp;#39;abcdefghijkl&amp;#39;]&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;I like the provision of initializer syntax for arrys, lists, and hashes within the language which provides for concise syntax&lt;/p&gt;
&lt;p&gt;Overall I have spent an enjoyable half-a-day familiarizing myself with Boo&amp;#39;s syntax so far. One immediate advantage to learning Boo over say learning Ruby is that you are dealing with .NET libraries. So when you see Console.ReadKey(true) in a line of Boo code your existing knowledge tells you what it is doing. You are able to leverage existing framework skills and apply them to a new language. This speeds up the learning process, because having learnt the new syntax you can to put it to use fare more quickly.&lt;/p&gt;
&lt;p&gt;Next time I&amp;#39;ll play with Boo&amp;#39;s methods and classes. Looking forward to it.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=193491" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="Object-Orientation" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Object-Orientation/default.aspx" /><category term="Boo" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Boo/default.aspx" /><category term=".Net" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/.Net/default.aspx" /></entry><entry><title>Seizing the BDD Nettle</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/31/seizing-the-bdd-nettle.aspx" /><id>/blogs/ian_cooper/archive/2009/03/31/seizing-the-bdd-nettle.aspx</id><published>2009-03-31T07:06:00Z</published><updated>2009-03-31T07:06:00Z</updated><content type="html">&lt;h2&gt;Learning BDD&lt;/h2&gt;
&lt;p&gt;I have been trying for some time now to understand what the Behavior Driven Development (&lt;a href="http://dannorth.net/introducing-bdd"&gt;BDD&lt;/a&gt;) exponents are talking about. I&amp;#39;m sure that &lt;a href="http://blog.scottbellware.com/"&gt;Scott&lt;/a&gt; and &lt;a href="http://www.lostechies.com/blogs/colinjack/"&gt;Colin Jack&lt;/a&gt; are sick of me asking questions on BDD.&lt;/p&gt;
&lt;p&gt;This is pretty much a journal of my understanding. It might help others on a similar journey, hence the reason for blogging it. I know a number of people have been asking me about BDD recently at community events, so this is an attempt to share where I am in understanding so far. Be aware that there may well be misunderstandings here. I&amp;#39;m not claiming any kind of authority for BDD. Hopefully more experienced practitioners will help me to correct any mistakes. Please use the comments. As my understanding improves I&amp;#39;ll keep you posted.&lt;/p&gt;
&lt;p&gt;For now be aware this is really a &amp;#39;notes to self&amp;#39; blog.&lt;/p&gt;
&lt;p&gt;The approach of this post is mostly historical. That is mostly because my current understanding of BDD is that it is an opinionated packaging of ideas from STDD, ATDD, and TDD. So I find it helpful to understand the ideas it is built on and where current skills form a part of the BDD mix.&lt;/p&gt;
&lt;p&gt; A key resource for me in understanding BDD is &lt;a href="http://www.code-magazine.com/article.aspx?quickid=0805061"&gt;Scott Bellware&amp;#39;s Code magazine article on the topic&lt;/a&gt;. The opinions here are my own though.&lt;/p&gt;
&lt;h2&gt;Behavior Driven Development in a historical context&lt;/h2&gt;
&lt;p&gt;On the current project we are practicing &lt;a href="http://industriallogic.com/papers/storytest.pdf"&gt;Industrial XP&amp;#39;s StoryTest-Driven Development&lt;/a&gt;. That article dates from 2004 but the practice and tools such as FIT have been around longer. For example &lt;a&gt;Customer Test Driven Development&lt;/a&gt;, a prior name, was a paradigm as far back as 2002. STDD supplements the unit tests of TDD with acceptance tests (usually delivered in FIT or Fitnesse).  The key principle in &lt;a href="http://industrialxp.org/community/bin/view/Main/StoryTestDrivenDevelopment"&gt;STDD&lt;/a&gt; is that you write new code only if an automated storytest has failed.&lt;/p&gt;
&lt;p&gt;It might seem obvious now, but the goal of agile engineering practices is to move the process of acceptance up the chain. When acceptance occurs at the end, it is expensive to fix mistakes. Developers have to re-acquire the depth of understanding they had when they first developed the feature. It leads to &amp;#39;never-ending&amp;#39; projects as acceptance drags on and on with the customer submitting more and more changes. Pushing acceptance up to the point that the code is written shortens the feedback loop making less expensive to fix issues. Pushing it ahead of writing the code prevents those defects occurring in the first place, the ideal.&lt;/p&gt;
&lt;p&gt;STDD helps us focus on creating the acceptance criteria first, so that we prevent defects instead of fixing them after they occur.&lt;/p&gt;
&lt;p&gt;In addition, STDD helps focus on the communication between Customer and Developer, clarifying the requirement. The article quoted above makes reference to Domain Driven Design in its comment that it is important to share the customer&amp;#39;s language in these tests, the DDD idea of &lt;a href="http://domaindrivendesign.org/discussion/messageboardarchive/UbiquitousLanguage.html"&gt;ubiquitous language&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One aspect of &lt;a href="http://xunitpatterns.com/storytest-driven%20development.html"&gt;STDD&lt;/a&gt; to note is that we have a separation between the &lt;a href="http://domaindrivendesign.org/discussion/messageboardarchive/UbiquitousLanguage.html"&gt;customer tests&lt;/a&gt; and the &lt;a href="http://xunitpatterns.com/unit%20test.html"&gt;unit tests&lt;/a&gt;. Customer Tests remain the same regardless of how we choose to implement. Unit tests cover the implementation details.&lt;/p&gt;
&lt;p&gt;Implicit in the name - story test-driven development is that we are working with user stories and the acceptance criteria on them. Interestingly this is often less explicit in descriptions of the technique, presumably because XP practitioners assumed everyone was working with stories and acceptance criteria.&lt;/p&gt;
&lt;p&gt;We use a mixture of &lt;a href="http://fitnesse.org/"&gt;Fitnesse&lt;/a&gt; and &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; for acceptance testing but equivalent tools exist. Acceptance testing tools remain woefully high friction and seem a clear area where improvements could be made.&lt;/p&gt;
&lt;p&gt;Of note is whether you use an &lt;a href="http://xunitpatterns.com/Philosophy%20Of%20Test%20Automation.html"&gt;Outside-In or Inside-Out&lt;/a&gt; approach. Most descriptions of STDD are Inside-Out. Although the developer has the acceptance tests as a target they then build unit-tested code from the bottom up to implement the requirements. Often the developers use a white-board or CRC card session to design the implementation. Then, at the end, they hook up the acceptance test to see everything pass (or fix anything that is not as expected). This is generally how we work on my current project. BDD descriptions often focus on an Outside-In approach. Outside-In relies on greater use of Test Doubles to replace depended upon components (DOC) that are not yet implemented. Adherents see a benefit in the design that emerges from being forced to make the DOC abstract.&lt;/p&gt;
&lt;h3&gt;Acceptance Test Driven Development&lt;/h3&gt;
&lt;p&gt;To me &lt;a href="http://testobsessed.com/wordpress/wp-content/uploads/2008/12/atddexample.pdf"&gt;Acceptance Test Driven Development (ATDD)&lt;/a&gt; is just another name for Story Test-Driven development. Both ATDD and STDD emphasize the idea of the executable specification. We make it possible to demonstrate that we &lt;a href="http://www.agilemodeling.com/essays/executableSpecifications.htm"&gt;meet the specification and can keep meeting it&lt;/a&gt;. I guess someone may put me straight if the two differ in philosophy. I heartily recommend &lt;a href="http://gojko.net/"&gt;Gojko Adzic&lt;/a&gt; to learn more about ATDD, particularly the interaction between customer and developer that occurs as part of that process.&lt;/p&gt;
&lt;h3&gt;Unit tests are not enough&lt;/h3&gt;
&lt;p&gt;We moved from a focus on unit tests and integration tests today, to add test-first acceptance testing to our strategy. This can be hard, because you are used to loading to testing at the back of the iteration (or even in the next iteration). Moving acceptance testing to the beginning of the story requires you to have a conversation about how you will accept the story, with customer and test engineers if you have them, before you start the story.&lt;/p&gt;
&lt;p&gt; In addition, you need to keep stories small so that you have acceptance throughout the iteration. It is no good defining scenarios up front if you end up confirming them at the end of the iteration. There is the pragmatic issue of overloading your test team, but also the problem of late feedback. That can be a hard discipline and we often end up with too much acceptance at the back end of the iteration from having insufficiently granular stories. We&amp;#39;re still working on getting better at getting our acceptance across the iteration, and it remains a real challenge. It&amp;#39;s one with an enormous payoff though. It is also worth noting that our failures are not failure of the goal, but a failure to excel well enough at breaking up epic stories etc.&lt;/p&gt;
&lt;p&gt; The value add in the approach is preventing defects rather than detecting them. It is also how stories were always supposed to be used - as a promise for a conversation. This seems to be much the same insight that pushed lean manufacturers to move QA into the line to prevent defects occurring instead of simply having them point them out once they had occurred. Testing &amp;#39;at the end of the line&amp;#39; is an anti-pattern that can only detect defects not prevent them.&lt;/p&gt;
&lt;h2&gt;Behavior Driven Development&lt;/h2&gt;
&lt;p&gt;Dan North coined the term &lt;a href="http://dannorth.net/introducing-bdd"&gt;Behavior Driven Development (BDD)&lt;/a&gt; to replace TDD. Dan felt that the emphasis on testing in the names used to that point was a distraction from the idea of confirming the behavior of the system or executable specifications. Dan&amp;#39;s history of BDD suggests that it began as an attempt to use &lt;a href="http://blog.daveastels.com/files/BDD_Intro.pdf"&gt;Behavior Specification&lt;/a&gt; over unit testing (see below). At first this was simply a question of naming test fixtures to indicate that they were assessing behavior and naming tests to indicate the behavior under test. This lead to the development of a tool, JBehave, as a clearer alternative to the unit testing tools that were prevalent. Dan then realized that the emphasis on behavior meant the technique could also encompass the process of acceptance criteria for stories as well. For me one transition in BDD thinking that seems distinct from STDD and TDD is that it removes the idea of these being separate activities, pitching more an idea of scenarios and specifications instead of different granularity of tests.&lt;/p&gt;
&lt;h3&gt;Acceptance Testing again&lt;/h3&gt;
&lt;p&gt;STDD, ATDD, and BDD all emphasize the same thing: unit testing is not enough, even if done test first. The problem is that while unit testing tells us that we have built the software right, it does not tell us if we have built the right software. In an analogy you may be great at cutting down trees, but if you chop down the wrong forest, you&amp;#39;ve bought yourself nothing but trouble.&lt;/p&gt;
&lt;p&gt;The classic model for development under BDD, seems similar to that for STDD, but we move from acceptance tests and unit tests to scenarios and specifications. This terminology change helps us think about the work as automating executable requirements instead of testing. That re-focuses us on these as design activities. They also improve the maintainability of the artefacts produced, because the strategy is inherently contextual. Note that when I say developer here, you might have a specialized software developer in test (SDT). When I say customer it might be a customer proxy such as a Business Analyst (BA) &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Developer works with customer to find user stories of form: As a&amp;nbsp;  &amp;lt;role&amp;gt;I want to &amp;lt;business activity&amp;gt;  so that I &amp;lt;business value&amp;gt;&lt;/li&gt;
&lt;li&gt;Developer works with customer to identity the acceptance criteria for that story&lt;/li&gt;
&lt;li&gt;Developer writes a scenario that exercises part of the acceptance criteria of the scenario (in a &lt;b&gt;Given-When-Then&lt;/b&gt; style). Tools like Fitnesse and Cucumber often present these customer facing tests. However, tools are not the issue here. Some folks may use an xUnit framework even at this point.&lt;/li&gt;
&lt;li&gt;Developer implements fixtures to create a failing scenario&lt;/li&gt;
&lt;li&gt;The developer may do some design with colleagues on a whiteboard, CRC cards etc.&lt;/li&gt;
&lt;li&gt;Developer writes a failing specification for a part of the implementation that will satisfy the story. This was traditionally the unit test, but BDD shifts the perspective to a specification to ensure we still think about execuable specifications over tests (see below for more)&lt;/li&gt;
&lt;li&gt;Developer writes the code to get the specification to pass&lt;/li&gt;
&lt;li&gt;Developer keeps writing new specifications, until the scenario passes&lt;/li&gt;
&lt;li&gt;Developer moves on to the next scenario for the acceptance criteria for the story&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;#39;s important not to emphasize tools here. It is not a question of using Fitnesse, Cucumber, or Selenium for your scenario and a particular xUnit for your specifications but a question of thinking about how we accept software. You might, for example, use SpecUnit throughout here; or you might use Fitnesse and NUnit with a home rolled specification framework.&lt;/p&gt;
&lt;h2&gt;Behavior Specification&lt;/h2&gt;
&lt;p&gt;For some time we have been using the &lt;a href="http://xunitpatterns.com/Four%20Phase%20Test.html"&gt;Four Phase Test approach&lt;/a&gt;. We were often explicit about the steps within a test method having an in-line setup, exercise, verify and teardown section within the test. Some people were writing this as Arrange, Act, Assert (AAA) when working in-line and we switched to using those monikers as it seemed to be more prevalent. The advantage of using a strict phase model is that it became easier to read tests - you knew how any test would be structured, where to find the pre-conditions and post-conditions and what was being exercised.The model also forced people to think about how they were highlighting the conditions important to the test, leading us to use ideas like &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/10/17/testdatabuilders.aspx"&gt;Test Data Builders&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;BDD uses the phrase &lt;b&gt;Given-When-Then&lt;/b&gt; to refer to the phases of the test model. The naming was a deliberate choice. The idea was to focus on a specification of what the Sysem under test (SUT) should do instead of focusing on verifying parts. Shifting the names took us out of the world of tests and into the world of executable specifications. We stop thinking about setup and start thinking around the context in which the business activity is occuring. We stop thinking about calling our API and start thinking about the operation being performed. We stop thinking about testing and instead focus on outcomes.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rspec.info/documentation/"&gt;RSpec&lt;/a&gt; changed the convention here to focus on Examples or Specifications. Dave Astels speaks about &lt;a href="http://blog.daveastels.com/files/BDD_Intro.pdf"&gt;Behavior Specification&lt;/a&gt; as an alternative mindset to testing. That approach was picked up by many others including Scott Bellware in &lt;a href="http://code.google.com/p/specunit-net/"&gt;SpecUnit&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;By focusing on a specification, Behavior Specification psychologically shifts us from thinking about testing into writing an executable specification for our code. With a user story approach the detail of the requirement is in the acceptance criteria so this shift to see testing as specification is just the natural outcome of thinking of requirement specifications as the driver for testing, providing the notion of expected behavior.&lt;/p&gt;
&lt;p&gt;Objects can be described as having a push-button API. Our calculator class has Multiply, Add etc. The danger with TDD is that it can lead to testing button rather than operations. You write a test to enter &amp;#39;2&amp;#39; and see it displayed on the screen. You write a test to press the Add button. But what we really want to test is that when In I add 2+2 I get 4. TDD can produce tests that don&amp;#39;t cover the whole specification, but fragmentary parts of it. This makes them hard to &amp;#39;read&amp;#39; and do not form effective executable documentation for our system. We want to be able to read the tests and know what the code is supposed to be achieving, not that the bits function. People who have delivered large systems using a classic approach to TDD have found that the tests are not expressive enough to act as clear documentation of the system. Specifications are much better in this regard. The skills are the same but the focus of the approach shifts from testing to specifying. This &amp;#39;eureka&amp;#39; moment of understanding the shift between unit tests and specifications seems to be one of those difficult to explain, but easy to appreciate areas of life.&lt;/p&gt;
&lt;p&gt; There are additional benefits. The shift to specifications for example seems to lower the issue of property heavy APIs on a class. With unit tests, the calling code can end up containing the behavior - the workflow of calls required to complete an operation. A specification surrenders control of that back to the SUT. So a specification approach should drive the design of a better API because we focus on what we want to achieve not how we achieve it.&lt;/p&gt;
&lt;h3&gt;It&amp;#39;s turtles all the way down&lt;/h3&gt;
&lt;p&gt;It&amp;#39;s important to understand that this approach -writing a specification of how the system should behave when something happens within a context (Given-When-Then) applies throughout the stack. So the traditional dichotomy of acceptance tests and unit tests fades to be replaced by tests at different levels of granularity, potentially using different tools as appropriate.&lt;/p&gt;
&lt;h2&gt;That is enough for now&lt;/h2&gt;
&lt;p&gt;There is more to say, but this has been a long enough post for people to read, so I&amp;#39;ll defer anything else to some subsequent posts on the topic. Those looking for examples of how might want to read Scott&amp;#39;s article for now. I&amp;#39;ll try to post some examples later. However one key for me was to share my current understanding is that simply using behavior specification xUnit frameworks is not &amp;#39;doing BDD&amp;#39;. BDD is a whole lifecycle approach to verifying you have met user requirements. In that context I suspect that focusing on individual frameworks may distract from, rather than enhance, the message.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=189931" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="TDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/TDD/default.aspx" /><category term="Agile" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Agile/default.aspx" /><category term="BDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/BDD/default.aspx" /><category term="Behavior Specification" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Behavior+Specification/default.aspx" /><category term="ATDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/ATDD/default.aspx" /><category term="STDD" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/STDD/default.aspx" /></entry><entry><title>Introduction to NHibernate, pt. 6</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/26/introduction-to-nhibernate-pt-6.aspx" /><id>/blogs/ian_cooper/archive/2009/03/26/introduction-to-nhibernate-pt-6.aspx</id><published>2009-03-26T08:55:00Z</published><updated>2009-03-26T08:55:00Z</updated><content type="html">&lt;p&gt;Last time we looked at &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2009/03/22/introduction-to-nhibernate-pt-5.aspx"&gt;mapping value types and user defined types&lt;/a&gt;. This time I want to look at sessions. Understanding sessions is one of the challenges for any developers approaching ORMs for the first time, because they can represent a new way of thinking about interaction with the Db.&lt;/p&gt;
&lt;p&gt;









 
  Normal
  0
  
  
  
  
  false
  false
  false
  
  EN-GB
  X-NONE
  X-NONE
  
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4
  
   
   
   
   
   
   
   
   
   
   
   
  

 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 









&lt;h4&gt;&lt;span lang="EN-US"&gt;Working with Sessions&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;We need to use a session when we work with NHibernate. We
will talk later about managing entity lifetime, but the short version is that
you should avoid accessing an entity outside of the context of the session that
loaded it.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;We obtain sessions from the session factory. The session
factory is an expensive resource, you want to create it once at application
startup. The factory gives you instances of sessions, which are cheap and you
should create and destroy as your business transactions require (see transient
and persistent entities below).&lt;/p&gt;
&lt;h4&gt;&lt;span lang="EN-US"&gt;Entity Lifetime Management&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;It is important to understand the lifetime issues around
entities when working with an ORM. Clarity here helps prevent many of the
issues people have when working within an ORM.&lt;/p&gt;
&lt;h4&gt;&lt;span lang="EN-US"&gt;Identity Map&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;The &lt;a target="_blank" href="http://martinfowler.com/eaaCatalog/identityMap.html"&gt;identity map&lt;/a&gt; is a cache of all of the entities loaded
from the Db during the session. We need an identity map because we want to
ensure that if we have made changes to an entity within the session i.e.
updated some of its data, new queries against the Db that returns a set of
entities keep our changes. As a corollary to this when working with an identity
map, we always get the same instance of an entity within a session, and they
can be compared by reference. Note that the identity map also functions as a
first-level cache, because it has our entities loaded. However, we will only go
to the first level cache in preference to querying the Db when using Get or Load to retrieve our entities. This is because only when we issue a query, through HQL for example, we do not know what entities will be returned, so it is only after the query is executed that we can look into the cache to se if we have that entity already, and return the copy there.&lt;/p&gt;
&lt;h4&gt;&lt;span lang="EN-US"&gt;Unit of Work&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;NHibernate stores the old and new values of entities within
the identity map. The unit of work also stores new entities that have been
added with Save and are waiting to be flushed to the Db. NHibernate flushes
these changes to the Db both on demand and automatically. Automatic flushing happens when you perform
certain operations. For example if you are about to query NHIbernate will flush to make sure that your query results will be consistent with the modified data. You can
also explicitly flush a session either by calling Flush() on the session or by
using a transaction. The principle here is that you want to optimize when updates occur, instead of them happening piecemeal.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;So when does NHibernate Flush?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;nbsp;
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;When you explicitly call
      Flush.&lt;/li&gt;
&lt;li class="MsoNormal"&gt;When you commit a
      transaction.&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Before some Find or
      Enumerable method calls&lt;/li&gt;
&lt;li class="MsoNormal"&gt;When an object using
      native ID generation is saved, the entity will be inserted&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Whe&amp;nbsp; you close a Session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;We can set the session FlushMode to restrict those to Commit
or Flush if we need to be explicit about when a flush occurs. One common reason for setting the FlushMode to Commit is the issue of what happens when an exception is thrown. It is common to have a using statement control your Session, so that it is closed when and flushed automatically. The problem becomes that if you throw an exception, the Dispose still runs as you exit the implicit try..finally block created by the using statement, flushing and pending writes. Given that an exception was thrown this might result in an incosistent or undesired state. Setting the session FlushMode to Commit and always using a transaction helps prevent this: the changes don&amp;#39;t get persisted until you commit. The side-affect to watch for is the issue that until your changes are flushed, queries will not report on any pending changes.&lt;/p&gt;
&lt;h4&gt;&lt;span lang="EN-US"&gt;Transient and Persistent Entities&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;We need to distinguish between transient and persistent entities.
A persistent entity is one that the session knows about. The session knows
about an entity that has been loaded through it, using get, load, or one of the
query APIs. A transient entity is one that the session does not know about i.e.
has been created with new in the application. A transient entity is made
persistent by calling Save() on the session passing the new entity as a
parameter, or by adding it to the graph of an existing persistent entity. In
the latter case we will persist the new entity if we have set the cascade
options in the mapping to pickup children. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;We need to remember that an entity has its changes tracked
by the unit of work held by the session which loads it. In addition, if we have
lazy loaded associations on an entity, those will be loaded via a proxy that
calls out to the original session. So we should not access an entity outside
the scope of a session. The model in NHibernate is:&lt;/p&gt;
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;Open Session
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;Begin a transaction on
      the session
&lt;ul&gt;
&lt;li class="MsoNormal"&gt;Retrieve any required
       entities&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Save any transient
       entities or add to graph&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Make any updates to the
       graph required&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Commit the transaction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="MsoNormal"&gt;Close the session&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;If we have a detached entity, one that we loaded via a
transaction that is no longer extant (remember we don&amp;#39;t want any lazy loaded
associations on it), because we have loaded it within a different context, then
we can re-attach it to a session using Update(). Update tells the session that
the entity it thinks is transient, because it is not in its identity map, is
actually persistent. In that case NHibernate adds it to its list of persistent
entities.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;NHibernate also supports SaveOrUpdate() which is useful if
are not sure if the entity is detached or transient. In this case it uses the
unsaved-value attribute of the primary key mapping to determine whether or not
we have a transient entity or a detached one.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;A common early mistake is to assume that the Update method needs to be called to amend a persitent (i.e. existing object). In fact you do not need to explicilty ask for changes to persistent objects to be saved. NHibernate looks in the Unit of Work to figure out which objects are &amp;#39;dirty&amp;#39; and flushes any changes to them.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Although there is support for detached entities, prefer to
work within the context of a session where possible as it prevents issues with
needing to fully materialize the object graph.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;If we have a transient object which is in the reachable from the graph of a persistent object, then we do not need to explicitly save it. NHibernate will pick up the transient object and save it for us when it saves the persistent object provided that we have set the association between the persistent object and the transient one to cascade saves or updates. This works well with an aggregate strategy where your repository laods and saves aggregates (via the aggregate root) as you only ever need to save the root object to persist the graph.&lt;/p&gt;
&lt;h3&gt;&lt;span lang="EN-US"&gt;CRUD&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;span lang="EN-US"&gt;Insert, and Retrieve&lt;/span&gt;&lt;/h4&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;Inserting a new object is straightforward. Create it, and
make it persistent with Save. We use flush here to persist it instead of using
a transaction:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Company
company = new Company();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;company.Name = companyName;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Customer customer = new Customer();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;customer.FirstName = &amp;quot;Neil&amp;quot;;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;customer.Surname = &amp;quot;Jordan&amp;quot;;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;customer.DateOfBirth = new DateTime(1950, 2, 25);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;customer.Company = company;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&amp;nbsp;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;company.Customers.Add(customer);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;using
(ISession session = sessionFactory.OpenSession())&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;session.Save(company);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;session.Flush();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Once we have saved our entity we can retrieve it. If we do
not know the id of the entity then we need to use one of NHibernate&amp;#39;s query
languages, HQL or ICriteria to find it. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;HQL is a SQL like query language that works against the
domain model instead of the relational model. Queries have the form &amp;quot;from
Customer as cust where cust.FirstName = :name&amp;quot;. &amp;quot;:name&amp;quot; is a
named parameter, you can also use &amp;quot;?&amp;quot;, but then you have to refer to
parameters by position when setting them, so by name is usually more readable. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;The Find method on session has been deprecated, so use the
CreateQuery on the Session to create an IQuery, set your parameters and
retrieve matching results.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;using
(ISession session = sessionFactory.OpenSession())&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IQuery
query = session.CreateQuery(&amp;quot;from Company org where Name = :name&amp;quot;);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;query.SetString(&amp;quot;name&amp;quot;, companyName);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;IList&amp;lt;Company&amp;gt; companies = query.List&amp;lt;Company&amp;gt;();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;if
(companies.Count &amp;gt; 0)&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine(companies[0].Name);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;foreach (Customer customer in companies[0].Customers)&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.Write(&amp;quot;First Name: &amp;quot;);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine(customer.FirstName);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.Write(&amp;quot;Surname: &amp;quot;);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine(customer.Surname);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return
companies[0].Id;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;In addition NHibernate also provides the ICriteria API&lt;/p&gt;
&lt;p class="MsoNormal"&gt;If we know the Id we can use Get or Load. The primary
difference is that Get returns null if the entity cannot be found, whereas Load
throws an exception. However, also note that if the object exists as a proxy in
the session&amp;#39;s identity map then Load will return that proxy, Get will always
retrieve the entity.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;using
(ISession session = sessionFactory.OpenSession())&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Company company = session.Load&amp;lt;Company&amp;gt;(companyId);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.Write(&amp;quot;Company Name: &amp;quot;);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Console.Out.WriteLine(company.Name);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Delete and Update&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Updating an entity is straightforward, any entity that is in
the identity map that we then update will have those changes persisted when
NHibernate flushes to the Db.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;string
companyName = string.Empty;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;using (ISession session =
sessionFactory.OpenSession())&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;Company company = session.Load&amp;lt;Company&amp;gt;(companyId);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;companyName = company.Name;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;ITransaction trans = session.BeginTransaction();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;Customer newCustomer = new
Customer();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;newCustomer.FirstName = &amp;quot;Angela&amp;quot;;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;newCustomer.Surname = &amp;quot;Carter&amp;quot;;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;newCustomer.DateOfBirth = new DateTime(1940, 5, 7);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;newCustomer.Company = company;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;trans.Commit();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Deleting an existing company is straightforward too, we
simply call the Delete method of the Session to remove it.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;using
(ISession session = sessionFactory.OpenSession())&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;session.Delete(&amp;quot;from Company
org where Id = :id&amp;quot;, companyId, NHibernate.NHibernateUtil.Int32);&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;session.Flush();&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/b&gt;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;How long to keep the session around?&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-size:10pt;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;Sessions are lightweight resources and designed to
be &amp;#39;kept around&amp;#39; as long as you need them.&amp;nbsp; For example, the session
only opens and closes a Db Connection when it flushes changes in the unit of
work to the Db. A session is also easy to create, so you should create them as
you need them.&amp;nbsp; By contrast the SessionFactory from which we get our sessions is a heavyweight object. It does all the work to generate code from the mappings, and generally you want to create this once, at application startup. The usual pattern is to create a session for each
business transaction, for which you may be collating changes in a unit of work.
On the web, it is common to use Http request affinity for a session, opening&amp;nbsp; a session as the request comes in and closing it once you have returned the response.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=189725" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="NHibernate" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/NHibernate/default.aspx" /><category term="ORM" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/ORM/default.aspx" /></entry><entry><title>Introduction to NHibernate, pt.5</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/22/introduction-to-nhibernate-pt-5.aspx" /><id>/blogs/ian_cooper/archive/2009/03/22/introduction-to-nhibernate-pt-5.aspx</id><published>2009-03-22T11:29:00Z</published><updated>2009-03-22T11:29:00Z</updated><content type="html">&lt;h2&gt;Last time around&lt;/h2&gt;
Last time we looked at how we &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2009/01/21/introduction-to-nhibernate-pt-4.aspx"&gt;map inheritance in NHibernate&lt;/a&gt;. This time I want to look at value types.
&lt;h2&gt;Mapping Value types&lt;/h2&gt;
&lt;p&gt;NHibernate supports a &amp;#39;fine-grained object model&amp;#39;. That is to say it allows us to map value types as well as entities.&lt;/p&gt;

&lt;p&gt;All ORM tools let you map between a class and a table. This provides us with the support we need to map the entities in our domain model. Entities are distinguished by having a unique identifier throughout their lifetime; that is to say we compare entities by identity, not by value. As an example, the tax system needs to continue to find you, even if you change your name, so you will have some form of tax number that acts as your unique identifier. The mapping used is straightforward. Because each row in a Db table needs a unique identifier (the primary key) a row can be seen as equivalent to an instance of an entity.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s obvious that all ORMs need to support mapping the primitive types (int, string, bool, etc) that you comprise your entity from. Again the principle is simple, each field or property on your entity maps to a column in the table.&lt;/p&gt;

&lt;p&gt;Less well understood is that primitive types are just one class of types that we call value types - that is types that we compare by value. When we build our object model we may find a host classes in our domain that should be compared by value instead of by identity.&lt;/p&gt;

&lt;p&gt;The canonical example here is money. When we record a monetary value we may want to know two things - the amount, and the currency. When we compare for equality between two monetary amounts we tend to compare that they have the same currency and amount. In an OO design we want to keep the two concepts, value and amount, together so we create a class called Money.&lt;/p&gt;

&lt;p&gt;Within the Db we would tend to represent money and amount as two columns, within the entity, such as a purchase order line item, we were recording the cost of. If our ORM only supports mapping entities though we will find that the only way to represent money and have it mapped to two columns on the LineItem table is to explicitly represent the monetary amount as a amount field and a currency field within the LineItem. We cannot use Money, because the only way that our ORM knows to map a class is as an entity, so we would have the somewhat perverse scenario of having a foriegn key lookup to the Money table to find the cost.&lt;/p&gt;

&lt;p&gt;What we want is to be able to map a value type to a number of columns on a table. (You don&amp;#39;t have to map a value type this way, but it makes the most sense in most cases). NHibernate allows you to map user-defined value types or collections of value types. We won&amp;#39;t show the latter here, as it’s not really an introductory topic, but we will talk about the former.&lt;/p&gt;

&lt;p&gt;NHibernate uses the term component for a user-defined type that is mapped to columns in the row of another entity. We use the &amp;lt;component/&amp;gt; element to map the value type on the &amp;lt;class/&amp;gt;.&lt;/p&gt;

&lt;p&gt;Consider, for example, that we might want to map the Customer&amp;#39;s FirstName and SurName as a Name type. (We are using the same entities that we provided earlier in the series). We could alter the class definition as follows:&lt;/p&gt;

&lt;p&gt;
&lt;br /&gt;public class Name
&lt;br /&gt;{
&lt;br /&gt;    public string FirstName {get;set;}
&lt;br /&gt;    public string Surname {get;set;}
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;public class Customer
&lt;br /&gt;{
&lt;br /&gt;   public Company Company { get; set; }
&lt;br /&gt;   public DateTime DateOfBirth { get; set; }
&lt;br /&gt;   public int Id { get; set; }
&lt;br /&gt;   public Name Name { get; set; }
&lt;br /&gt;   public int Version { get; set; }
&lt;br /&gt;}
&lt;/p&gt;

&lt;p&gt;Then we can map it as follows:&lt;/p&gt;
&lt;p&gt;&amp;lt;class name=&amp;quot;Customer&amp;quot; table=&amp;quot;Customer&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id name=&amp;quot;Id&amp;quot; type=&amp;quot;Int32&amp;quot; unsaved-value=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;generator class=&amp;quot;identity&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/generator&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/id&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version name=&amp;quot;Version&amp;quot;&amp;gt;&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&amp;quot;DateOfBirth&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;component name=&amp;quot;Name&amp;quot;&amp;gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&amp;quot;FirstName&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&amp;quot;Surname&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/component&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;many-to-one name=&amp;quot;Company&amp;quot; column=&amp;quot;CompanyId&amp;quot; cascade=&amp;quot;all-delete-orphan&amp;quot;&amp;gt;&amp;lt;/many-to-one&amp;gt;&lt;br /&gt;&amp;lt;/class&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;And that is all there is to it.&lt;/p&gt;
&lt;h3&gt;User Defined Mappings&lt;/h3&gt;
&lt;p&gt;NHibernate also has support for providing custom mapping for any type, allowing you to take control of how objects are persisted and materialized. In some cases you may want to use this to take more control of your mappings. To add a custom mapping you need to create a class that derives from IUserType (for single field types) or ICompositeUserType (for types with multiple fields). Custom mapping is too large in scope for this article to cover completely, butwe&amp;#39;ll try to cover the basics.&lt;/p&gt;

&lt;p&gt;Let us assume that we want to map our Name above using a composite user type instead of a component&lt;/p&gt;

&lt;p&gt;We create a new type NameUserType and implement the ICompositeUserType interface. Essentially NHibernate calls our composite user type to materialize or persist instances of our value type. Those of you who have written ADO.Net persistence code for a data reader by hand will probably recognize how this works.&lt;/p&gt;

&lt;p&gt;
&lt;br /&gt;    public class NameUserType : ICompositeUserType
&lt;br /&gt;    {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        private static readonly SqlType[] sqlTypes = new SqlType[] {NHibernateUtil.String.SqlType, NHibernateUtil.String.SqlType};
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public object GetPropertyValue(object component, int property)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            var name = (Name) component;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (property == 0)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                return name.Firstname;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            else
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;               return name.Lastname;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;       public void SetPropertyValue(object component, int property, object value)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;           //our value type is immutable, we create a new instance instead of modifying
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            throw new InvalidOperationException(&amp;quot;Name is immutable&amp;quot;);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public bool Equals(object x, object y)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            if (object.ReferenceEquals(x,y)) return true;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            if (x == null || y == null) return false;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //our type should know how to compare itself
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return x.Equals(y);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public int GetHashCode(object x)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //our type should provide a hashcode
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return x.GetHashCode();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            var firstName = NHibernateUtil.String.NullSafeGet(dr, names[0]);
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            var lastName = NHibernateUtil.String.NullSafeGet(dr, names[1]);
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return new Name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                       {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                           Firstname = firstName,
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Lastname = lastName
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                       };
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public void NullSafeSet(IDbCommand cmd, object value, int index, ISessionImplementor session)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            if (value == null)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                ((IDataParameter)cmd.Parameters[index+1]).Value = DBNull.Value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            }
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            else
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;                var name = (Name)value;
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((IDataParameter)cmd.Parameters[index]).Value = (object)name.Firstname ?? DBNull.Value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((IDataParameter)cmd.Parameters[index + 1]).Value = (object)name.Lastname ?? DBNull.Value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object DeepCopy(object value)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //As an immutable value type, just return the argument. 
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //If we were an entity we would need to deep copy
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public object Disassemble(object value, ISessionImplementor session)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //write to 2nd level cache
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return value;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object Assemble(object cached, ISessionImplementor session, object owner)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //read from 2nd level cache
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return cached;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object Replace(object original, object target, ISessionImplementor session, object owner)
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //we are immutable
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            return original;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;&amp;nbsp;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public string[] PropertyNames
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //What are the names of our user types properties
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            get { return new string[] {&amp;quot;Firstname, Lastname&amp;quot;};}
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public IType[] PropertyTypes
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            //What are the types of our user types properties
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            get { return new IType[] {NHibernateUtil.String, NHibernateUtil.String}; }
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public Type ReturnedClass
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            get { return typeof (Name); }
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public SqlType[] SqlTypes
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            get { return sqlTypes; }
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;        public bool IsMutable
&lt;br /&gt;&amp;nbsp;&amp;nbsp;        {
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //we are immutable
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            get { return false; }
&lt;br /&gt;&amp;nbsp;&amp;nbsp;        }
&lt;br /&gt;    }
&lt;/p&gt;

&lt;p&gt;If we can map Name by both a component and a user type why would we ever want to use a user type? One answer is simply to save duplication in our mapping files. But a more complex answer is that you may want to map a family of types through an interface, that all share the same state, but have differing behaviour. You need to distinguish which concrete type NHibernate should use to materialize this instance from the store. You can write code within your user type to manage that.&lt;/p&gt;

&lt;p&gt;The key takeaway is to recognize that NHibernate supports a rich domain model better ORMs, for example Linq To Sql, that do not have support for mapping value types.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=189588" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="Object-Orientation" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Object-Orientation/default.aspx" /><category term="NHibernate" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/NHibernate/default.aspx" /><category term="ORM" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/ORM/default.aspx" /></entry><entry><title>Why people do not see how smart your idea is at first</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/06/why-people-do-not-see-how-smart-your-idea-is-at-first.aspx" /><id>/blogs/ian_cooper/archive/2009/03/06/why-people-do-not-see-how-smart-your-idea-is-at-first.aspx</id><published>2009-03-06T08:57:00Z</published><updated>2009-03-06T08:57:00Z</updated><content type="html">&lt;p&gt;One of the &amp;#39;features&amp;#39; of my current project is that the development team are seperated by the Atlantic from the analysts. So we have to learn overcome the resulting communication issues. One observation that we have from that experience is why other people do not always &amp;#39;grok&amp;#39; your new great idea.&lt;/p&gt;
&lt;p&gt;A scenario we experience commonly is that the developer team and the analysts begin discussing  a problem in the shared working hours of the day. During our shared time we may move from steps A-H of solving a problem. But in the interim one team or the other may take a way the problem and keep working on it and take the problem from I-Z reaching a conclusion. When the team meets up again, the team that continued working on the problem presents their solution Z (usually with a drum roll) in full expectation that the other team will laud their clever solution. &lt;/p&gt;
&lt;p&gt;But what usually happens is the other team start asking questions. Why would you do it that way? What was wrong with this solution? Often the presenting team are dissappointed and furstrated. Why don&amp;#39;t you get my beautiful idea? Why don&amp;#39;t you just accept what I am saying to you?&lt;/p&gt;
&lt;p&gt;The problem is of course that one team is at H and the other is at Z. You can&amp;#39;t just skip all the steps in between. The team presenting has to walk the team that need to catch up from I to Z so that the lagging team can understand the reasoning that led to their conclusion. As my math teacher used to say: show all your working.&lt;/p&gt;
&lt;p&gt;As a community Alt.Net often experiences this problem. We leave the path everyone else is on at H and run all the way to Z. When we come back and tell everyone else that Z is now the way to go, there is questioning and disbelief, because we left the broader community at H. If we want to communicate effectively we have to summarize I to Z.&lt;/p&gt;
&lt;p&gt;The Peristence Ignorance conversation at Alt.Net Seattle was a great example of this. You cannot just present Persistence Ignorance and expect folks to adopt it. You have to explain what steps (testability, seperation of concerns, single responsibility etc.) lead you to prefer persistence ignorance and how tools that do support it achieve that.&lt;/p&gt;
&lt;p&gt;Of course we could put our head in the sands and just say it&amp;#39;s up to the rest of the community to work through I to Z, but too often we do not document our footsteps well enough for others to follow in them.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=188997" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry><entry><title>Persistence Ignorance with LINQ To SQL</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/03/persistence-ignorance-with-linq-to-sql.aspx" /><id>/blogs/ian_cooper/archive/2009/03/03/persistence-ignorance-with-linq-to-sql.aspx</id><published>2009-03-03T13:51:00Z</published><updated>2009-03-03T13:51:00Z</updated><content type="html">
&lt;p&gt;I do not usually just re-point to older blogs, but some people including &lt;a href="http://blogs.msdn.com/donsmith/"&gt;Don Smith&lt;/a&gt; were asking in the Persistence Ignorance session at Alt.NET Seattle about support for PI with LINQ To SQL.&lt;/p&gt;

&lt;p&gt;I would maintain that LINQ To SQL supports a PI approach. I talked about it originally &lt;a href="http://iancooper.spaces.live.com/blog/cns%21844BD2811F9ABE9C%21397.entry"&gt;here&lt;/a&gt; but you might also want to read the relevant sections of my series on Architecting Applications with LINQ to SQL which cover mapping &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/02/17/architecting-linq-to-sql-applications-part-5.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/03/09/previous-architecting-linq-to-sql-applications-part-5.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The major lack is around support for a fine-grained object model i.e. you can&amp;#39;t map a value type to one or more columns only entities to tables. However, I don&amp;#39;t think that is a PI issue, but a modelling issue.&lt;br /&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=188881" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry><entry><title>ALT.NET Seattle 2009, some impressions</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/03/02/alt-net-seattle-2009-some-impressions.aspx" /><id>/blogs/ian_cooper/archive/2009/03/02/alt-net-seattle-2009-some-impressions.aspx</id><published>2009-03-02T19:52:00Z</published><updated>2009-03-02T19:52:00Z</updated><content type="html">
&lt;p&gt;Having just got back from &lt;a href="http://altnetseattle.pbwiki.com/"&gt;Alt.Net Seattle 2009&lt;/a&gt;, I wanted to post a few reflections. Mostly this is just a dump of things that grabbed my attention - its not meant to be any kind of documentation of the convesations there. I would also like to thank all the organizers for their effort - I had a great time - and my fellow delegates for stimulating and challenging conversation.&lt;/p&gt;
&lt;h3&gt;DTOs, Messages, and the Presentation Layer&lt;/h3&gt;
&lt;p&gt;I hosted this session. Given parallels with a morning session, it evolved into a discussion of communication between the domain layer and the presentation layer. The question many of us had was whether the consensus was that the presentation layer could depend directly on the domain model, or should depend on a seperate model that acted as an intermediary to the domain layer. Broadly there was agreement that the advantage of a specific model was reducing the coupling between the presentation layer and the domain layer by keeping the presentation layer igorant to the structure of the objects in the domain. &lt;a href="http://www.udidahan.com/"&gt;Udi Dahan&lt;/a&gt; pointed out that many of us were using the term &lt;a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html"&gt;DTO&lt;/a&gt; incorrectly to describe the composition or projection of data from the domain model into a shape that we needed for the view, pointing out that this was actually the &lt;a href="http://martinfowler.com/eaaDev/PresentationModel.html"&gt;Presentation Model&lt;/a&gt;. DTOs as a pattern represent on-the-wire serialization of data between to physical layers, not seperating between a &amp;#39;behind-the-glass&amp;#39; view of the data and the domain model. That clarification helped the conversation to realize that the principle we needed to talk about more was command-query seperation (CQS). We query for the presentation model, composing or projecting as required, and we update the domain model through a command. I realized that my conversations on this one had used lazy mis-application of the DTO name, and the session should be a good kick-in-the-pants to use terminology more carefully here.
&lt;/p&gt;
&lt;h3&gt;Can MS help with DDD Tooling&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.udidahan.com/"&gt;Udi&lt;/a&gt; challenged my thinking again in this session with the observation that in DDD the Aggregate Root is a role. The interesting part of this idea is that it allows us to treat aggregate roots (AR) polymorpically so that we provide separate interfaces for the use of the AR - the &lt;a href="http://www.objectmentor.com/resources/articles/isp.pdf"&gt;Interface Segregation Principle&lt;/a&gt;&lt;a&gt;. Some things fall out nicely once we do this. The first is the simplicity within the service layer of interacting with the AR now that we have reduced its surface area. But we can also make other decisions based of the fact that we now understand the context we are using the AR in. As an example, &lt;strong&gt;&lt;em&gt;orderRepository&amp;lt;IEnterNewOrder&amp;gt;.Get(id)&lt;/em&gt;&lt;/strong&gt; now carries enough information to allow the repository to decide which portions of the object graph need eager loading and which need lazy loading. Another is that if we want to use behavior based testing instead of state based testing on our service layer (because it holds no state) then we can easily provide a &lt;/a&gt;&lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;test double&lt;/a&gt; for the interface to the aggregate.
&lt;/p&gt;
&lt;h3&gt;Is Persistence Ignorance Necessary&lt;/h3&gt;
&lt;a href="http://neverindoubtnet.blogspot.com/"&gt;Ward Bell&lt;/a&gt; did a great job in facilitating the discussion, clearly setting out his understanding of PI and his concerns around it.There was a broad consensus that Persistence Ignorance (PI) within the domain model brought benefits to the developer (low friction,well-seperated concerns) but &lt;a href="http://neverindoubtnet.blogspot.com/"&gt;Ward&amp;#39;s&lt;/a&gt; question was to whether this meant paying a high price within the infrastructure layers where that PI was implemented. I believe that those of us who favor PI were able to get agreement from those who are still doubtful that if it was easy to implement persistence with PI as without, then they would support PI, because they could see the benefits. Obviously the NHibernate fans felt that the cost of supporting PI was well worth the benefits. But, it&amp;#39;s always seems easy when you know how. It&amp;#39;s always worth the PI believers remembering that they had to make the effort to learn the paradigms that NHibernate uses to support PI (sessions, transient and persistent objects etc.) before they could reap its benefits. So the feeling that PI takes effort is understandable, because there is a learning curve the first time you use an ORM that supports PI.
&lt;p&gt; But the conversation ended positively because many of the doubters seemed to be more open to deeper exporation of NHibernate in order to more clearly understand why those using NHibernate do not find the cost of supporting PI an issue. Overall a session that could have been very fractious ended up being very fruitful.&lt;/p&gt;
&lt;h3&gt;Why We Stopped Using the Auto-Mocking Container and What&amp;#39;s Next&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://aaron.codebetter.com/"&gt;Aaron Jensen&lt;/a&gt; hosted this one. He shared his experiences of the issues with over-use of mocking within your tests. I was interested to see this one emerge because I have posted about it before, from &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2007/12/19/mocks-and-the-dangers-of-overspecified-software.aspx"&gt;my own experience&lt;/a&gt;,and in our discussions at &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/02/04/classicist-vs-mockist-test-driven-development.aspx"&gt;altnetconf in the UK&lt;/a&gt;, but not really seen much acknowledgement of it from the other side of the pond.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s timing is also ironic because although we prefer state based testing in our domain layer, I am starting to move toward preferring use of behavior based testing in the service layer precisely because services have no state to test, and I don&amp;#39;t want to test the state of the Depended-Upon-Components (DoC) from my Service Layer. The conclusion from the fact that both absolutist approaches lead to issues would seem to be that an appropriate combination of behavior and state based testing is needed, depending on the characteristics of the System Under Test (SUT).&lt;/p&gt;
&lt;p&gt; One issue with a state based approach is that it is harder to see how it works with a top-down or outside-in approach to building your components as opposed to an inside-out or bottom-up approach to development, because the top-down approach relies on stubbing out components. We tend to use CRC cards or whiteboard sessions to determine what to build. Fitnesse tests work well with this style too because we can define failing tests prior to providing an implementation. We then build bottom-up, assuming the risk of some re-work for un-needed objects or methods will be small. Aaaron was investigating a best of both world&amp;#39;s solution that would allow him to combine the design benefits of a top-down approach with the amenability of state-based testing to change. It will be interesting to see how that develops.&lt;/p&gt;

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=188836" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author><category term="Agile" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Agile/default.aspx" /><category term="altnetconf" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/altnetconf/default.aspx" /><category term="Mocks" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Mocks/default.aspx" /><category term="NHibernate" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/NHibernate/default.aspx" /><category term="Events" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/Events/default.aspx" /><category term="ORM" scheme="http://codebetter.com/blogs/ian_cooper/archive/tags/ORM/default.aspx" /></entry><entry><title>With Services the focus is on behavior</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/02/21/with-services-the-focus-is-on-behavior.aspx" /><id>/blogs/ian_cooper/archive/2009/02/21/with-services-the-focus-is-on-behavior.aspx</id><published>2009-02-21T15:54:00Z</published><updated>2009-02-21T15:54:00Z</updated><content type="html">&lt;p&gt;This post is really just tying together some ideas. A year ago I posted on &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/02/04/classicist-vs-mockist-test-driven-development.aspx"&gt;my preference for classicist TDD&lt;/a&gt;. However, when it comes to services you are dealing only with behavior not state so using classicist approaches becomes trickier. One way out of this issue is to test the results of the service on the stateful objects (entities, repositories) that the service interacts with. Having experimented with that style the outcome is usually unsatisfactory because the service&amp;#39;s tests frequently mirror the tests against the stateful objects themselves. That leads to un-needed code (or worse duplicated code) in the tests, and multiple tests failing when you get something wrong.&lt;/p&gt;
&lt;p&gt;So I think this is one of those cases where it is clear that the way to test the System Under Test (SUT - the service you are testing in this case) is by its interaction with its depended upon components (DoC).&lt;/p&gt;
&lt;p&gt;I also think that this approach helps prevent the obesity issues with &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/12/03/the-fat-controller.aspx"&gt;Fat Controllers&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2009/02/19/quot-inappropriate-intimacy-quot-points-to-the-bleeding-out-of-your-domain-logic.aspx"&gt;Flabby Services&lt;/a&gt; because it discourages you from adding much additional behavior to your service beyond command and control logic, because it is then hard to test that outcomes of that logic.&lt;/p&gt;
&lt;p&gt;So in the context of services I would vote for looking at &amp;#39;mocking&amp;#39; as an approach.&lt;/p&gt;
&lt;p&gt;For controllers, we have found &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/archive/2009/02/03/auto-mocking-explained.aspx"&gt;auto-mocking containers&lt;/a&gt;&lt;a&gt;&lt;/a&gt; to be a powerful way to get our code under test.&lt;/p&gt;

&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=188540" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry><entry><title>"Inappropriate Intimacy" points to the bleeding out of your domain logic</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/02/19/quot-inappropriate-intimacy-quot-points-to-the-bleeding-out-of-your-domain-logic.aspx" /><id>/blogs/ian_cooper/archive/2009/02/19/quot-inappropriate-intimacy-quot-points-to-the-bleeding-out-of-your-domain-logic.aspx</id><published>2009-02-19T09:24:00Z</published><updated>2009-02-19T09:24:00Z</updated><content type="html">&lt;p&gt;A while ago I posted about &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/12/03/the-fat-controller.aspx"&gt;Fat Controllers&lt;/a&gt;. Another area that can quickly get beyond you are any domain level services that you have. Often this is exactly what your controllers are calling. Services should have no state and do co-ordination and control. Your domain logic should not live in the service layer, it lives in the entities that your service co-ordinates.&lt;/p&gt;
&lt;p&gt;In a Domain Driven Design architecture your service often serves to retrieve aggegates from one or more repositories and then co-ordinate calling methods on the aggregate roots to carry out your intent.&lt;/p&gt;
&lt;p&gt;One way to see that problems have arisen is if you have what Fowler calles the Inappropriate Intimacy smell between the service and the aggregate root.&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;Sometimes classes become far too intimate and spend too much time delving in each others&amp;#39;private parts. We may not be prudes when it comes to people, but we think our classes should follow strict, puritan rules.&lt;/i&gt;&lt;/blockquote&gt;
&lt;p&gt;A good aggregate is a boundary to outside interference, somewhat akin to a facade. If outsiders want something from within the aggregate then they are best of asking the root for it, not drilling into the graph of objects under the root. Watch for using the dot operator to navigate your way into the aggregate as a smell that your service has inappropriate intimacy. That inappropriate intimacy will almost certainly result in domain logic leeking out of the entity and into the service layer&lt;/p&gt;
&lt;p&gt;The Inappropriate Intimacy smell is closely connected to the Law of Demeter. Simply put the Law of Demeter says that we can play with our friends but we shouldn&amp;#39;t touch their intimate parts. A more complex definition is that we should only call methods on objects that we own, create, or receive as a parameter, not on objects that are returned from one of those &amp;#39;friends&amp;#39; by a method call or property access.&lt;/p&gt;
&lt;p&gt;As an example the code below violates the Law of Demeter, because it chains through from our friend to one of its intimate parts&lt;/p&gt;
&lt;br /&gt;&lt;b&gt; var options = product.Characteristics.SupportedOptions;&lt;/b&gt;
&lt;p&gt;It&amp;#39;s likely that we are getting the supported options because we want to perform some business logic with them. It would be better to move the logic that needs those options down to the Characteristics or SupportedOptions level as appropriate.&lt;/p&gt;
&lt;p&gt;Sometimes the Law of Demeter is treasted as though the code is more what you&amp;#39;d call guidelines but violation is usually a sign that you are bleeding domain logic through an open wound.&lt;/p&gt;
&lt;p&gt;One area of temptation that seems to be catching some right now is the use of LINQ expressions. LINQ expressions can provide you withe a concise and declartive way to iterate over a sequence and perform operations, but they can be tempting to code so that they violate the Law of Demeter, just because you can, pulling domain logic into the wrong location. Consider the above example again:&lt;/p&gt;
&lt;br /&gt;&lt;b&gt; var matchingOptions = from option in product.Characteristics.SupportedOptions&lt;/b&gt;
&lt;br /&gt;&lt;b&gt;			        where option.Code == &amp;quot;Foo&amp;quot;&lt;/b&gt;
&lt;br /&gt;&lt;b&gt;                            select new Match {Code = option.Code, Price = option.Price, InStock = option.InStock};&lt;/b&gt;
&lt;p&gt;The solution here is to move this logic down on to iterate the list from within Characteristics and provide a method on Option that allows creation of a Match without exposing its details to the caller&lt;/p&gt;
&lt;p&gt;If you don&amp;#39;t watch for inappropriate intimacy you will find that you end up with transcation scripts in your services. Those in turn lead to duplication, because it becomes hard to find existing funcionality that already provides that feature. Duplication makes our system difficult to maintain because we have multiple versions of the truth which increases the cost of updates and the risk that they disagree as to what the truth is.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=188482" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry><entry><title>Learning some new tools</title><link rel="alternate" type="text/html" href="/blogs/ian_cooper/archive/2009/01/21/learning-some-new-tools.aspx" /><id>/blogs/ian_cooper/archive/2009/01/21/learning-some-new-tools.aspx</id><published>2009-01-21T22:20:00Z</published><updated>2009-01-21T22:20:00Z</updated><content type="html">&lt;p&gt;I an re-writing the &lt;a href="http://dnug.org.uk/"&gt;London .NET User Group website&lt;/a&gt; which is old and long in the tooth. I like these personal projects because they form a great learning opportunity. I can explore new tools and frameworks without worrying about exposing an employer to &lt;a href="http://codebetter.com/blogs/ian_cooper/archive/2008/10/10/on-project-learning.aspx"&gt;&amp;#39;learning on the job&lt;/a&gt;&amp;#39;.&amp;nbsp; I have a number of learning goals on this project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.asp.net/mvc/"&gt;ASP.NET MVC&lt;/a&gt;. I am using &lt;a href="http://www.castleproject.org/MonoRail/"&gt;Monorail&lt;/a&gt; commercially and I am looking forward to getting a feel for the differences.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.dejardin.org/"&gt;Spark View Engine&lt;/a&gt;. I prefer templates that do not obscure the structure of the html and I&amp;#39;m looking forward to taking this one out on the road.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/specunit-net/"&gt;SpecUnit&lt;/a&gt;. I have wanted to give an &lt;a href="http://xunitpatterns.com/example-driven%20development.html"&gt;example-driven development&lt;/a&gt; tool a run out for a while now as part of efforts to pick up from the &lt;a href="http://dannorth.net/introducing-bdd"&gt;BDD&lt;/a&gt; guys.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/fluent-nhibernate/"&gt;Fluent NHibernate&lt;/a&gt;. I&amp;#39;m a Castle Active Record user, but I want to find out if Fluent NHibernate offers me anything more. &lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#39;ll probably give some feedback on all of these over the weeks, including fluent NHibernate in my NHibernate series.&lt;/p&gt;
&lt;h2&gt;Trial and Error&lt;/h2&gt;
&lt;p&gt;One really interesting idea is &lt;a href="http://blog.jagregory.com/2009/01/10/fluent-nhibernate-auto-mapping-introduction/"&gt;Fluent NHibernate&amp;#39;s Automapping&lt;/a&gt;. Fluent NHibernate is a great example of what is possible with &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/07/06/exploring-shadetree-features-part-1-static-reflection-with-reflectionhelper.aspx"&gt;static reflection&lt;/a&gt;. However, I found myself a little bit cool on automapping at first. I found it a little hard at first not knowing what the mappings were. I&amp;#39;m used to using &lt;a href="http://www.castleproject.org/activerecord/index.html"&gt;Castle Active Record&lt;/a&gt; whose close association between attribute and mapped property or class makes this fairly explicit. I have always been less concerned by friction from representing orthogonal concerns as attributes so it took me a while to before I started to enjoy Fluent NHibernate&amp;#39;s ClassMap. Automapping pushed my comfort out even further because it was even more &amp;#39;under the hood&amp;#39;. Getting more comfortable here was a multi-step process. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The first was using the explicit ClassMap files to become confident with the mapping, before tacking automap. Small steps.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;The second step was to hook up log4net (a good step with NHibernate anyway). Maybe its just reflex but when I get a persistence error one of the first things I want to do is look at how I was mapping. This meant I could refer to the generated xml for the mapping when I set the logging level to DEBUG. I generate the Db from the domain model using a separate console project I just run from the command line, so this simple step meant I could recover the feedback I wanted as to the mappings from that. That helped me see my mistaken assumptions or confirm that the automap was doing what I wanted.&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;The last step is to use the built in support for integration testing that the Fluent NHibernate project provides. That gave me confidence that the mapping was what I wanted. James Gregory shows how &lt;a href="http://blog.jagregory.com/2008/08/08/introducing-fluent-nhibernate/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, I suspect that you may need to be careful if your domain has a lot of exceptions. Exceptions may end up being confusing. I&amp;#39;m not sure that &lt;a href="http://blog.jagregory.com/2009/01/11/fluent-nhibernate-auto-mapping-entity-conventions/"&gt;altering the conventions for the mappings that differ&lt;/a&gt; may not end up being less confusing than just explicitly mapping in the long run. I suspect there is a trade off here. If most of your classes conform to your conventions and you only have one or two exceptions this may be the way to go, but if you have a lot of variants then this may not be so helpful and you might be better off just using the explicit ClassMap&amp;lt;&amp;gt;. &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;My one oustanding concern is how people&amp;nbsp;&lt;a href="http://blog.jagregory.com/2009/01/10/fluent-nhibernate-auto-mapping-introduction/"&gt; supply automap with criteria for the classes to map from the assembly&lt;/a&gt;. Your domain assembly will contain a lot of types which will be transient and not persisted. So you have to provide some selection criteria to pick the types you want to map out of the assembly. The danger here is that to make my selection criteria you might adopt a strategy of deriving from a base class or interface which does not have any value in your domain but is just a &amp;#39;marker&amp;#39; for persistence. This reduces my adherence to Persistence Ignorance principles because my entity ends up being designed to meet the needs of a mapping technology. I suggest preferring to use criteria such as namespaces here. &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://codebetter.com/aggbug.aspx?PostID=187338" width="1" height="1"&gt;</content><author><name>Ian Cooper</name><uri>http://codebetter.com/members/Ian-Cooper/default.aspx</uri></author></entry></feed>