<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-385473814989421290</atom:id><lastBuildDate>Fri, 13 Feb 2026 11:06:29 +0000</lastBuildDate><category>.NET</category><category>ActiveRecord</category><category>Build</category><category>PSake</category><category>PowerShell</category><category>XML</category><category>BookOfIdeas</category><category>BugByDesign</category><category>Generics</category><category>RavenDB</category><category>Sessions</category><category>Web Frameworks</category><title>Morts Like Us</title><description></description><link>http://mortslikeus.blogspot.com/</link><managingEditor>noreply@blogger.com (Anonymous)</managingEditor><generator>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-5441221933329020746</guid><pubDate>Tue, 07 Aug 2012 20:43:00 +0000</pubDate><atom:updated>2012-08-07T21:44:53.010+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">RavenDB</category><title>Playing with Ravens</title><description>&lt;p&gt;Right now, I have a few ideas for pet projects I plan to work on over the next months. More on that in another post, but most of them include a data store other than an RDBMS.&lt;/p&gt;  &lt;p&gt;Being on .Net, I have chosen to use &lt;a href=&quot;http://ravendb.net/&quot; target=&quot;_blank&quot;&gt;RavenDB&lt;/a&gt;. Now it’s not that easy for an old SQL boy like me, so I started playing with it and making some notes here.&lt;/p&gt;  &lt;h4&gt;Getting the software&lt;/h4&gt;  &lt;p&gt;Ayende said on the mailing list, the &lt;a href=&quot;http://builds.hibernatingrhinos.com/builds/RavenDB-Unstable&quot; target=&quot;_blank&quot;&gt;current unstable version&lt;/a&gt; will be ready in a few month. Realistically, I won’t finish my project before this upcoming version will be out of support &lt;img style=&quot;border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; alt=&quot;Winking smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdE9BsSm-FZg2mnnmvldnV_RnCav7GUHtaXhset_4KKn0jTyXEBlbADYazrTGtK_MFCQfbxtWI50sSxum6-4dzBlt6GxMDyoIlLSAXP3x_FRPgMrYkX21YDMAP3xAA8nLxF1X3zweeXcQ/?imgmax=800&quot; /&gt;, so I can go for unstable confidently. Even more when I read the standard reply on the list for bug reports: &lt;a href=&quot;https://groups.google.com/d/msg/ravendb/mSsdFgM-QYU/pwah-4o5iYcJ&quot; target=&quot;_blank&quot;&gt;&amp;quot;Test will pass in the next build.&amp;quot;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Installing&lt;/h4&gt;  &lt;p&gt;Simple: Unzip build to directory, and call start.cmd. This will even work by clicking on it since a new window pops up by default. &lt;font color=&quot;#666666&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;However will be a UAC popup as the server calls netsh to grant rights for http.sys, but it requests this only once.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h4&gt;First steps&lt;/h4&gt;  &lt;p&gt;In the beginning, there was nothing. Not even a database, so let’s create a sample database. Did I mention I love it when batteries are included?&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9lrLs4FnNgxLNTyI0uyMtYvM2JiMZYEh0lyHreLuiZUIrmebG2WJC4m5Ec7ADNcA8xK1SiaXnxkN9Kg3yGGx_fnhYIASlSK9RcMGmxktv4LQRO1fUTcp-qF9Q16i2lu2fUKwLs_xqjoI/s1600-h/image%25255B11%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV3KjoL5AC3V6Ic6XsxpqLmJq7YFH2ZEOy7r4D35r-Jdxz-Z5v5_TLdPG4kSGFXsM_F6s4eqIWNUxhebknJfbH1VFF_m5PBGUSVVVaB5CxncUvBsC4Cc0T7pUrdgr7gRe42oIr18iHIA0/?imgmax=800&quot; width=&quot;804&quot; height=&quot;564&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After creating the sample data, let’s take a look at the contents:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMHaQQZ94Oa7u6mX8bK1F19KBcSmk_DPqXwAZ5r84sxZqmTv7E5V7LZxlqNtPi3oaXGnq_vpvmYQwWwNJIndADYo4ZhTUcwI6cbgAnmUm28-E0k8O3gr5EfnjZ-HfZvhE1HnDKXi_ZVl4/s1600-h/image%25255B17%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHIpBExPw_apqHmMNfmN_pyxt4fWutIdNCApI6kFsguB8ccVdqR5k2V304XUm3p-HSdi9xa_wdYNnELaXDmHdvdeH1TTHd8K8_veolJjC0lmtCD5aQAeUQoL8MdNaz3uDKAPYBUWe4fDw/?imgmax=800&quot; width=&quot;644&quot; height=&quot;471&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ok, so we can view and inspect and update entities. Now, can we also do queries?&lt;/p&gt;  &lt;h4&gt;Querying data&lt;/h4&gt;  &lt;p&gt;Now where are the queries? It turns out (with a little bit of clicking around) that they are filed under indexes.&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUx0yo-vN_cxOEiT3CAhQEyyzdOZOdT5GaeYQZ5LBJy-eFv6g6qgdMBRvS4gaJ86yuYKqBgg_gtHr10-nXuLSh6YcwfB_t3Mng8gM2_M1ek4UtVtIu9-3yUw_8eESspHsxkX24RnT64CQ/s1600-h/image%25255B21%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIduYbxqPwOz2rfX_a6DUfzvWCb5KuwJUCh03r3ocnqANxp8tylqyyaQ2_IvfmuV5EV-OfJgRnYORJwuYxyckoe6o4TkIeh-biI7H6UCuovbjRXYH5CpTs42GxDkWkfmBiHZ38PFOi4oQ/?imgmax=800&quot; width=&quot;367&quot; height=&quot;132&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So let’s start with a dynamic query, which is the equivalent to ad-hoc SQL queries on an RDBMS. Raven uses Lucene query syntax, which is documented on the &lt;a href=&quot;http://www.lucenetutorial.com/lucene-query-syntax.html&quot; target=&quot;_blank&quot;&gt;Lucene tutorial&lt;/a&gt;. Now let’s look what albums are of my taste here:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzHYpM5evJvO7prYyPT4Fudkz3VIOEfi4JPIs0Sq0mVI7c9C1zTYZ81LqHdl5G2kQt2VP8u95RpHzLOqEF1_58ed3wvIaVimGGihjthSSiazYbfpi9HxHJ8vVKxxC7ofVTcxYosJY9D1k/s1600-h/image%25255B25%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg59-hFA84G-MeZtfSVDK41T7reMzciuDPUgp7ECfaY-Z1k3STsdzUqseMB3rvtylCSk2fVP72zYkzcf-Z9ltPNSMdCa1yXH25d16ttZibR1M17r-eGl1_FM2-X2acrC31Y2VmI12Ld6yA/?imgmax=800&quot; width=&quot;819&quot; height=&quot;482&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ok, that’s cool. We have everything we need on the page: Query, results, statistics. However, the result data displayed is not what I wanted. So I hit “Show fields”, hoping to get some dialog for choosing fields. But when I have it activated, Raven only displays the IDs of the documents.&lt;/p&gt;  &lt;p&gt;Well, you can change it by right clicking the column titles:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrBPAs5uv198cbdo3Qid-nwd4oLJQCj-GbH9p9l6Iyc89oRvpc-SrsZjEQ809C-bkAT8pPRiqRyr0SYNsQO8TtYvXtcvvmX6hkH0LzOnurw2nnVRqYaStqTa0yi9oyeIAoneaqlBJxdJM/s1600-h/image%25255B29%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3ZLzklFkmbSOTjVyOpZTo4WFLKoZeZI82jQsx-s5hEZR8sswbbTZNHVbRu8zGsHx7g8-ItJ6ZmK1sDcG9aJZ41Ipcs9Cl3gg3hvdeUadAU0VxrcQBygOsl5hPQzXTA-1V8SXP17g6rsM/?imgmax=800&quot; width=&quot;272&quot; height=&quot;87&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1fE75QrX-kUD1mrsGxsrn7wexJiRjyyTp8sPbky4-gZWauj4hXRhqSJyghKxAjv8MNr1KbaMXUE0FYOIohlu5h-WIgTzYeaPwprxHBcctITzXWuhBdaj4eYtjCkoeYStNQj6BsCv5WSo/s1600-h/image%25255B33%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimxblHG9XL-_i90GFASkeIRYQCKh_0DTshHLM31QJku3BCi-Qa2qWDbWFkmrEOykBEYSyyflWNfarXzvZlLma5Vpu2Fbi_Ju5EOCKcEOJKd_CobsB65iLx7ekviJXeVnxhHRxMfT4uvxs/?imgmax=800&quot; width=&quot;409&quot; height=&quot;317&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaVe0480pNm7NgtnusZ4McSKvB_dzCWfmAH_uj68ax4sV_WL4Qoilt7IZqw53GO5Av-LqNP3xF4g7cxDgPzas73ulfnaoWU2Vk1GTmrQvArU6J4BowueYqM385j5KkY0vMdNkYYsJAFi4/s1600-h/image%25255B40%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO78BBpf3ap0qeiSqNrUVqNGnlbtcQxjVALkBqyhBgAeemCoSMPp8qiL2ZkIHQQKnPuQmkWWzdcRBoMWKhfHQ4mFwznEnE7kqkES8vIyioLTqJJT7zV1On_0snfqSGnQ2fFIz-Zarfpas/?imgmax=800&quot; width=&quot;509&quot; height=&quot;186&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ok, so we can query the data ad-hoc without writing a &lt;a href=&quot;http://howfuckedismydatabase.com/nosql/fault-tolerance.png&quot; target=&quot;_blank&quot;&gt;map-reduce-function&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Indexes&lt;/h4&gt;  &lt;p&gt;Back on the index page, the query I just executed is displayed as an temporary index:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgypADm297NQnV8BEYRJO0srrro7NrjeVoZd-aDBSUYWXBfqzVs2nnFJvoWA6U8RvKPKBsuRaP1jUyeW6B-wfAR779_PIRpdqnwfcd2GHGKbL532f9sKJB3tFC4qCw0XpzfnRUhbXKBk6U/s1600-h/image%25255B48%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc2TkvXJlRuFzcGa0gzq-d9FO2rAWY72caYaUyiYxBVfp3wuGZ3gBEVpQbrvjjZNdxUANdvoh38E78xo7Bg198RBrx0sSN5KaXYBw9l8brfr_OfTGKv6y43EOzbH5m9lNLa2gc3psrRiw/?imgmax=800&quot; width=&quot;424&quot; height=&quot;273&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ok, let’s edit this, so we can get the same result as before:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhse4A8p_fVkHClhkGhk09bJZw03AOihwF2PYbNKTE1-g8Itmf5zPs7BDnqyZMKCA5PmHhq6ujYn-GUM1y6ZuPe4KEpHTG1fCMqdkANgAlIEe2OgO240NIsW4u63snj5KvrhZDNK6xKgJo/s1600-h/image%25255B52%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQ7pHAGzj8XaZAnzoGtCcwmbWME1isGC8zyJ7UwrgBsSUxhef0FvoiCy3lYwonAFosd30mzs4Fj3EI_imxTVWH2jbs19MH_d-FE3cn3OVwC3eNHiB5aqveKbDMHoemkfPavMcIePc6SoI/?imgmax=800&quot; width=&quot;321&quot; height=&quot;45&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Looks like C# Linq, so how about this:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglkmmCw9tvFkPcI-Z6Dzx9VOg9wvYnC5idDLOfpCymsQRboTCcGMMKKkxkjU0krrO3OlfS5aKXL_KmKQaVAapAm2Ge2nwinbLIXvOCgNg1oWeH_d0qiYVgsmE2eyB67T-fak2L8feNbvo/s1600-h/image%25255B56%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG3J6uD-gc7TpwYhnO73wCKSu-H38OIBfPsKxxVz1g3q44RsWfGlUrzYImdYbcgGeBcUSy7Mr7rVsDGnNizxPxsdMhqQT1c0ovFS4aU18KBZmpHlXU6KhxGWLSmfz3OxpvaNw4iXruC_U/?imgmax=800&quot; width=&quot;404&quot; height=&quot;287&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That looks promising and the index can actually be queried, but the studio shows the same strange result as above:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1ITlR5rsehgg18H2HP7_Ph3lMNEwBitk-O-mh7vPR1N4eWvX7GreCeNH0_mnRqC157ISAGB0dgx3yQlckQ6UXQ5M6c3srtrFvbvILulvQ7loURskt-qsCk4-ryLm3__ZdqZmO41_tv94/s1600-h/image%25255B60%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSvwpKGaiwkHFN4iBIMyq2kr9AQ4jjybB6bVtcP0Fi5YTjwZ4wJ1616nesuzKbtuAEd5e9IkQI-hDBNr8JHASbsoG4sqs5u1FCY28kydY1rmUt6xs8u3HvOMC1nzAnIhOlk3xbLOpk6n0/?imgmax=800&quot; width=&quot;899&quot; height=&quot;447&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Eventually I will find that out… some day…&lt;/p&gt;  &lt;h4&gt;More Indexing&lt;/h4&gt;  &lt;p&gt;Now let’s go for a more demanding example. I want to know how many albums each Artist has published here. Luckily, there is already an artist index we can start with:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpgBCj0l2iy0fnuR6VbgCLdSUzSxHBGd25wjh2hyUfgfrfrqMUd-Ip03kUFZjBxr-0WNLSwVSSFMz25I_uCTooduv9bkWDTTNzuky7Gk1P-zYf4ofKZcLLDdJJ0Ygl18rJ0Nt9FkJJRV0/s1600-h/image%25255B64%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLFA_8NfEDop2DhgmIAuvTFmJR8LEL88GvYTdGbsjl05lv2dzJqa_bstkzY9sPlwg-pQfW8IwV1OGSHwIe34eV7VFlhFDP5fyXSCE5cLUpGX890LD_-hiRzFcyr4FjCfeuyJedk1ivFbg/?imgmax=800&quot; width=&quot;492&quot; height=&quot;288&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s actually quite easy, though I needed some minutes to get it right:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkKmI8vYFXy2mR9SliaKxo5dWdf1nGB8P0dCxedy2rxdz-yrRo-1sAdT99SZATK5L9CaLoYZBMH9tfrkI0D7AAafZP5ylM9Nr8cQNGWS4NqECvyiKBbRdF7zzFWbfEusGGgmrAtEovE-E/s1600-h/image%25255B68%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjXnX7sTHEJPm0CRd35FZWp3t5n-CS4S3MZ7ekS8ZhWACN3Wl8Q2N7JNYboYrdeJtjyGH9-wvoX-UEys9LE8BA0hD2fR1fVJa1XT6Ht97WnBdCvxNIxnUMxgY-GH1oycTaIZR5XgzEz14/?imgmax=800&quot; width=&quot;565&quot; height=&quot;295&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You should keep the following in mind:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Don’t put the Albums count into the group &lt;/li&gt;    &lt;li&gt;Use Extension Methods for aggregations &lt;/li&gt;    &lt;li&gt;Everything is case sensitive! &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now we nearly got it:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLJwEiZJ5Y3HopMDK9_K7A88RmOXNzeu-QPeIzVElpcSDDiSbIvhCS3te9Tp_3pkzqultpky9iVlkG4tLVVBZ8vCdkGethS_InZFalYST8poeQ43uCkLoz0XuZ8t7SV7fXa6AZyx2jRNg/s1600-h/image%25255B72%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmQVm9P3y-cNAd-Qvm4EMa_gABhAbiYLUl5s_HiX2DgvJcEgaWW_K7u6dxiy5V_0FlIiMn5Z3KWnbtwNdZIwzpvauZrj_iC38Dkcs3DFYfuKChhMilE3PqIx1WDVQ6kQcDUcTWVGzQvFQ/?imgmax=800&quot; width=&quot;457&quot; height=&quot;258&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;One more thing before I send the ravens back to their nest. I want only Artists that have between 10 and 20 albums published in the database. The default Lucene Syntax could be: Albums: [10 TO 20], but&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIFzx-7zDdd4Px18I1BhUsFn42JQ7Y0yGNLNwY4jF9Z40o-mFugqJGNyVsS55R5yZKzWcPUEipBBRIp0dtxbq2IY3xJ8h5jyW8ocC0CR3Ur9B6KeBiuDUuC3qC7pKQJoC8gKOXAYuvfmQ/s1600-h/image%25255B76%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3rfCAQiBjfnN11fCd1cTPe2pcFjik0XAQzt36-P1vd4ntgB84Q2koKfLyMBnGz0REeNEZcFUwRiCBbUaHTlifvwD4NlmhsBnr1mJlxTUdD8sOqj5hNGKe6Fw0HeLU4t9HUdlwdzsPDZ8/?imgmax=800&quot; width=&quot;519&quot; height=&quot;342&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lucene searches lexicographically, so we need a special, yet nearly undocumented syntax, that I found in an example in the &lt;a href=&quot;http://ravendb.net/docs/client-api/faceted-search&quot; target=&quot;_blank&quot;&gt;RavenDB docs&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEd2dApeDfHookzzUotjNb50td_s_aSiROdOFfzK7Vy8vzfNKwHNujAXil_VTBHbT_pJIw3OaH8yhJGQGbIFptf_3GpdFTKStprI1zrYPLxMlEbFy9Ecg7xPuNrLbsFS1sWdpjsV0XJ7s/s1600-h/image%25255B80%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjACCntVtB7jd0EUu_0moJ8Ki1SoT3bkoLOeycm_H6ygSqAMrUhkZq62KsbZn7dtNLWBwv1PmXpXq4S_fqnoeucGOYzXhwWYAKXCjaMK2Mv5jQrEOwsJNnI20y4bxYwRm3WpoFegue840M/?imgmax=800&quot; width=&quot;488&quot; height=&quot;276&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;p&gt;Now I feel somewhat familiar with the studio, so next time let’s see how we can query this values from within code.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2012/08/playing-with-ravens.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdE9BsSm-FZg2mnnmvldnV_RnCav7GUHtaXhset_4KKn0jTyXEBlbADYazrTGtK_MFCQfbxtWI50sSxum6-4dzBlt6GxMDyoIlLSAXP3x_FRPgMrYkX21YDMAP3xAA8nLxF1X3zweeXcQ/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-6300269945773768967</guid><pubDate>Mon, 02 Jan 2012 18:40:00 +0000</pubDate><atom:updated>2012-01-02T18:40:54.900+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web Frameworks</category><title>To How Many Bounded Contexts Does Your Model Belong To?</title><description>&lt;p&gt;Yesterday I have read &lt;a href=&quot;http://lostechies.com/chadmyers/2011/12/30/sweet-sweet-vindication/&quot; target=&quot;_blank&quot;&gt;this blog post&lt;/a&gt; by Chad Myers. I agree with him – more or less – on the current state of web frameworks, but I have something to add:&lt;/p&gt;  &lt;h4&gt;&lt;strike&gt;More pants&lt;/strike&gt;&amp;#160;&lt;a href=&quot;http://www.youtube.com/watch?v=Ii7S0SDQbxA&quot; target=&quot;_blank&quot;&gt;Bras&lt;/a&gt; on the head&lt;/h4&gt;  &lt;p&gt;Chad emphasizes the …Model. Every web framework since WebForms emphasizes the …Model. There is MVC, there is MVVM and MVP. Everywhere there is a …Model. But what is the …Model? Let’s take a closer look.&lt;/p&gt;  &lt;h5&gt;What is a model?&lt;/h5&gt;  &lt;p&gt;A model is an abstraction. If I have something complex, something too complex to handle, I create a model that allows me to handle it. Looking at typical web applications, I ask myself: What is so complex here that I need an abstraction layer or even two?&lt;/p&gt;  &lt;p&gt;To pull the data from the data store, we use a model. We put bras on the head and chant the rhyme of “Persistence Ignorance”. Then we build another model, now called view model that consists of a projection of the “real model” along with some specialized collections with one or two extra properties, because using more than one object to pass in the view is the deadly sin of web programming.&lt;/p&gt;  &lt;p&gt;All this to put a simple &lt;font face=&quot;Courier New&quot;&gt;SELECT TITLE,AUTHOR FROM POSTS &lt;/font&gt;&lt;font face=&quot;Verdana&quot;&gt;on a web page? You must be kidding.&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;Complex Applications&lt;/h5&gt;  &lt;p&gt;Ok, not all applications are tutorial like. Let’s have a look at an application that deserves a model: Imagine something more complex, like Eric Evans shipping sample in Domain Driven Design. Here we have a model and the model will be used to calculate shipping costs and the time required to deliver and so on.&lt;/p&gt;  &lt;p&gt;But will you use it in the company’s web application? Most likely not. To be more precise, if you do, you really need to reread Mr. Evan’s book.&lt;/p&gt;  &lt;p&gt;So what model will you use in such an application? I guess there will be a CQRS-like denormalized data store for you application and changes are either issued with service calls or commands. In this case you will use your models to put an even simpler &lt;font face=&quot;Courier New&quot;&gt;SELECT * FROM SpecializedViewTable &lt;/font&gt;&lt;font face=&quot;Verdana&quot;&gt;on a web page.&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;Something in Between&lt;/h5&gt;  &lt;p&gt;There are a few web applications that have a model that is the only bounded context and still complex enough to justify a model. If you have such a domain, you’ll be fine with the model cascade on your web application, but I have found them to be quite rare. &lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2012/01/to-how-many-bounded-contexts-does-your.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-416947772215127594</guid><pubDate>Thu, 22 Sep 2011 16:26:00 +0000</pubDate><atom:updated>2011-09-24T11:35:00.975+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">ActiveRecord</category><title>The Big Rewrite (1)</title><description>It has been a long time since my last blog post. It also has been a long time since I worked on the Castle project either. I don’t want to talk about the reasons however, but I had some ideas regarding ActiveRecord which I want to share.&lt;br /&gt;
My ideas have nothing to do with the current version of Castle ActiveRecord. Henry has done a great job pushing an RC out of the door, but AR’s codebase has grown over the years into a state that makes it hard to impossible keeping up with NHibernate’s features.&lt;br /&gt;
In the meantime, other changes took place in the world of ORMs that make most AR’s current features obsolete:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;For NHibernate there are two independent mapping libraries allowing to work without XML. I have used confORM recently and it is a pleasure to use. Mapping with attributes is rather clumsy compared to confORM, FluentNHibernate, or NHibernate’s own mapping by code. &lt;/li&gt;
&lt;li&gt;Since NHibernate 2.0 (which is a long time ago), transactions are mandatory. AR uses SessionScope and TransactionScope and a few other scope types which aren’t used widely, making AR even more complicated than naked NHibernate. &lt;/li&gt;
&lt;li&gt;NHibernate has new mapping features. Honestly, I don’t know whether someone has added them to the AR codebase. The last time I tried, the visitor model used for examining the attributes drove me nuts. &lt;/li&gt;
&lt;li&gt;Entity Framework has matured and while EF 4.1 is still a bit behind NHibernate, it is simpler to use than ActiveRecord. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
Goals of ActiveRecord vNext&lt;/h3&gt;
So what are the features I envision for the next AR version? You might guess them from what I don’t like in the current version:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ActiveRecord API (entity.Save() etc.) &lt;/li&gt;
&lt;li&gt;POCO Support &lt;/li&gt;
&lt;li&gt;Testability &lt;/li&gt;
&lt;li&gt;A single Unit-of-Work concept. &lt;/li&gt;
&lt;li&gt;Abstracting from the used ORM as much as &lt;strike&gt;possible&lt;/strike&gt; reasonable. &lt;/li&gt;
&lt;/ul&gt;
For now, I will only highlight each of the design goals in short. I will share more on them in separate posts.&lt;br /&gt;
&lt;h4&gt;
&lt;/h4&gt;
&lt;h4&gt;
ActiveRecord API&lt;/h4&gt;
AR vNext will concentrate on one major goal: Providing an easy to use API of the active record pattern. As a user, I want to call Save() or Find() from anywhere in my code without passing around session objects, DAOs or repositories.&lt;br /&gt;
&lt;h4&gt;
POCO Support&lt;/h4&gt;
The model should consist of plain object classes. The current AR requires inheritance for full support of the active record API. AR vNext will not even contain a base class for models. It will not require to use an attribute either. However, there is a drawback: Even with the full power of C# 4.0, implementing an empty interface is needed to streamline the experience.&lt;br /&gt;
&lt;h4&gt;
Testability&lt;/h4&gt;
Testing without database access is a must for TDD. Even the use of in-memory-databases requires initialization of the ORM which is far more problematic than getting data from an in-process-call to SQLite.&lt;br /&gt;
AR vNext will contain the necessary abstractions and native support for mocking and stubbing data access. Have your code use entity.Save() and fail the test if the wrong entity was saved… all without even loading the ORM’s assemblies.&lt;br /&gt;
&lt;h4&gt;
Single Unit-of-Work Concept&lt;/h4&gt;
A unit of work is mandatory unless you want to code demo apps. However, we don’t need separate concepts for web apps, service executables, GUIs and CLI programs. The single UoW must include transactions and allow both implicit and explicit usage.&lt;br /&gt;
&lt;h4&gt;
Reasonable Abstractions&lt;/h4&gt;
You might have noticed that I used ORM in the paragraphs above and not NHibernate. Well, while NH will be used and integrated as default ORM in vNext, I strive to abstract it out of the core API, so that it is possible to plug in other persistence frameworks in the future, which might be EF or RavenDB.&lt;br /&gt;
This abstraction will not used at any price. Don’t expect to change a configuration value to move from SQL to NoSQL or something similar. The goal is to factor out ORM-specific features in separate classes, so that you can remove the assembly references and have your compiler tell you what is required to adapt in order to use another ORM.&lt;br /&gt;
&lt;h4&gt;
When can I use it?&lt;/h4&gt;
Right now. &lt;br /&gt;
NuGet: Monastry.ActiveRecord-NHibernate&lt;br /&gt;
GIT: &lt;a href=&quot;https://github.com/mzywitza/Monastry.ActiveRecord&quot;&gt;https://github.com/mzywitza/Monastry.ActiveRecord&lt;/a&gt;</description><link>http://mortslikeus.blogspot.com/2011/09/big-rewrite-1.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3082379927146438123</guid><pubDate>Thu, 21 Jan 2010 04:05:00 +0000</pubDate><atom:updated>2010-01-21T04:05:14.022+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Build</category><category domain="http://www.blogger.com/atom/ns#">PowerShell</category><category domain="http://www.blogger.com/atom/ns#">PSake</category><category domain="http://www.blogger.com/atom/ns#">XML</category><title>Working with XML in PowerShell (2)</title><description>&lt;p&gt;In a previous post I wrote about examining XML with PowerShell. However, it is often not only necessary to peek into XML, but also to change it.&lt;/p&gt;  &lt;h4&gt;Updating XML with NAnt&lt;/h4&gt;  &lt;p&gt;In NAnt, it is possible to use &lt;a href=&quot;http://nant.sourceforge.net/nightly/latest/help/tasks/xmlpoke.html&quot; target=&quot;_blank&quot;&gt;xmlpoke&lt;/a&gt; to update XML in arbitrary files. The following NAnt snippet is taking from the build script of ActiveRecord’s test project and allows to adjust the database settings of the build machine.&lt;/p&gt;  &lt;div style=&quot;font-family: courier new; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;configure-tests&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;app.config&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;${build.dir}/${project::get-name()}.dll.config&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;xmlpoke&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;${app.config}&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;xpath&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;/configuration/activerecord/config/add[@key=&#39;connection.connection_string&#39;]/@value&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;${ar.connection.connection_string.1}&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In the snippet above I have omitted some 10 more xmlpoke tasks that all change values in the same application configuration file.&lt;/p&gt;

&lt;p&gt;How can this be done in PowerShell? The preceding post in this series showed how to assign the output of a command to a variable, so we only have to use a command that reads the contents of a file and assign the output to the variable:&lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;    $app_config = $project_path + &amp;quot;\build\net-3.5\debug\Castle.ActiveRecord.Tests.dll.config&amp;quot;
    [xml] $cfg = Get-Content $app_config&lt;/pre&gt;

&lt;p&gt;Now we have the XML to update available as an instance of XmlDocument and the full power of .NET at our hands to manipulate it. When we just had to traverse a path to change our XML, we could simply use dotted path. But if we have to differentiate siblings by its attribute values, the dotted path becomes unwieldy as we had to use a for-each-loop. But we can use XPath instead:&lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;    $cfg.SelectSingleNode(&amp;quot;/configuration/activerecord/config/add[@key=&#39;connection.connection_string&#39;]&amp;quot;).value = $myDatabaseConnString
    $cfg.SelectSingleNode(&amp;quot;/configuration/activerecord/config/add[@key=&#39;dialect&#39;]&amp;quot;).value = $myDatabaseDialect
    # ...&lt;/pre&gt;

&lt;p&gt;Finally, we have to save the updated XML. There is one caveat here: XmlDocuments don’t keep whitespace but normalize where it is deemed to be safe. But if we change generated files instead of manually edited ones, this is only a minor nuisance. &lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;    $cfg.Save($app_config)   &lt;/pre&gt;

&lt;p&gt;The full script is shown below. As before it is quite short compared to the NAnt XML script.&lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;properties {
    [string] $project_path = &amp;quot;C:\dev\castle\SVN\ActiveRecord&amp;quot;
    $myDatabaseConnString = &amp;quot;PSDBCFG&amp;quot;
    $myDatabaseDialect = &amp;quot;PSDBDIALECT&amp;quot;
}

task default -depends configure_tests

task configure_tests {
    $app_config = $project_path + &amp;quot;\build\net-3.5\debug\Castle.ActiveRecord.Tests.dll.config&amp;quot;
    [xml] $cfg = Get-Content $app_config
    $cfg.SelectSingleNode(&amp;quot;/configuration/activerecord/config/add[@key=&#39;connection.connection_string&#39;]&amp;quot;).value = $myDatabaseConnString
    $cfg.SelectSingleNode(&amp;quot;/configuration/activerecord/config/add[@key=&#39;dialect&#39;]&amp;quot;).value = $myDatabaseDialect
    # ...
    $cfg.Save($app_config)   
}&lt;/pre&gt;  </description><link>http://mortslikeus.blogspot.com/2010/01/working-with-xml-in-powershell-2.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3918120292076735347</guid><pubDate>Wed, 20 Jan 2010 05:56:00 +0000</pubDate><atom:updated>2010-01-20T05:56:31.544+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Build</category><category domain="http://www.blogger.com/atom/ns#">PowerShell</category><category domain="http://www.blogger.com/atom/ns#">PSake</category><category domain="http://www.blogger.com/atom/ns#">XML</category><title>Working with XML in PowerShell (1)</title><description>&lt;p&gt;During the last days, I started reading about PowerShell and PSake. While looking at the &lt;a href=&quot;http://nant.sourceforge.net/&quot; target=&quot;_blank&quot;&gt;NAnt&lt;/a&gt; scripts that I currently use, I recognized that among others the capability of examining and editing XML files is required.&lt;/p&gt;  &lt;h4&gt;Examining XML in NAnt&lt;/h4&gt;  &lt;p&gt;In NAnt, inspecting XML is done with the &lt;a href=&quot;http://nant.sourceforge.net/nightly/latest/help/tasks/xmlpeek.html&quot; target=&quot;_blank&quot;&gt;xmlpeek&lt;/a&gt;-task. It takes a file name, an XPath and a property name to fill with the result.&lt;/p&gt;  &lt;p&gt;One of the uses of xmlpeek is to find out the current revision of a code base, for example to set the private part of the version number with it. In the Castle Project’s build script this is done this way:&lt;/p&gt;  &lt;div style=&quot;font-family: courier new; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;common.find-svninfo&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!--&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; For adding SVN revision to builds &lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;svn.revision&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;overwrite&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!--&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt; try to update the revision &lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;exec&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;program&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;svn&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;commandline&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&#39;&lt;span style=&quot;color: blue&quot;&gt;info &amp;quot;${project::get-base-directory()}&amp;quot; --xml&lt;/span&gt;&#39;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;output&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;_revision.xml&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;failonerror&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;xmlpeek&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;_revision.xml&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;xpath&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;/info/entry/@revision&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;property&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;svn.revision&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;failonerror&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;_revision.xml&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;failonerror&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;INFO: Using Subversion revision number: ${svn.revision}&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;target&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So while this is quite a clever solution to find out the projects current revision, it has some drawbacks, such as being nearly 20 lines of code and that it uses a temporary file. But it does the job, reading the revision from the project folder.&lt;/p&gt;

&lt;p&gt;Examining XML in PowerShell&lt;/p&gt;

&lt;p&gt;PowerShell treats XML as a first class type and also has some shortcuts available. If we take a look at the result of svn info, we see that it is thankfully simple:&lt;/p&gt;

&lt;div style=&quot;font-family: courier new; background: white; color: black; font-size: 10pt&quot;&gt;
  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;xml&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;entry&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;dir&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;.&lt;/span&gt;&amp;quot;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style=&quot;color: red&quot;&gt;revision&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;6536&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;...&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;entry&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #a31515&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And because we can traverse XML nodes and attributes in PowerShell like object properties, it is possible to get the revision number even without an XPath expression.&lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;$revision = $rev_xml.info.entry.revision&lt;/pre&gt;

&lt;p&gt;So now it is only necessary to fill the $rev_xml variable with the output of the svn info command. The NAnt script does this using a temporary file but PowerShell allows to assign the standard output of a command line program directly to a variable:&lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;$rev_xml = svn.exe info --xml &lt;/pre&gt;

&lt;p&gt;But PowerShell treats the output of such a program as an array of objects, in this case strings. We have to hint PowerShell that what we want is an XMLDocument instead of an array of strings:&amp;#160; &lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;[xml] $rev_xml = svn.exe info --xml &lt;/pre&gt;

&lt;p&gt;That’s all. We now only have to put this together into a PSake build script for testing and reference. &lt;/p&gt;

&lt;pre class=&quot;brush: ps&quot;&gt;properties {
    [string] $project_path = &amp;quot;C:\dev\castle\SVN\ActiveRecord&amp;quot;
    $revision = 0
}

task default -depends get_revision
task get_revision {
    [xml] $rev_xml = svn.exe info $project_path --xml 
    $revision = $rev_xml.info.entry.revision
    &amp;quot;INFO: Using Subversion revision number: $revision&amp;quot;
}&lt;/pre&gt;

&lt;p&gt;This whole script is shorter than the snippet of NAnt script I’ve shown at the beginning. Taking only the relevant work, 5 lines of PS script replace 15 lines of NAnt XML. &lt;/p&gt;

&lt;p&gt;The script of course ignores the fact that getting the revision number should not be a task but rather a function that is called by a build task’s precondition for example. I will get back this in a while in another post.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2010/01/working-with-xml-in-powershell-1.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3629002570292221367</guid><pubDate>Thu, 14 Jan 2010 06:05:00 +0000</pubDate><atom:updated>2010-01-14T06:05:50.410+00:00</atom:updated><title>ActiveRecord 2.1 released</title><description>&lt;p&gt;Yesterday was ActiveRecord 2.1 released. The binaries can be downloaded on &lt;a href=&quot;https://sourceforge.net/projects/castleproject/files/ActiveRecord/2.1/AR%202.1.zip/download&quot; target=&quot;_blank&quot;&gt;SourceForge&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Most of the new functionalities in this release were contributed by &lt;a href=&quot;http://kozmic.pl/&quot; target=&quot;_blank&quot;&gt;Krzysztof Kozmic&lt;/a&gt;, a fellow castle committer, who was a great help to get this release out. More thanks go out to the &lt;a href=&quot;http://www.hornget.net/packages/&quot; target=&quot;_blank&quot;&gt;HornGet&lt;/a&gt; team, whose efforts took a lot of work out of the release process. Finally, I want to thank all contributors for patches and spotting bugs.&lt;/p&gt;  &lt;p&gt;So now what is new in that release?&lt;/p&gt;  &lt;h4&gt;Updated Dependencies&lt;/h4&gt;  &lt;p&gt;Castle.Core and Castle.DynamicProxy were updated to their newest releases (1.2 and 2.2 resp.).&lt;/p&gt;  &lt;p&gt;NHibernate has been updated to the last stable version 2.1.4 and compiled against the new Castle libraries.&lt;/p&gt;  &lt;p&gt;NHibernate.Linq and NHibernate.Search were compiled against NHibernate 2.1.4.&lt;/p&gt;  &lt;p&gt;Default configuration feature&lt;/p&gt;  &lt;p&gt;This new feature allows to skip all of the &amp;lt;add/&amp;gt;-tags from your configuration if you are only using the database’s default values. In this case your config will be reduced to:&lt;/p&gt;  &lt;pre&gt;&amp;lt;activerecord&amp;gt;
    &amp;lt;config db=&amp;quot;MsSqlServer2005&amp;quot; csn=&amp;quot;MyConnectionStringName&amp;quot;/&amp;gt;
&amp;lt;/activerecord&amp;gt;&lt;/pre&gt;

&lt;p&gt;The default configurations are available for most databases.&lt;/p&gt;

&lt;h4&gt;Inferring PrimaryKeyType from property type&lt;/h4&gt;

&lt;p&gt;Inspired by FluentNH, ActiveRecord now infers the PrimaryKeyType from the key’s property type:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;For Guid PrimaryKeyType.GuidComb is used &lt;/li&gt;

  &lt;li&gt;For string PrimaryKeyType.Assigned is used &lt;/li&gt;

  &lt;li&gt;All others default to PrimaryKeyType.Native as before. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Support for backfield and readonly properties&lt;/h4&gt;

&lt;p&gt;These property accessors are now available in ActiveRecord. Especially readonly is interesting, it allows to store values computed by the entities in the database and is therefore the complement to a computed table column.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2010/01/activerecord-21-released.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3747472515957452421</guid><pubDate>Sat, 01 Aug 2009 14:39:00 +0000</pubDate><atom:updated>2009-08-01T15:39:45.703+01:00</atom:updated><title>ActiveRecord 2.0</title><description>&lt;p&gt;Finally it’s final. I just created the ActiveRecord 2.0 zipfile.&lt;/p&gt;  &lt;p&gt;It can be downloaded at &lt;a href=&quot;https://sourceforge.net/projects/castleproject/files/&quot; target=&quot;_blank&quot;&gt;SourceForge&lt;/a&gt;. This release includes the NHLinq 1.0 release.&lt;/p&gt;  &lt;p&gt;Have Fun!&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/08/activerecord-20.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-33601026210331306</guid><pubDate>Wed, 29 Jul 2009 06:15:00 +0000</pubDate><atom:updated>2009-07-29T07:15:34.661+01:00</atom:updated><title>ActiveRecord Fluent Configuration</title><description>&lt;p&gt;Earlier this morning I committed a first spike of code to the actual (post 2.0) trunk of ActiveRecord. This fluent configuration shows a lot of features I am planning for 2.x releases.&lt;/p&gt;  &lt;p&gt;Let’s take a look at the new syntax. This one is for ActiveRecord itself and mere syntactic sugar:&lt;/p&gt;  &lt;div style=&quot;font-family: consolas; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: #2b91af&quot;&gt;IActiveRecordConfiguration&lt;/span&gt; configuration = &lt;span style=&quot;color: #2b91af&quot;&gt;Configure&lt;/span&gt;.ActiveRecord&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ForWeb()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Flush(&lt;span style=&quot;color: #2b91af&quot;&gt;DefaultFlushType&lt;/span&gt;.Leave)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .UseThreadScopeInfo&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;SampleThreadScopeInfo&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .UseSessionFactoryHolder&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;SampleSessionFactoryHolder&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MakeLazyByDefault()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .VerifyModels()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .RegisterSearch();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The following code is however more interesting. It does not only show how AR is currently configured, but also which features will become available soon:&lt;/p&gt;  &lt;div style=&quot;font-family: consolas; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: #2b91af&quot;&gt;IStorageConfiguration&lt;/span&gt; configuration = &lt;span style=&quot;color: #2b91af&quot;&gt;Configure&lt;/span&gt;.Storage&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .For&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .AllOtherTypes()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MappedBy(&lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;XmlNhibernateMapping&lt;/span&gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .InAssemblyOf&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;OneOfMyEntities&lt;/span&gt;&amp;gt;())&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .As&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ConnectionStringName(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;a_string&amp;quot;&lt;/span&gt;)&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Driver&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;SqlClientDriver&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ConnectionProvider&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;DriverConnectionProvider&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Dialect&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;MsSql2005Dialect&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ProxiedBy&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;ProxyFactoryFactory&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ShowSql();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;The first thing to note is the interface IStorageConfiguration. Each storage configuration will be used to create a NHibernate SessionFactory.&lt;/p&gt;  &lt;p&gt;The storage configuration consists of two parts: The database configuration is syntactic sugar for the current NHibernate configuration strings, which are a pain in the neck especially if you need to declare types.&lt;/p&gt;  &lt;p&gt;The more interesting part is the storage type selection. The part begins in line 2 by using the For-property. The storage type selection allows you to specify which types should use the session factory created by the storage configuration and how they are mapped.&lt;/p&gt;  &lt;p&gt;The selection above contains all classes that are not explicitly added to another storage configuration (line 3) and it says that these types are mapped using classic NHibernate mapping files (line 4) which should be loaded from a given assembly (line 5).&lt;/p&gt;  &lt;p&gt;Line 6 finally switches back to the storage configuration.&lt;/p&gt;  &lt;h4&gt;Storage Type Selections&lt;/h4&gt;  &lt;p&gt;The storage type selection shown above is effectively a specification pattern for types. Its existence shows to consequences for future versions of ActiveRecord:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;You can distribute your classes among multiple databases without the need of a common abstract baseclass. It will be possible to select the types for a storage by namespace, assembly, supertype, interfaces implemented or simply by enumerating them in the storage type selection. &lt;/li&gt;    &lt;li&gt;ActiveRecord attributes will be only one option to map persistent types. Types mapped by HBM files or Fluent NHibernate will become first class citizens of ActiveRecord. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The specification patternfor storage type selection allows more complex combinations than currently shown. Here is another example:&lt;/p&gt;  &lt;div style=&quot;font-family: consolas; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: #2b91af&quot;&gt;IStorageConfiguration&lt;/span&gt; auditConfig = &lt;span style=&quot;color: #2b91af&quot;&gt;Configure&lt;/span&gt;.Storage&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .For&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .SubtypesOf&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;AuditType&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .InNamespaceOf&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;DefaultAuditorType&lt;/span&gt;&amp;gt;() &lt;span style=&quot;color: green&quot;&gt;// logical and&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MappedBy(&lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;FluentNHibernateMapping&lt;/span&gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .InAssemblyOf&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;MyMappingClass&lt;/span&gt;&amp;gt;())&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .And &lt;span style=&quot;color: green&quot;&gt;// Logical or - we start the next StorageTypeSelection&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .TypesInAssemblyOf&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;MessagingImpl&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: green&quot;&gt;// No MappedBy defaults to ActiveRecord attributes&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .As&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .DefaultsFor&amp;lt;&lt;span style=&quot;color: #2b91af&quot;&gt;MsSqlServer2000Configuration&lt;/span&gt;&amp;gt;()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .ConnectionString(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;server=bla;...&amp;quot;&lt;/span&gt;);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Multiple selections can be created by using the And-property (line 7). Since the storage configuration holds an arbitrary number of storage type selections, this allows for a logical-or-construct. It also allows mixing different mapping types. In the example the first selection is mapped with Fluent Nhibernate (lines 5-6) and the second one with ActiveRecord attributes (line 9).&lt;/p&gt;  &lt;p&gt;It is also possible to narrow down type selections by adding multiple specifications to a single type selection (lines 3 and 4). This means that only types are selected that satisfy all specifications. In the example only types are selected that inherit from AuditType and are in the same namespace as DefaultAuditorType.&lt;/p&gt;  &lt;h4&gt;Storage Configuration&lt;/h4&gt;  &lt;p&gt;The storage configuration (where the database is configured) is not yet as clearly defined as the storage type selection.&lt;/p&gt;  &lt;p&gt;But it will contain default values for most database systems, a templating mechanism and special subconfigurations for fluently defining behaviour needed only occasionally, such as NHibernate Search configurations.&lt;/p&gt;  &lt;h4&gt;Does this work yet?&lt;/h4&gt;  &lt;p&gt;No. I just implemented enough to compile and run some simple tests. The features shown above will go into AR 2.1 and AR 2.2.&lt;/p&gt;  &lt;p&gt;This article is mainly a showcase for the planned functionality. Suggestions, critic and patches are always welcome.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/07/activerecord-fluent-configuration.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-8599820775955286460</guid><pubDate>Tue, 21 Jul 2009 16:01:00 +0000</pubDate><atom:updated>2009-07-21T17:01:57.399+01:00</atom:updated><title>ActiveRecord Release Candidate</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;RC 1 of ActiveRecord 2.0 is now available on &lt;a href=&quot;https://sourceforge.net/projects/castleproject/files/ActiveRecord/ActiveRecord2.0RC1.zip/download&quot; target=&quot;_blank&quot;&gt;SourceForge&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Unless serious bugs are found within, this version will be released as ActiveRecord 2.0 RTM on August, 1st.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/07/activerecord-release-candidate.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-7266478832103500571</guid><pubDate>Tue, 14 Jul 2009 17:36:00 +0000</pubDate><atom:updated>2009-07-14T18:36:21.421+01:00</atom:updated><title>German Blog reactivated</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;My german blog is &lt;a href=&quot;http://dotnetanders.blogspot.com/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/07/german-blog-reactivated.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-96796567336953484</guid><pubDate>Tue, 14 Jul 2009 17:03:00 +0000</pubDate><atom:updated>2009-07-14T18:03:37.621+01:00</atom:updated><title>ActiveRecord Beta 1 released</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The first beta of ActiveRecord 2.0 has been released last weekend. You can get it from &lt;a href=&quot;http://sourceforge.net/projects/castleproject/files/ActiveRecord/ActiveRecord2.0Beta1.zip/download&quot; target=&quot;_blank&quot;&gt;Sourceforge&lt;/a&gt;. &lt;/p&gt;  &lt;h4&gt;Changes&lt;/h4&gt;  &lt;p&gt;Beta 1 took about two months to complete, mostly due to the number of last minute additions to the 2.0 release. The highlights are:&lt;/p&gt;  &lt;h5&gt;In-Memory-Testing&lt;/h5&gt;  &lt;p&gt;It’s now possible to test your schema without hitting a database. Inherit from our base class to specify your favorite framework’s infrastructure and the classes/assemblies to test:&lt;/p&gt;  &lt;div style=&quot;font-family: consolas; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;TestBase&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;InMemoryTest&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Type&lt;/span&gt;[] GetTypes()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; [] {&lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt;(&lt;span style=&quot;color: #2b91af&quot;&gt;Blog&lt;/span&gt;), &lt;span style=&quot;color: blue&quot;&gt;typeof&lt;/span&gt;(&lt;span style=&quot;color: #2b91af&quot;&gt;Post&lt;/span&gt;)};&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;SetUp&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; SetUp()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;base&lt;/span&gt;.SetUp();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;TearDown&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 15&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; TearDown()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 16&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 17&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;base&lt;/span&gt;.TearDown();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 18&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 19&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 20&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;, &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;&amp;gt; GetProperties()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 21&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 22&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;, &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;&amp;gt;() { {&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;show_sql&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;} };&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 23&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 24&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;You can then simply create tests that don’t need a database:&lt;/p&gt;  &lt;div style=&quot;font-family: consolas; background: white; color: black; font-size: 10pt&quot;&gt;   &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 1&lt;/span&gt; [&lt;span style=&quot;color: #2b91af&quot;&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 2&lt;/span&gt;&amp;#160;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;CRUDTests&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;TestBase&lt;/span&gt;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 3&lt;/span&gt; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 4&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;Test&lt;/span&gt;]&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 5&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Create()&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 6&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 7&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; blog = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Blog&lt;/span&gt; { Name = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Blog&amp;quot;&lt;/span&gt; };&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 8&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; blog.Save();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160;&amp;#160; 9&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 10&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;var&lt;/span&gt; post = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Post&lt;/span&gt; { Title = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Post&amp;quot;&lt;/span&gt;, Blog = blog };&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 11&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; blog.Posts.Add(post);&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 12&lt;/span&gt;&amp;#160;&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 13&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; blog.Save();&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 14&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: #2b91af&quot;&gt;&amp;#160;&amp;#160; 15&lt;/span&gt; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Note: The tests shown above have no app.config altogether! &lt;/p&gt;  &lt;h5&gt;Basic LINQ Support&lt;/h5&gt;  &lt;p&gt;The formerly contrib project Castle.ActiveRecord.Linq has been added to ActiveRecord. &lt;/p&gt;  &lt;p&gt;Please note that the underlying NHLinq implementation is not fully implemented. Some features are still missing, i. e. joins between unrelated entities.&lt;/p&gt;  &lt;h5&gt;NHSearch integration&lt;/h5&gt;  &lt;p&gt;If you want to search your entities, NHSearch is the right project for you. The current release simplifies usage within ActiveRecord by registering the listeners for you when you add searchable=”true” to your ActiveRecord-configuration.&lt;/p&gt;  &lt;p&gt;More on using NHSearch can be found on this &lt;a href=&quot;http://using.castleproject.org/display/AR/Using+NHibernate.Search+with+ActiveRecord&quot; target=&quot;_blank&quot;&gt;wiki page&lt;/a&gt;&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/07/activerecord-beta-1-released.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-1645768237380222660</guid><pubDate>Fri, 05 Jun 2009 16:58:00 +0000</pubDate><atom:updated>2009-06-05T17:58:18.907+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">ActiveRecord</category><title>Understand ActiveRecord mapping: Collections of simple objects</title><description>&lt;p&gt;Recently I had a post in the Castle user’s group about mapping a collection of enums with ActiveRecord. Since I know it’s just as mapping other simple types, I only referred to the documentation of the Element and ElementType properties of the HasMany attribute. &lt;/p&gt;  &lt;p&gt;But, it turned out it is not really clear to many how to map a collection of simple values using HasMany. Therefore I decided to prepare an explanatory post, which is what you are reading now.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Mapping Basics&lt;/h4&gt;  &lt;p&gt;The problem: I want to hold a collection of enum values, say I have a status enum and want a history of that status persisted. Here is my model:&lt;/p&gt;  &lt;pre style=&quot;font-size: small&quot;&gt;namespace EnumMapping
{
	[ActiveRecord]
	public class Article
	{
		[PrimaryKey]
		public virtual int Id { get; set; }

		[Property]
		public virtual string Author { get; set; }

		[Property]
		public virtual string Title { get; set; }

		[Property]
		public virtual Status CurrentStatus { get;set;}

		[HasMany(...)]
		public virtual IList&lt;status&gt; StatusHistory
		{
			get { return statusHistory; }
			set { statusHistory = value; }
		}
		private IList&lt;status&gt; statusHistory = new List&lt;status&gt;();

	}

	public enum Status
	{
		None, Planned, InWriting, InEditing, Released 
	}
}&lt;/pre&gt;

&lt;p&gt;The ellipsis in the HasMany attribute is by design. I will work out in this post what you have to put here, so I let it out to make you understand the post, and not just read the code and copy and paste it.&lt;/p&gt;

&lt;p&gt;To understand what information ActiveRecord requires to map this collection, we first will take a look into how these collections are saved in the database:&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW0rKHSNbSW_YgdSOybQaYQv1gP4W240M8WfWBsgU1a-0VU1hrWOzawucGqko6HukeXv6j2hICOvxwdmgIbQsrO3fOoD_S6vhkMEx9SiefF6Nxq06FlOjBY2YXnRW3K-1JUCpKfKdSL2w/?imgmax=800&quot; width=&quot;465&quot; height=&quot;166&quot; /&gt; &lt;/p&gt;

&lt;p&gt;As expected, we have to tables. The Article table stores all the simple properties, but it cannot store collections. In a relational model, collections are always modeled by foreign key relations. That means we need a second table that stores both the values and the link to the article in question. &lt;/p&gt;

&lt;p&gt;Note: You might have noticed that the StatusHistory table does not have a primary key. This is because of the bag semantics we currently have for this collection. More efficient semantics are shown later.&lt;/p&gt;

&lt;p&gt;Looking at the StatusHistory table again, we see what we have to tell ActiveRecord to fetch the values for us and populate our List:&lt;/p&gt;

&lt;h5&gt;What is the table’s name? &lt;/h5&gt;

&lt;p&gt;&amp;#160;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvXvhX5jQ6jtt-IhE_OHq87T4R4nN0Q_SPsQgvDdqHds2oOn4ToAhSw0YlPejxAzg-_tZXEjVbHW5NmxIsCXpAWUd2JKkfLD5qxiPEwy1k4j2PNM9GEtLLB9AiZtpEIELDpr8K2l4O2D0/?imgmax=800&quot; width=&quot;221&quot; height=&quot;111&quot; /&gt; &lt;/p&gt;

&lt;p&gt;We take that name and put it into the respective property of the HasMany attribute:&lt;/p&gt;

&lt;pre style=&quot;font-size: small&quot;&gt;[HasMany(Table=&amp;quot;StatusHistory&amp;quot;,
	...)]
public virtual IList&lt;status&gt; StatusHistory {...}&lt;/pre&gt;

&lt;p&gt;As you can see from the code, we are not through yet.&lt;/p&gt;

&lt;h5&gt;Which column refers to the article?&lt;/h5&gt;

&lt;p&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOGBTHW-vPzBt5nv9JY5B_CFDe9taPxiOw6iEtPJpTS5GfcBxfJGHEIPSnYK-03XpQ5wdEu8tnsLludiGb7_6G0pX8MZXKZtOnu2l1nxbeDSUXs83UD0PBIdyHoFvrPP0DNL9WZxjK0Co/?imgmax=800&quot; width=&quot;221&quot; height=&quot;111&quot; /&gt;&lt;/p&gt;

&lt;pre style=&quot;font-size: small&quot;&gt;[HasMany(Table = &amp;quot;StatusHistory&amp;quot;,
	ColumnKey = &amp;quot;article&amp;quot;,
	...)]
public virtual IList&lt;status&gt; StatusHistory {...}&lt;/pre&gt;

&lt;h5&gt;Which column holds the value?&lt;/h5&gt;

&lt;p&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAwKSE15xq3ghqQ-UTD88CSoorIgDo780FLP9hhpuJoA4aCZZUa1uElkPzfVc-KNq-Pvbl3OiTMsDgge_R1C_aJNKyHhyphenhyphenIwC1v2h8PEHFVKnh_X1W26Lr0ZsDLfPSZRsAUTI-pq46srgA/?imgmax=800&quot; width=&quot;221&quot; height=&quot;111&quot; /&gt;&lt;/p&gt;

&lt;pre style=&quot;font-size: small&quot;&gt;[HasMany(Table = &amp;quot;StatusHistory&amp;quot;,
	ColumnKey = &amp;quot;article&amp;quot;,
	Element = &amp;quot;status&amp;quot;,
	...)]
public virtual IList&lt;status&gt; StatusHistory {...}&lt;/pre&gt;

&lt;p&gt;What? There is even more to specify even though we already have all columns included? &lt;/p&gt;

&lt;p&gt;Yes. ActiveRecord also needs to know the types of the columns. The foreign key’s column can be inferred from the types primary key, but we need to know what type the value actually has.&lt;/p&gt;

&lt;pre style=&quot;font-size: small&quot;&gt;[HasMany(Table = &amp;quot;StatusHistory&amp;quot;,
	ColumnKey = &amp;quot;article&amp;quot;,
	Element = &amp;quot;status&amp;quot;,
	ElementType = typeof(Status))]
public virtual IList&lt;status&gt; StatusHistory {...}&lt;/pre&gt;

&lt;p&gt;That’s it (for now). We now can take that mapping and go for the database.&lt;/p&gt;

&lt;h4&gt;The Collection Types&lt;/h4&gt;

&lt;p&gt;I already mentioned the missing primary key on the collection’s table and that the collection uses bag semantics. So what are these semantics? There are a few available in ActiveRecord:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Bag: All elements are unordered and may appear multiple. Total chaos. &lt;/li&gt;

  &lt;li&gt;Set: The elements are unordered, but each one can be present only once. This is the typical relational collection. &lt;/li&gt;

  &lt;li&gt;List: Elements are ordered and may be there multiple times. &lt;/li&gt;

  &lt;li&gt;Dictionary: Elements have a key that identifies them. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the collection type is not specified, ActiveRecord assumes that you want bag semantics. After all, that’s what a collection is. Put things in there and get them out. No one cares for ordering or duplication.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is quite inefficient with databases:Items in a bag cannot be updated individually. Recall that there is no primary key in the collection table. Since the value can be in the collection more than once, an update or delete would effect all rows with that value. As a result, every time the collection is updated, it is completely deleted from the DB and inserted again.&lt;/p&gt;

&lt;p&gt;To get around this, we could use a set. However, this requires us to use another Collection type, Set&amp;lt;Status&amp;gt; from Iesi.Collections. So instead of a set, I will use a list semantic. This is suitable, because a status history has an implicit ordering.&lt;/p&gt;

&lt;p&gt;To use the list semantic, the schema must be changed first, because an index column is needed to store the list’s index.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitgYEUdfHdalki4-JrGZ9m2xsX-GyHXh8qLCRKSF_PCTkn_R2sAxABBYyRUgqIl0sDZ1BHDgpbMFCQ3kkCAIQlXADWD_v8bXuCzn4HTlq1OTso4rnlbWTEBqSGvpoJ0Xgw4LrXRjrdbOI/?imgmax=800&quot; width=&quot;474&quot; height=&quot;141&quot; /&gt; &lt;/p&gt;

&lt;p&gt;We now don’t have only an additional column, we also have a nice primary key consisting of the combination of the article’s id and the list’s index. So every value in the list can now be updated individually. &lt;/p&gt;

&lt;p&gt;Now we must tell ActiveRecord to use list semantics and how to find the index:&lt;/p&gt;

&lt;pre style=&quot;font-size: small&quot;&gt;[HasMany(Table = &amp;quot;StatusHistory&amp;quot;,
	ColumnKey = &amp;quot;article&amp;quot;,
	Element = &amp;quot;status&amp;quot;,
	ElementType = typeof(Status),
	RelationType = RelationType.List,
	Index = &amp;quot;idx&amp;quot;)]
public virtual IList&lt;status&gt; StatusHistory {...}&lt;/pre&gt;

&lt;p&gt;That’s it.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/06/understand-activerecord-mapping.html</link><author>noreply@blogger.com (Anonymous)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW0rKHSNbSW_YgdSOybQaYQv1gP4W240M8WfWBsgU1a-0VU1hrWOzawucGqko6HukeXv6j2hICOvxwdmgIbQsrO3fOoD_S6vhkMEx9SiefF6Nxq06FlOjBY2YXnRW3K-1JUCpKfKdSL2w/s72-c?imgmax=800" height="72" width="72"/><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-7765754632523154898</guid><pubDate>Fri, 08 May 2009 21:01:00 +0000</pubDate><atom:updated>2009-05-08T22:01:36.127+01:00</atom:updated><title>ActiveRecord Alpha Release</title><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You will have already heard it: It is release season in the Castle’s domain.&lt;/p&gt;  &lt;p&gt;The newest release is ActiveRecord 2.0 Alpha 1, recently uploaded to &lt;a title=&quot;http://groups.google.com/group/castle-project-users/web/ActiveRecord2.0Alpha1.zip&quot; href=&quot;http://groups.google.com/group/castle-project-users/web/ActiveRecord2.0Alpha1.zip&quot;&gt;http://groups.google.com/group/castle-project-users/web/ActiveRecord2.0Alpha1.zip&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This release includes a lot of breaking changes with regard to the last release, ActiveRecord 1.0 RC3, which is the main reason for going through a new complete release cycle starting with alpha releases.&lt;/p&gt;  &lt;p&gt;This release includes a move from NHibernate 1.2 to NHibernate 2.1. Please make sure to read the &lt;a href=&quot;http://groups.google.com/group/castle-project-users/web/AR2.0Alpha1_Changes.txt&quot; target=&quot;_blank&quot;&gt;Changes.txt&lt;/a&gt; and start testing early. &lt;/p&gt;  &lt;p&gt;Bugs can be posted at &lt;a href=&quot;http://support.castleproject.org/projects/AR/issues/new&quot; target=&quot;_blank&quot;&gt;donjon&lt;/a&gt; and last-minute-features can be suggested at &lt;a href=&quot;http://castle.uservoice.com&quot; target=&quot;_blank&quot;&gt;UserVoice&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;There is no feature freeze yet: All suggestions on &lt;a href=&quot;http://castle.uservoice.com&quot; target=&quot;_blank&quot;&gt;UserVoice&lt;/a&gt; that get 15+ votes there until May 17th, will be considered for addition in Alpha 2. If no features take this hurdle, I will move forward to Beta 1.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/05/activerecord-alpha-release.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3383341144707560436</guid><pubDate>Thu, 23 Apr 2009 09:06:00 +0000</pubDate><atom:updated>2009-04-23T10:06:12.432+01:00</atom:updated><title>Understanding ActiveRecord Sessions 2</title><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;This article series deals with the internal session keeping of Castle ActiveRecord. This installment introduces the concept of a scope and how scopes are used within ActiveRecord.&lt;/p&gt;  &lt;h3&gt;Introducing Scopes&lt;/h3&gt;  &lt;p&gt;Having a session per database call is suboptimal. There is no chance to use transactions, which is a showstopper for most serious uses. Another issue is lazy loading: Lazy loading prevents NHibernate from loading large collections until they are requested, avoiding to load unnecessary data. Lazy loading is however only possible when done within a single session.&lt;/p&gt;  &lt;p&gt;Castle ActiveRecord uses scopes to overcome this. A scope represents a single unit of work. It is not necessarily a single transaction, but may span multiple transactions. Prior to NHibernate 2.0, when transactions were not mandatory, scopes did not even have to support transactions.&lt;/p&gt;  &lt;p&gt;The scopes that are part of the ActiveRecord package do always share a single session that is used for all persistance related calls. However, it is possible to implement a scope that uses a new session, but the changed semantic should be clearly communicated in such a case.&lt;/p&gt;  &lt;h4&gt;Localizing Scopes&lt;/h4&gt;  &lt;p&gt;In order to access scopes without holding a reference to the object, they stored in thread static stacks. The central interface for this is IThreadScopeInfo, which is implemented by various classes to cover different situations such as web applications. WebThreadScopeInfo for example uses a HttpContext for storing the scopes while the default ThreadScopeInfo implementation uses a thread static field.&lt;/p&gt;  &lt;p&gt;In order to acquire the current IThreadScopeInfo implementation, ThreadScopeAccessor can be used. This class is a singleton providing the current ScopeInfo under&lt;/p&gt;  &lt;pre&gt;public IThreadScopeInfo ScopeInfo&lt;/pre&gt;

&lt;p&gt;Additionally it acts a proxy to this scope, delegating calls to the scope info in the property above. This allows to access the current scope without keeping a field for it using&lt;/p&gt;

&lt;pre&gt;ThreadScopeAccessor.Instance.XXX();&lt;/pre&gt;

&lt;p&gt;where XXX is one of the methods defined in IThreadScopeInfo.&lt;/p&gt;

&lt;p&gt;With the IThreadScopeInfo available, the current scope can be requested by SessionFactoryHolder using the following methods:&lt;/p&gt;

&lt;pre&gt;ISessionScope GetRegisteredScope()
bool HasInitializedScope&lt;/pre&gt;

&lt;h4&gt;Scope Initialization&lt;/h4&gt;

&lt;p&gt;When a scope is created, it has no sessions stored at first. That is intentional. While the ActiveRecordStarter configures the ISessionFactoryHolder at startup, it cannot configure an arbitrary number of ISessionScope implementations.&lt;/p&gt;

&lt;p&gt;Therefore the initialization of scopes is implemented using a simple protocol between ISessionFactoryHolder and ISessionScope:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Upon creation, the ISessionScope registers itself with the current IThreadScopeInfo.&lt;/p&gt;

    &lt;pre&gt;void IThreadScopeInfo.RegisterScope(ISessionScope scope)&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;ISessionFactoryHolder fetches the scope the next time it has to deliver a session to the ActiveRecordBase methods.&lt;/p&gt;

    &lt;pre&gt;bool IThreadScopeInfo.HasInitializedScope
ISessionScope IThreadScopeInfo.GetRegisteredScope()&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;The ISessionFactoryHolder asks the ISessionScope whether it already has a suitable session stored. Scopes do not hold only one session. Due to different database connections by root type, they need to hold a dictionary of sessions. The scope doesn&#39;t know the key to the sessions because the key is provided by the ISessionFactoryHolder everytime a session is required.&lt;/p&gt;

    &lt;pre&gt;bool ISessionScope.IsKeyKnown(object key)&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;If there is a session registered with the scope, the session is requested and the protocol ends.&lt;/p&gt;

    &lt;pre&gt;ISession ISessionScope.GetSession(object key)&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;If there is no suitable session available the ISessionFactoryHolder asks the ISessionScope whether it accepts an existing session or if it wants to create its own session.&lt;/p&gt;

    &lt;pre&gt;bool ISessionScope.WantsToCreateTheSession&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;Depending on the answer to 5, the ISessionFactoryHolder either opens a session itself or provides a suitable ISessionFactory to the ISessionScope so that the session can be created by the scope itself.&lt;/p&gt;

    &lt;pre&gt;ISession ISessionScope.OpenSession(ISessionFactory sessionFactory, IInterceptor interceptor)&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;The session is registered with the ISessionScope by the holder. This is done regardless who in fact created the session.&lt;/p&gt;

    &lt;pre&gt;void ISessionScope.RegisterSession(object key, ISession session)&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;p&gt;The freshly registered session is fetched from the scope.&lt;/p&gt;

    &lt;pre&gt;ISession ISessionScope.GetSession(object key)&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;The different Scope Types&lt;/h4&gt;

&lt;p&gt;Scopes generelly have two attributes that describe there behaviour: by FlushAction and by SessionScopeType. The FlushAction controls whether changes are automatically flushed to the database. The SessionScopeType describes the behaviour of the scope in common, most important whether the scope supports transactions.&lt;/p&gt;

&lt;p&gt;If the FlushAction is defined as FlushAction.Never, no writing to the database will occur unless ISessionScope.Flush() is called by the using code. This behaviour gives full control to the using code, but requires it to control flushing. This is important: If the changes are not flushed, queries will still find an older state in the database although the entity has already changed.&lt;/p&gt;

&lt;p&gt;FlushAction.Auto instructs the NHibernate session to flush its first-level-cache whenever needed. That means that if the cache contains an unflushed change to an entity, the session will write those changes back before it runs a query against the entity&#39;s type.&lt;/p&gt;

&lt;p&gt;The SessionScopeType has four values:&lt;/p&gt;

&lt;pre&gt;SessionScopeType.Undefined
SessionScopeType.Simple
SessionScopeType.Transactional
SessionScopeType.Custom&lt;/pre&gt;

&lt;p&gt;Undefined should never be used; it is more an error state than a valid scope type. Simple and Transactional define whether the scope supports transactional behaviour. Custom can be used for own implementations that fall in between. An example would be a SessionScope that uses transactions only for specific sessions.&lt;/p&gt;

&lt;p&gt;The next part of the series will show how ActiveRecord usage differs when using a scope.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/04/understanding-activerecord-sessions-2.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-8902306299756615993</guid><pubDate>Tue, 21 Apr 2009 12:28:00 +0000</pubDate><atom:updated>2009-04-21T13:28:29.501+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ActiveRecord</category><category domain="http://www.blogger.com/atom/ns#">Sessions</category><title>Understanding ActiveRecord Sessions 1</title><description>&lt;p&gt;This article series deals with the internal session keeping of Castle ActiveRecord. It begins in explaining how sessions are managed within ActiveRecord and how the user can influence this behavior.&lt;/p&gt;  &lt;h3&gt;What happens when Save() is called?&lt;/h3&gt;  &lt;p&gt;The first part of our journey starts in &lt;em&gt;ActiveRecordBase&lt;/em&gt;. Whenever a method is called that requires a NHibernate session, it requests one from the following field:&lt;/p&gt;  &lt;pre&gt;protected internal static ISessionFactoryHolder holder;&lt;/pre&gt;

&lt;p&gt;Since that field is marked protected internal static, subclasses of &lt;em&gt;ActiveRecordBase&lt;/em&gt; can directly access it to acquire a session. This is done with the following methods:&lt;/p&gt;

&lt;pre&gt;ISession CreateSession(Type type);
void ReleaseSession(ISession session);
void FailSession(ISession session);&lt;/pre&gt;

&lt;p&gt;The first method requests a session from the &lt;em&gt;ISessionFactoryHolder&lt;/em&gt;, that can be used to issue calls to the session, such as &lt;em&gt;Save()&lt;/em&gt;, &lt;em&gt;Load()&lt;/em&gt; etc. After the operation was completed, &lt;em&gt;ReleaseSession&lt;/em&gt; must be called, preferably in a finally block.&lt;/p&gt;

&lt;p&gt;If an exception is raised from NHibernate, the session cannot be used anymore. The &lt;em&gt;ISessionFactoryHolder&lt;/em&gt; must be notified through the &lt;em&gt;FailSession&lt;/em&gt;-method.&lt;/p&gt;

&lt;p&gt;To further understand the inner workings of ActiveRecord, we need to look at the default implementation of &lt;em&gt;ISessionFactoryHolder&lt;/em&gt;, which is simply called &lt;em&gt;SessionFactoryHolder&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;SessionFactoryHolder&lt;/em&gt; keeps a dictionary which maps the configured ActiveRecord root types to &lt;em&gt;ISessionFactory&lt;/em&gt; instances. Whenever &lt;em&gt;CreateSession&lt;/em&gt; is called, it fetches the &lt;em&gt;ISessionFactory&lt;/em&gt; for that type and creates an &lt;em&gt;ISession&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When &lt;em&gt;ReleaseSession&lt;/em&gt; is called the session is flushed and disposed, closing any open connections. If you use the holder to acquire sessions directly, keep in mind that it is necessary to release them or you will get a resource leak. Database sessions are among the most critical resources with regard to leaks.&lt;/p&gt;

&lt;p&gt;If an exception is raised, the &lt;em&gt;FailSession&lt;/em&gt; method will clear the session so that it doesn&#39;t throw again when the session is released.&lt;/p&gt;

&lt;p&gt;When ActiveRecord is used without any scopes, all of this happens on a single call of any of the data retrieval or persistence methods (Save(), FindAll() etc.):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;ActiveRecordBase gets an ISession from the SessionFactoryHolder. ActiveRecordMediator simpy calls a static method on ActiveRecordBase, so there are no differences with respect to session handling. &lt;/li&gt;

  &lt;li&gt;ActiveRecordBase performs the desired database operation. &lt;/li&gt;

  &lt;li&gt;If there is no exception, ReleaseSession is called by ActiveRecordBase. In case of an exception, FailSession is called instead and the exception is rethrown. &lt;/li&gt;

  &lt;li&gt;SessionFactoryHolder closes the ISession instance. Upon the next call, a new session is created. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But what if we need to have a single session span multiple commands? This will be handled in the following articles when we talk about scopes.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/04/understanding-activerecord-sessions-1.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-4341296983401638212</guid><pubDate>Tue, 27 Jan 2009 12:14:00 +0000</pubDate><atom:updated>2009-01-27T12:14:39.294+00:00</atom:updated><title>Active Record and DDD</title><description>&lt;p&gt;One of the most fatal mistakes one can conduct when beginning with Domain-Driven Design is doubling Active Record types as domain entities. This does not include Castle ActiveRecord, but all frameworks that map classes and tables one-to-one, and to some extend even more flexible solutions like NHibernate.&lt;/p&gt;  &lt;h4&gt;How does it start?&lt;/h4&gt;  &lt;p&gt;This trap is usually hit by developing a data-driven applications using ActiveRecord as an ORM. There is nothing bad with the approach per se, and I&#39;m actually using it myself a lot. Let&#39;s see the following code taken from the Castle ActiveRecord GettingStarted section:&lt;/p&gt;  &lt;pre&gt;[ActiveRecord]
public class Blog : ActiveRecordBase&amp;lt;Blog&amp;gt;
{
	private int id;
	private String name;
	private String author;
	private IList&amp;lt;Post&amp;gt; posts = new List&amp;lt;Post&amp;gt;();

	public Blog()
	{
	}

	public Blog(String name)
	{
		this.name = name;
	}

	[PrimaryKey]
	public int Id
	{
		get { return id; }
		set { id = value; }
	}

	[Property]
	public String Name
	{
		get { return name; }
		set { name = value; }
	}

	[Property]
	public String Author
	{
		get { return author; }
		set { author = value; }
	}

	[HasMany(
		Table=&amp;quot;Posts&amp;quot;, ColumnKey=&amp;quot;blogid&amp;quot;, 
		Inverse=true, Cascade= ManyRelationCascadeEnum.AllDeleteOrphan)]
	public IList&amp;lt;Post&amp;gt; Posts
	{
		get { return posts; }
		set { posts = value; }
	}
}&lt;/pre&gt;

&lt;p&gt;This is straight forward data-driven code and there is nothing bad about it. Note that no business logic is embedded in the class. In the simple GettingStarted example, the logic is buried in the GUI, but in a real application you would perhaps use Transaction Scripts to encapsulate logic in objects.&lt;/p&gt;

&lt;h4&gt;Setting the trap&lt;/h4&gt;

&lt;p&gt;The programmer eventually reads Eric Evans great book or hears from a mailing list about DDD. He might remember that Castle ActiveRecord does not require a base class and removes it, using ActiveRecordMediator for database access.&lt;/p&gt;

&lt;p&gt;Now that there are only POCOs, our unwary programmer starts adding business logic to the ActiveRecord types. By that, he tries to encapsulate complexity within the &amp;quot;domain model&amp;quot;.&lt;/p&gt;

&lt;p&gt;But what has happened:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Most important, he violates the Single Responsibility Principle (SRP); the class is now responsible for multiple aspects:&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Storing data&lt;/li&gt;

    &lt;li&gt;Executing business logic&lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;In the first few iterations, business logic that was previously packed in one method is now cluttered over multiple classes. DDD&#39;s supple design promises to mitigate that but a design usually only becomes supple by a lot of refactoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The immediate result is big step backwards in maintainability. Over the long term, DDD will have a better maintainability, but you will need a lot of work to reach this state. By that time, the trap has already sprung...&lt;/p&gt;

&lt;h4&gt;The trap fires&lt;/h4&gt;

&lt;p&gt;For a while, all will be well. The programmer get accustomed to the code and does some changes. The code gets more complex and a bit unwieldy. Finally, the programmer needs a &amp;quot;break-through&amp;quot;; a big refactoring takes place to make the code more supple.&lt;/p&gt;

&lt;p&gt;Now, violating the SRP fires back: It is not possible to refactor the design without writing complex migration scripts for the database. Integration suddenly becomes an issue. However, the redesign is utterly needed because of the business logic embedded in the design.&lt;/p&gt;

&lt;p&gt;The typical outcome is that the redesign is put off until &amp;quot;there is more time&amp;quot;, or shorter: &amp;quot;never&amp;quot;. In the meanwhile, the code base is growing and getting more and more fragile.&lt;/p&gt;

&lt;h4&gt;How to recover?&lt;/h4&gt;

&lt;p&gt;The most important task in recovering from such a dilemma is deciding which approach will be used for the application. You can choose a data-driven approach or a domain-driven approach, but not both. &lt;/p&gt;

&lt;h5&gt;Using DDD&lt;/h5&gt;

&lt;p&gt;If the complexity of the domain mandates DDD, it is necessary to do it right. This means using the ActiveRecord types as a DAO/DTO layer and building a model upon it that contains the business logic. The model is then decoupled from the data structure. If the model is redesigned, the mapping code requires to adapt, not the structure of the data storage. If the storage structure changes, the mapping code changes and not the model.&lt;/p&gt;

&lt;p&gt;This is also the reason why it is possible to use NHibernate directly on a domain model: The NHibernate mapping files are mapping code, written in an XML-based DSL (and soon with a fluent API)&lt;/p&gt;

&lt;p&gt;So this is the other way out of the trap when using DDD. If you use Castle ActiveRecord, take the hbm-files created when using the debug switch and use NHibernate directly instead.&lt;/p&gt;

&lt;h5&gt;Using data-driven design&lt;/h5&gt;

&lt;p&gt;It is also possible to make a full turn. A domain of modest complexity that defines most of the business cases as sequential workflows and processes, will benefit from using a data-driven approach.&lt;/p&gt;

&lt;p&gt;The processes defined in the business domain can be modeled using the Transaction Script pattern and the Active Record model is exactly that: a pattern for accessing an underlying database. &lt;/p&gt;

&lt;h4&gt;On the &amp;quot;Anemic Model&amp;quot;&lt;/h4&gt;

&lt;p&gt;Many of the solutions above use a model that is disregarded as anemic by many. But whether a model is anemic, depends on responsibilities rather than on LOC.&lt;/p&gt;

&lt;p&gt;Thus an ActiveRecord-model is not anemic because it is responsible for accessing the data store. A DAO/DTO is part of the persistence layer and its responsibility is passing data around. By coincidence, it doesn&#39;t need any methods for this task, but it is not anemic.&lt;/p&gt;

&lt;p&gt;After all, violating the SRP is always worse than having an anemic model.&lt;/p&gt;

&lt;h4&gt;Disclaimer&lt;/h4&gt;

&lt;p&gt;The poor programmer who unwarily builds a trap who fired at himself was of course me.&lt;/p&gt;  </description><link>http://mortslikeus.blogspot.com/2009/01/active-record-and-ddd.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-8592927270395957004</guid><pubDate>Wed, 19 Mar 2008 15:30:00 +0000</pubDate><atom:updated>2008-03-19T14:37:24.194+00:00</atom:updated><title>Emulating MixIns with C#</title><description>One of the shortcomings of C# is the missing support of MixIns, which are a popular substitute for multiple inheritance especially in Ruby.
MixIns provide a way to put a common functionality in a separate classand use it in another class. That is still easy in C#, one can simply use inheritance. But, what will you do, when your classes are already inheriting from other classes? You won&#39;t want to break up your inheritance hierarchie for this, will you?

Using a MixIn, you can put a common functionality in a separate class and mix it into multiple classes, regardless of their inheritance hierarchy. The methods and properties of a MixIn-class are merged into the using classes&#39; interface and can also use the original classes members. That&#39;s the theory and what is possible in Ruby, but can it be achieved in C#?

If you need an example for MixIns, you might want to read the following blog post &lt;a href=&quot;http://www.juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/&quot;&gt;http://www.juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/&lt;/a&gt;. However, you don&#39;t need any Ruby knowledge for the remainder of my post.

Ok, what are the characteristics of a MixIn again:
&lt;ol&gt;
&lt;li&gt;Accessible via the using class&lt;/li&gt;
&lt;li&gt;Has access to the using class&#39; instance members&lt;/li&gt;
&lt;li&gt;Must not use inheritance&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Taking into account that C# is a statically and strongly typed compiled language, this is not possible at first glance. But, if all possibilities of C# are used, they can be fulfilled at least partially.&lt;/p&gt;&lt;p&gt;As an example, I will develop a MixIn that adds reduction-functionality to collections. Reduction is a functional programming concept means that the collection will be reduced (boiled down) to a scalar value using a user-specified delegate. Simple reductions are joining a collection of strings or adding up a collection of integers.&lt;/p&gt;&lt;p&gt;The following code shows how this can be implemented using a conventional static method:&lt;/p&gt;&lt;div style=&quot;BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;&quot;   &gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    1&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    2&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    3&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;namespace&lt;/span&gt; Example&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    4&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    5&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;delegate&lt;/span&gt; TItem &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;TItem&amp;gt;(&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    6&lt;/span&gt;         TItem firstItem, &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    7&lt;/span&gt;         TItem secondItem);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    8&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    9&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;Reduction&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   10&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   11&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;static&lt;/span&gt; TItem Reduce&amp;lt;TItem&amp;gt;(&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   12&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;IEnumerable&lt;/span&gt;&amp;lt;TItem&amp;gt; collection, &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   13&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;TItem&amp;gt; reduceFunction)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   14&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   15&lt;/span&gt;             TItem result = &lt;span style=&quot;color:blue;&quot;&gt;default&lt;/span&gt;(TItem);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   16&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;bool&lt;/span&gt; first = &lt;span style=&quot;color:blue;&quot;&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   17&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;foreach&lt;/span&gt; (TItem item &lt;span style=&quot;color:blue;&quot;&gt;in&lt;/span&gt; collection)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   18&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   19&lt;/span&gt;                 &lt;span style=&quot;color:blue;&quot;&gt;if&lt;/span&gt; (first)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   20&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   21&lt;/span&gt;                     result = item;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   22&lt;/span&gt;                     first = &lt;span style=&quot;color:blue;&quot;&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   23&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   24&lt;/span&gt;                 &lt;span style=&quot;color:blue;&quot;&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   25&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   26&lt;/span&gt;                     result = reduceFunction(result, item);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   27&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   28&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   29&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;return&lt;/span&gt; result;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   30&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   31&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   32&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
Now the question is, how can this functionality be implemented as a mixin. We will need at least to interfaces for this:
&lt;ul&gt;&lt;li&gt;An interface that allows the mixin access to the using class.&lt;/li&gt;&lt;li&gt;An external interface that allows a client to use the functionality provided by the mixins.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The code below shows how these are declared:&lt;/p&gt;
&lt;div style=&quot;BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;&quot;   &gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    1&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;namespace&lt;/span&gt; Mixin&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    2&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    3&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;delegate&lt;/span&gt; TItem &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;TItem&amp;gt;(&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    4&lt;/span&gt;         TItem firstItem, &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    5&lt;/span&gt;         TItem secondItem);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    6&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    7&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceClient&lt;/span&gt;&amp;lt;TItem&amp;gt; : &lt;span style=&quot;color:#2b91af;&quot;&gt;IEnumerable&lt;/span&gt;&amp;lt;TItem&amp;gt;{}&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    8&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    9&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceMixin&lt;/span&gt;&amp;lt;TItem&amp;gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   10&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   11&lt;/span&gt;         TItem Reduce(&lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;TItem&amp;gt; reduceFunction);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   12&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   13&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   14&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;interface&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;IWithReduce&lt;/span&gt;&amp;lt;TItem&amp;gt; : &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceClient&lt;/span&gt;&amp;lt;TItem&amp;gt;, &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceMixin&lt;/span&gt;&amp;lt;TItem&amp;gt; {}&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   15&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   16&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceMixin&lt;/span&gt;&amp;lt;TItem&amp;gt; : &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceMixin&lt;/span&gt;&amp;lt;TItem&amp;gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   17&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   18&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; ReduceMixin(&lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceClient&lt;/span&gt;&amp;lt;TItem&amp;gt; client)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   19&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   20&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;this&lt;/span&gt;.client = client;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   21&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   22&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   23&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceClient&lt;/span&gt;&amp;lt;TItem&amp;gt; client;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   24&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   25&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; TItem Reduce(&lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;TItem&amp;gt; reduceFunction)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   26&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   27&lt;/span&gt;             TItem result = &lt;span style=&quot;color:blue;&quot;&gt;default&lt;/span&gt;(TItem);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   28&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;bool&lt;/span&gt; first = &lt;span style=&quot;color:blue;&quot;&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   29&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;foreach&lt;/span&gt; (TItem item &lt;span style=&quot;color:blue;&quot;&gt;in&lt;/span&gt; client)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   30&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   31&lt;/span&gt;                 &lt;span style=&quot;color:blue;&quot;&gt;if&lt;/span&gt; (first)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   32&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   33&lt;/span&gt;                     result = item;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   34&lt;/span&gt;                     first = &lt;span style=&quot;color:blue;&quot;&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   35&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   36&lt;/span&gt;                 &lt;span style=&quot;color:blue;&quot;&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   37&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   38&lt;/span&gt;                     result = reduceFunction(result, item);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   39&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   40&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   41&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;return&lt;/span&gt; result;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   42&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   43&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   44&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Line 7 declares the interface that the mixin uses to access the using class (IReduceClient). This can be arbitrary complex, but in this case, we only need an enumeration, so I just inherited from IEnumerable. Line 9 declares the interface that is publicly used to access the mixin&#39;s functionality (IReduceMixin). IWithReduce on line 14 just brackets the other two interfaces, so that an using class can specify IWithReduce, which shows the intention better than using the two different interfaces.&lt;/p&gt;&lt;p&gt;The mixin class is shown on lines 16ff. It simply holds a reference to the client, a.k.a. the using class and the Reduce implementation shown above.&lt;/p&gt;&lt;p&gt;Now the problem is how can the mixin added to a client. The code below would be ideal, but won&#39;t work with C# 2.0:&lt;/p&gt;
&lt;div style=&quot;BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;&quot;   &gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    1&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;namespace&lt;/span&gt; Client&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    2&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    3&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style=&quot;color:#2b91af;&quot;&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style=&quot;color:#2b91af;&quot;&gt;IWithReduce&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    4&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    5&lt;/span&gt;         &lt;span style=&quot;color:green;&quot;&gt;// Won&#39;t work that way!&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    6&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    7&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Before I show a (naive) implementation, here is the test code for the whole thing, that shows how it is used:&lt;/p&gt;
&lt;div style=&quot;BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;&quot;   &gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    1&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;namespace&lt;/span&gt; Test&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    2&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    3&lt;/span&gt;     [&lt;span style=&quot;color:#2b91af;&quot;&gt;TestFixture&lt;/span&gt;]&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    4&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceTest&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    5&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    6&lt;/span&gt;         [Test]&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    7&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;void&lt;/span&gt; TestMixin()&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    8&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    9&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt;&amp;gt; rl = &lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   10&lt;/span&gt;             rl.AddRange(&lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt;[] {&lt;span style=&quot;color:#a31515;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color:#a31515;&quot;&gt;&quot;b&quot;&lt;/span&gt;, &lt;span style=&quot;color:#a31515;&quot;&gt;&quot;c&quot;&lt;/span&gt;});&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   11&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   12&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;IReduceMixin&lt;/span&gt;&amp;lt;&lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt;&amp;gt; reducable = rl;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   13&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style=&quot;color:#a31515;&quot;&gt;&quot;a,b,c&quot;&lt;/span&gt;, reducable.Reduce(&lt;span style=&quot;color:blue;&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt; s1, &lt;span style=&quot;color:blue;&quot;&gt;string&lt;/span&gt; s2) { &lt;span style=&quot;color:blue;&quot;&gt;return&lt;/span&gt; s1 + &lt;span style=&quot;color:#a31515;&quot;&gt;&quot;,&quot;&lt;/span&gt; + s2; }));&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   14&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   15&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color:blue;&quot;&gt;int&lt;/span&gt;&amp;gt; rli = &lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;&lt;span style=&quot;color:blue;&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   16&lt;/span&gt;             rli.AddRange(&lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;int&lt;/span&gt;[] {1, 2, 3, 4});&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   17&lt;/span&gt;             &lt;span style=&quot;color:#2b91af;&quot;&gt;Assert&lt;/span&gt;.AreEqual(10, rli.Reduce(&lt;span style=&quot;color:blue;&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color:blue;&quot;&gt;int&lt;/span&gt; i, &lt;span style=&quot;color:blue;&quot;&gt;int&lt;/span&gt; j) { &lt;span style=&quot;color:blue;&quot;&gt;return&lt;/span&gt; i + j; }));&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   18&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   19&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   20&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;R# Jedi&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;One simple, naive and somewhat cheating method to make the ReducableList work, is using ReSharper. Just add a IRecudeMixin&lt;t&gt; field and choose Alt+Ins/Delegate members. As a finishing touch you need to initialize the field. &lt;/p&gt;
&lt;p&gt;The resulting code is shown below:&lt;/p&gt;
&lt;div style=&quot;BACKGROUND: white;font-family:Courier New;font-size:8pt;color:black;&quot;   &gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    1&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;namespace&lt;/span&gt; Client&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    2&lt;/span&gt; {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    3&lt;/span&gt;     &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReducableList&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style=&quot;color:#2b91af;&quot;&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style=&quot;color:#2b91af;&quot;&gt;IWithReduce&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    4&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    5&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; ReducableList()&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    6&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    7&lt;/span&gt;             reducer = &lt;span style=&quot;color:blue;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceMixin&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style=&quot;color:blue;&quot;&gt;this&lt;/span&gt;);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    8&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;    9&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   10&lt;/span&gt;         &lt;span style=&quot;color:green;&quot;&gt;// Other constructors omitted for brevity&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   11&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   12&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color:blue;&quot;&gt;readonly&lt;/span&gt; &lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceMixin&lt;/span&gt;&amp;lt;T&amp;gt; reducer;&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   13&lt;/span&gt; &lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   14&lt;/span&gt;         &lt;span style=&quot;color:blue;&quot;&gt;public&lt;/span&gt; T Reduce(&lt;span style=&quot;color:#2b91af;&quot;&gt;ReduceDelegate&lt;/span&gt;&amp;lt;T&amp;gt; reduceFunction)&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   15&lt;/span&gt;         {&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   16&lt;/span&gt;             &lt;span style=&quot;color:blue;&quot;&gt;return&lt;/span&gt; reducer.Reduce(reduceFunction);&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   17&lt;/span&gt;         }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   18&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style=&quot;MARGIN: 0px&quot;&gt;&lt;span style=&quot;color:#2b91af;&quot;&gt;   19&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, I know that this is not a viable solution for maintainable software, but it is at least a quick fix and an introduction for the next article, which will show how to use DynamicProxy2 for creating a ReducableList without ReSharper Jedi.&lt;/p&gt;</description><link>http://mortslikeus.blogspot.com/2008/01/emulating-mixins-with-c.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-1363369817816871008</guid><pubDate>Thu, 28 Feb 2008 07:51:00 +0000</pubDate><atom:updated>2008-02-28T14:49:54.207+00:00</atom:updated><title>The Component Burden Concept</title><description>&lt;span style=&quot;font-weight: bold;&quot;&gt;Important Note:&lt;/span&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;Mort that I am, I have mistaken ReleasePolicy for Component Burden and blogged about the former...&lt;/span&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;As soon as I know what I am writing about, I will update that post.&lt;/span&gt;
&lt;p&gt;
&lt;/p&gt;&lt;p&gt;There is a discussion on the Castle mailing list recently about the Component Burden problem. This is one of the oldest Castle &lt;a href=&quot;http://support.castleproject.org/browse/IOC-2&quot; target=&quot;_blank&quot;&gt;issues&lt;/a&gt; (and the oldest that is not resolved by now). Now, the issue got a little bit of momentum by Ayende&#39;s &lt;a href=&quot;http://groups.google.com/group/castle-project-devel/browse_thread/thread/e7c7d1904aac620c/61bb4d7635ba840f?hl=en#61bb4d7635ba840f&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; and Hammett&#39;s &lt;a href=&quot;http://hammett.castleproject.org/?p=252&quot; target=&quot;_blank&quot;&gt;blog entry&lt;/a&gt; about it.&lt;/p&gt;  &lt;p&gt;In short, the problem is this: If there are non-singleton components created by the IoC-Container that implement &lt;span style=&quot;font-family:Courier New;&quot;&gt;IDisposable&lt;/span&gt;, someone sometime needs to call &lt;span style=&quot;font-family:Courier New;&quot;&gt;Dispose()&lt;/span&gt;. However, both someone and sometime pose a problem:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Someone could be the using code or the container. It has been proposed that a component should dispose it&#39;s dependencies itself, but if you think about it, this is problematic because the component cannot know it&#39;s dependencies&#39; lifestyles. Just imagine a service configured to run as a singleton being disposed after the very first request it served, because an using component doesn&#39;t need it anymore. Additionally there is a simple principle about resource allocation: The code that allocates a resource is responsible for deallocation too. Period. Back when C/C++ was used, every developer adhered to that principle because there was no GC...&lt;/li&gt;    &lt;li&gt;Sometime is dependent on the components lifestyle. A singleton must not be disposed before the container shuts down itself while a transient component must be disposed as soon as possible to free allocated resources.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now it is clear that the container is fully responsible for both construction and destruction of dependency objects. But how will it know, when the component is not used anymore?&lt;/p&gt;  &lt;p&gt;Well, at least one component must be resolved from the container. This component must be released after you are finished using it: &lt;/p&gt;  &lt;p&gt;&lt;span style=&quot;font-family:Courier New;&quot;&gt;MyComponent c = container.Resolve&amp;lt;MyComponent&amp;gt;();    
// Some work     
container.Release(c);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;Do you need to do this even if you&#39;re component is not disposable? Yes, because it can have direct or indirect dependencies that are disposable. If you don&#39;t release it, the container cannot know that it is now safe to dispose these dependencies, when they are otherwise unused.&lt;/p&gt;  &lt;p&gt;Now there is one thing missing: The container must keep track of the dependencies. Assume that your component uses a custom per-web-request-logger that uses a &lt;span style=&quot;font-family:Courier New;&quot;&gt;FileStream&lt;/span&gt;.&lt;/p&gt;  &lt;p&gt;Every time you resolve a component that uses the logger in one web request, the dependency will be fulfilled with the same logger. If you release a component, the container must remember that it used the logger, then check whether the logger is still used by other instances and if not, dispose the logger.&lt;/p&gt;  &lt;p&gt;This bookkeeping of dependencies and disposal is called the component burden in the &lt;a href=&quot;http://castleproject.org/&quot; target=&quot;_blank&quot;&gt;Castle project&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Although I don&#39;t know Microkernel&#39;s source code for this, I have an idea how to implement such a concept. But this is a topic for another post.&lt;/p&gt;</description><link>http://mortslikeus.blogspot.com/2008/02/component-burden-concept.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-576637242109682175</guid><pubDate>Fri, 09 Nov 2007 13:03:00 +0000</pubDate><atom:updated>2007-11-09T13:32:14.079+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">ActiveRecord</category><category domain="http://www.blogger.com/atom/ns#">BugByDesign</category><category domain="http://www.blogger.com/atom/ns#">Generics</category><title>WTF: Overloading and Generics</title><description>Recently I discovered some behaviour of .NET that I couldn&#39;t explain. I still wonder whether this is an error or &quot;&lt;a href=&quot;http://ayende.com/Blog/archive/2007/09/18/Microsoft-Connect-Redefining-bugs-as-features-as-a-standard-operation.aspx&quot;&gt;ByDesign&lt;/a&gt;&quot;. I found it when I tried to call ActiveRecordMediator&#39;s Exists method, which threw out an unexpected exception. Minutes later, I stared unbelievingly to the screen: A complete different method overload was called.

I sat down and created a short example that doesn&#39;t use ActiveRecord, so it can be understood from any .NET-developer:

&lt;pre&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;interface&lt;/strong&gt;&lt;/span&gt; IString
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; Content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; get&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/span&gt; DString&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt;IString
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;private&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;readonly&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;

  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; Content
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    get &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;DString&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#cc00cc;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;content &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/span&gt; Class1
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;void&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;Foo&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;params&lt;/strong&gt;&lt;/span&gt; IString&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt; bars&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;foreach&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;IString s &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;in&lt;/strong&gt;&lt;/span&gt; bars&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
      Console&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;WriteLine&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;s&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;Content&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;void&lt;/strong&gt;&lt;/span&gt; Foo&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;T&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;T bar&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;throw&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;new&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;TestFixture&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/span&gt; Tester
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;Test&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;void&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;CallBar&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    Class1&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Foo&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;new&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;DString&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#ff00cc;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ff00cc;&quot;&gt;baz&lt;/span&gt;&lt;span style=&quot;color:#ff00cc;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
  &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;

So what would you expect when running the unit test?

That&#39;s what I got:

&lt;span style=&quot;font-family:courier new;&quot;&gt;TestCase &#39;ClassLibrary2.Tester.CallBar&#39; failed: System.NotImplementedException : The method or operation is not implemented.&lt;/span&gt;

What happens here? If you add exactly one optional parameter, the compiler somehow thinks, you meant Foo&amp;lt;istring&amp;gt;() instead of Foo(). This happens only if the type parameter is an interface. I tried with string and that worked like expected, calling Foo().

So, is this a bug or a documented behaviour. Do you know ressources that document it? I didn&#39;t find any...</description><link>http://mortslikeus.blogspot.com/2007/11/wtf-overloading-and-generics.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-385473814989421290.post-3713984271470453318</guid><pubDate>Tue, 06 Nov 2007 11:26:00 +0000</pubDate><atom:updated>2007-11-06T13:16:31.946+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ActiveRecord</category><category domain="http://www.blogger.com/atom/ns#">BookOfIdeas</category><title>From The Book of Ideas: Searchable ActiveRecord-Entities</title><description>One of the feature requests that I hear most often from my users that they want a search function for the grids. I then show them a search form where they can specify field and values exactly. Most often, I then hear:
&quot;No, I meant a search field. I enter some text and the software shows all relevant entries.&quot;
I usually answer by asking whether it should also save the climate and overcome poverty or if simple mindreading is sufficient.

Ok, but last night I had an idea how searching with a single textfield interface can be accomplished without redeveloping that nasty thing for each view. I use the &lt;a href=&quot;http://www.castleproject.org/&quot;&gt;Castle&lt;/a&gt; stack for .Net for my applications, which means that my entities are created with Castle ActiveRecord and displayed in MonoRail web applications.

The idea works like this: There is only one who knows which properties must be included into the search and this the developer that created the entities. Therefore we need some mechanism to specify the searchable properties. My idea was adding a Searchable attribute to the ActiveRecord classes&#39; properties that need to be included in such searches:



&lt;pre&gt;&lt;span style=&quot;color:#000000;&quot;&gt;    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;ActiveRecord&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/span&gt; Entity &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/span&gt; ActiveRecordBase&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;Entity&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;private&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;int&lt;/strong&gt;&lt;/span&gt; id&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;private&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; name&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;private&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; entityDesc&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;private&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; internalName&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;

        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;PrimaryKey&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;int&lt;/strong&gt;&lt;/span&gt; Id
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
            get &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; id&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
            set &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; id &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; value&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;Searchable&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;Property&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; Name
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
            get &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; name&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
            set &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; name &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; value&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Searchable&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;FriendlyName &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#ff00cc;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#ff00cc;&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#ff00cc;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;Property&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; EntityDesc
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
            get &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; entityDesc&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
            set &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; entityDesc &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; value&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;

        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;Property&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; InternalName
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
            get &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; internalName&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
            set &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt; internalName &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; value&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;

The Searchable takes an optional parameter, FriendlyName that allows to specify a localized or other, more user-friendly name. The attribute can be applied to both properties and relations. If applied to a relation attribute (BelongsTo, HasMany, HasAndBelongsToMany etc.) the properties tagged in that type will be added to the search as well.

Then there is a SearchMediator, which will create a NHibernate Criteria Query that will check for every search term whether it can be parsed by the datatype of a tagged property and adds it to the query if this is the case.

The code below sketches how the query could be created:



&lt;pre&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;public&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;static&lt;/strong&gt;&lt;/span&gt; T&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#9966ff;&quot;&gt;Search&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; text&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt; words &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; text&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Split&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
    DetachedCriteria criteria &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; DetachedCriteria&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;For&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;T&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;foreach&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#0099ff;&quot;&gt;&lt;strong&gt;string&lt;/strong&gt;&lt;/span&gt; word &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;in&lt;/strong&gt;&lt;/span&gt; words&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
        Disjunction group &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt; Expression&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Disjunction&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;foreach&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;PropertyInfo info &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;in&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;typeof&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;T&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;GetProperties&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/span&gt;
            &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;if&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;info&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;GetCustomAttributes&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;typeof&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;SearchableAttribute&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;,&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#cc00cc;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;Length &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;&lt;/span&gt; &lt;span style=&quot;color:#ff0000;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;
                group&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;Expression&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Like&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;info&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;Name&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;,&lt;/strong&gt;&lt;/span&gt; word&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;,&lt;/strong&gt;&lt;/span&gt; MatchMode&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;Anywhere&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
        &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
        criteria&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;Add&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;group&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;
    &lt;span style=&quot;color:#006699;&quot;&gt;&lt;strong&gt;return&lt;/strong&gt;&lt;/span&gt; ActiveRecordMediator&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;lt;&lt;/strong&gt;&lt;/span&gt;T&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;&amp;gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#9966ff;&quot;&gt;FindAll&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;criteria&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color:#000000;&quot;&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
This can be extended by many means. Examples include:

&lt;ul&gt;&lt;li&gt;Allowing propertyName:searchTerm to narrow search to a specific property by its name or friendly name.&lt;/li&gt;&lt;li&gt;Allowing other operators than the colon like price&gt;10.00 or name!Foo&lt;/li&gt;&lt;li&gt;Add globbing to specify whether exact matches or all matches should be found&lt;/li&gt;&lt;li&gt;Specify the MatchMode behavior for string properties as part of SearchableAttribute&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Using that mechanism, I can add searching to almost any entity similar to validation. What do you think, would such a Search component benefit the Castle Framework?&lt;/p&gt;That is only some thoughts. I didn&#39;t start implementing anything yet. However, anyone interested in helping is welcome, of course.</description><link>http://mortslikeus.blogspot.com/2007/11/from-book-of-ideas-searchable.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>2</thr:total></item></channel></rss>