<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Castle</title>
        <link>http://ayende.com/Blog/category/489.aspx</link>
        <description>Castle</description>
        <language>en-US</language>
        <copyright>Ayende Rahien</copyright>
        <managingEditor>Ayende@ayende.com</managingEditor>
        <generator>Subtext Version 2.0.0.0</generator>
        <item>
            <title>Optimizing Windsor</title>
            <link>http://ayende.com/Blog/archive/2009/09/18/optimizing-windsor.aspx</link>
            <description>&lt;p&gt;Recently we got a bug report about the performance of Windsor when registering large number of components (thousands). I decided to sit down and investigate this, and found out something that was troublesome. &lt;/p&gt;  &lt;p&gt;Internally, registering a component would trigger a check for all registered components that are waiting for a dependency. If you had a lot of components that were waiting for dependency, registering a new component degenerated to an O(N^2) operation, where N was the number of components with waiting dependencies.&lt;/p&gt;  &lt;p&gt;Luckily, there was no real requirement for an O(N^2) operation, and I was able to change that to an O(N) operation.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Huge&lt;/em&gt; optimization win, right?&lt;/p&gt;  &lt;p&gt;In numbers, we are talking about 9.2 &lt;em&gt;seconds&lt;/em&gt; to register 500 components with no matching dependencies. After the optimization, we dropped that to 500 &lt;em&gt;milliseconds&lt;/em&gt;. And when we are talking about larger number of components, this is still a problem.&lt;/p&gt;  &lt;p&gt;After optimization, registering 5,000 components with no matching dependencies took 44.5 seconds. That is better than before (where no one has the patience to try and figure out the number), but I think we can improve up it.&lt;/p&gt;  &lt;p&gt;The problem is that we are still paying that O(N) cost for &lt;em&gt;each registration&lt;/em&gt;. Now, to suppose systems that already uses Windsor, we can’t really change the way Windsor handle registrations by default, so I came up with the following syntax, that safely change the way Windsor handles registration:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div id="codeSnippetWrapper"&gt;     &lt;pre id="codeSnippet" class="csharpcode"&gt;var kernel = &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultKernel();&lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (kernel.OptimizeDependencyResolution())&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 500; i++)&lt;br /&gt;    {&lt;br /&gt;        kernel.AddComponent(&lt;span class="str"&gt;"key"&lt;/span&gt; + i, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using this method, registering 5,000 components drops down to 2.5 seconds. &lt;/p&gt;

&lt;p&gt;I then spent additional time finding all the other nooks and crannies where optimizations hid, dropping the performance down to 1.4 seconds.&lt;/p&gt;

&lt;p&gt;Now, I have to say that this is &lt;em&gt;not &lt;/em&gt;linear performance improvement. Registering 20,000 components will take about 25 seconds. This is not a scenario that we worry over much about.&lt;/p&gt;

&lt;p&gt;The best thing about the non linear curve is that for a 1,000 components, which is what we &lt;em&gt;do&lt;/em&gt; care about, registration takes 240 milliseconds. Most applications don’t get to have a thousand components, anyway.&lt;/p&gt;

&lt;p&gt;There are also other improvements made in the overall runtime performance of Windsor, but those would be very hard to notice outside of a tight loop.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/11127.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/09/18/optimizing-windsor.aspx</guid>
            <pubDate>Fri, 18 Sep 2009 07:06:56 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/09/18/optimizing-windsor.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/11127.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Castle Windsor 2.0 RTM Released</title>
            <link>http://ayende.com/Blog/archive/2009/05/05/castle-windsor-2.0-rtm-released.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/CastleWindsor2.0RTMReleased_1365/image_8.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="219" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/CastleWindsor2.0RTMReleased_1365/image_thumb_3.png" width="343" align="right" border="0" /&gt;&lt;/a&gt;Some would say that it is &lt;em&gt;about&lt;/em&gt; time, I would agree. Windsor might not be the OSS project in pre release state for the longest time (I think that the honor belong to Hurd), but it spent enough time at that state to at least deserve a honorary mention.&lt;/p&gt;  &lt;p&gt;That was mostly because, although Windsor was production ready for the last three or four years or so, most of the people making use of it were happy to make use of the trunk version. &lt;/p&gt;  &lt;p&gt;If you will look, you won’t find Windsor 1.0, only release candidates for 1.0. As I believe I mentioned, Windsor has been production ready for a long time, and for the full release we decided to skip the 1.0 designator, which doesn’t really fit, and go directly to 2.0&lt;/p&gt;  &lt;p&gt;The last Windsor release (RC3) was almost a year and a half ago, and in the meantime, much has improved in Windsor land. Adding upon the already superb engine and facilities, we have fitted Windsor to the 3.5 release of the .Net framework, created a full fledged fluent API to support easy configuration, allowed more granular control over the behavior of the container when selecting components and handlers and improved overall performance.&lt;/p&gt;  &lt;p&gt;All in all, pretty good stuff, even if I say so myself. Just to give you an idea, the list of changes from the previous release goes for quite a while, so I am going to let the short listing above to stand in its place.&lt;/p&gt;  &lt;p&gt;You can get the new release from the &lt;a href="https://sourceforge.net/project/showfiles.php?group_id=124416&amp;amp;package_id=136235"&gt;source forge site&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10913.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2009/05/05/castle-windsor-2.0-rtm-released.aspx</guid>
            <pubDate>Mon, 04 May 2009 22:22:51 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2009/05/05/castle-windsor-2.0-rtm-released.aspx#feedback</comments>
            <slash:comments>33</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10913.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Logging - the AOP way</title>
            <link>http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx</link>
            <description>&lt;p&gt;Logging is probably the most mentioned sweet spot of AOP. Probably because it is the simplest and most straightforward example most people can think of. I remember going over a piece of code that handles &lt;em&gt;billions&lt;/em&gt; of transactions a day(that is for you, Jdn), and seeing something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; DoSomethingInteresting(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; arg1, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; arg2)
{
	LogGateway.Enter("&lt;span style="color: #8b0000"&gt;DoSomethingInteresting&lt;/span&gt;", arg1, arg2);
	&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
	{
		&lt;span style="color: #008000"&gt;// actual method code &lt;/span&gt;
		LogGateway.Success("&lt;span style="color: #8b0000"&gt;DoSomethingInteresting&lt;/span&gt;", arg1, arg2);
	}
	&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;(Exception e)
	{
		LogGateway.Error(e, "&lt;span style="color: #8b0000"&gt;DoSomethingInteresting&lt;/span&gt;", arg1, arg2);
		&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; e;
	}
	&lt;span style="color: #0000ff"&gt;finally&lt;/span&gt;
	{
		LogGateway.Exit("&lt;span style="color: #8b0000"&gt;DoSomethingInteresting&lt;/span&gt;", arg1, arg2);
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was repeated for each and every method in the system. It was horrible. &lt;/p&gt;

&lt;p&gt;I don't &lt;em&gt;care&lt;/em&gt; how you do it, but there are at least &lt;a href="http://www.ayende.com/Blog/archive/2007/07/02/7-Approaches-for-AOP-in-.Net.aspx"&gt;7 AOP approaches&lt;/a&gt; in the CLR, at least three of them are applicable in &lt;em&gt;your&lt;/em&gt; environment.&lt;/p&gt;

&lt;p&gt;I am going to show how to handle that with Windsor's AOP, but the same thing is applicable using other approaches. First, our service:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; ISmsSender
{
	&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Send(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; to, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; msg);
}

&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SmsSender : ISmsSender
{
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Send(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; to, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; msg)
	{
		&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(msg.Length&amp;gt;160)
			&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException("&lt;span style="color: #8b0000"&gt;too long&lt;/span&gt;","&lt;span style="color: #8b0000"&gt;msg&lt;/span&gt;");
		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; to.Length;
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And now we need to define the interceptor:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LoggingInterceptor : IInterceptor
{
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Intercept(IInvocation invocation)
	{
		var logger = LogManager.GetLogger(invocation.TargetType);
		&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
		{
			StringBuilder sb = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
			&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (logger.IsDebugEnabled)
			{
				sb = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder(invocation.TargetType.FullName)
					.Append("&lt;span style="color: #8b0000"&gt;.&lt;/span&gt;")
					.Append(invocation.Method)
					.Append("&lt;span style="color: #8b0000"&gt;(&lt;/span&gt;");
				&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; invocation.Arguments.Length; i++)
				{
					&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (i &amp;gt; 0)
						sb.Append("&lt;span style="color: #8b0000"&gt;, &lt;/span&gt;");
					sb.Append(invocation.Arguments[i]);
				}
				sb.Append("&lt;span style="color: #8b0000"&gt;)&lt;/span&gt;");
				logger.Debug(sb);
			}

			invocation.Proceed();
			&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(logger.IsDebugEnabled)
			{
				
				logger.Debug("&lt;span style="color: #8b0000"&gt;Result of &lt;/span&gt;" + sb + "&lt;span style="color: #8b0000"&gt; is: &lt;/span&gt;" + invocation.ReturnValue);
			}
		}
		&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception e)
		{
			logger.Error(e);
			&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;
		}
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The code is really simple, we get the logger instance ( in this case, from log4net ), check if logging is enabled and if so, write the method and parameters to the log. We then execute the code and log the return value as well.&lt;/p&gt;

&lt;p&gt;If there was an error, we log that as well.&lt;/p&gt;

&lt;p&gt;Here is my test code:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WindsorContainer()
	.Register(
		Component.For&amp;lt;LoggingInterceptor&amp;gt;(),
		Component.For&amp;lt;ISmsSender&amp;gt;().ImplementedBy&amp;lt;SmsSender&amp;gt;()
			.Interceptors(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InterceptorReference(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(LoggingInterceptor))).First
	);
BasicConfigurator.Configure(); &lt;span style="color: #008000"&gt;// configure log4net&lt;/span&gt;
var sender = container.Resolve&amp;lt;ISmsSender&amp;gt;();
&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
{
	sender.Send("&lt;span style="color: #8b0000"&gt;ayende&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;short&lt;/span&gt;");
	sender.Send("&lt;span style="color: #8b0000"&gt;rahien&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;('q', 161));
}
&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception)
{
	
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the output for that is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;241 [1] DEBUG ConsoleApplication9.SmsSender (null) - ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(ayende, short)
    &lt;br /&gt;272 [1] DEBUG ConsoleApplication9.SmsSender (null) - Result of ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(ayende, short) is: 6

    &lt;br /&gt;272 [1] DEBUG ConsoleApplication9.SmsSender (null) - ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(rahien, 

    &lt;br /&gt;    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq

    &lt;br /&gt;    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq

    &lt;br /&gt;    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq)

    &lt;br /&gt;273 [1] ERROR ConsoleApplication9.SmsSender (null) - System.ArgumentException: too long

    &lt;br /&gt;Parameter name: msg

    &lt;br /&gt;   at ConsoleApplication9.SmsSender.Send(String to, String msg) in C:\Users\ayende\Documents\Visual Studio 2008\Projects\ConsoleApplication9\ConsoleApplication9\ISmsSender.cs:line 15

    &lt;br /&gt;   at ISmsSenderProxyb24fc36182fb434fa7f466d148259c48.InvocationSend_1.InvokeMethodOnTarget()

    &lt;br /&gt;   at Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS\Castle\Tools\Castle.DynamicProxy2\Castle.DynamicProxy\AbstractInvocation.cs:line 140

    &lt;br /&gt;   at ConsoleApplication9.LoggingInterceptor.Intercept(IInvocation invocation) in C:\Users\ayende\Documents\Visual Studio 2008\Projects\ConsoleApplication9\ConsoleApplication9\Program.cs:line 65&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple, elegant, and doesn't clutter my code.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10380.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx</guid>
            <pubDate>Thu, 31 Jul 2008 18:40:07 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/07/31/Logging--the-AOP-way.aspx#feedback</comments>
            <slash:comments>15</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10380.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Integrating NHibernate and Active Record</title>
            <link>http://ayende.com/Blog/archive/2008/07/13/Integrating-NHibernate-and-Active-Record.aspx</link>
            <description>&lt;p&gt;On the face of it, this is a nonsense post. What do I mean, integrating NHibernate and Active Record? Active Record is based on NHibernate, after all. What kind of integration you need? Well, sometimes you want to be able to use NHibernate entities in an Active Record project. And that tended to be very hard. (The other way was extremely easy, just tell Active Record to generate the mapping and move from there.)&lt;/p&gt;  &lt;p&gt;A week or so ago I added support for doing it the other way around, of adding POCO NHibernate entities into the ActiveRecord model. &lt;/p&gt;  &lt;p&gt;Here is the test:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;[Test]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CanIntegrateNHibernateAndActiveRecord()
{
	ActiveRecordStarter.ModelsValidated += &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;
	{
		&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActiveRecordModelBuilder().CreateDummyModelFor(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(NHibernateClass));
	};
	ActiveRecordStarter.Initialize(
		GetConfigSource(),
		&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ActiveRecordClass),
		&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(NHibernateClass));

	Recreate();

	&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TransactionScope tx = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope())
	{
		ActiveRecordClass ar = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActiveRecordClass();
		ar.Friend = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NHibernateClass();
		ActiveRecordMediator.Save(ar.Friend);
		ActiveRecordMediator.Save(ar);
		tx.VoteCommit();
	}

	&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (TransactionScope tx = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TransactionScope())
	{
		ActiveRecordClass first = ActiveRecordMediator&amp;lt;ActiveRecordClass&amp;gt;.FindFirst();
		Assert.IsNotNull(first);
		Assert.IsNotNull(first.Friend);
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that I would reserve this to advance scenarios only, in most cases, it is recommended to only use a consistent approach.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10319.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/07/13/Integrating-NHibernate-and-Active-Record.aspx</guid>
            <pubDate>Sun, 13 Jul 2008 09:06:05 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/07/13/Integrating-NHibernate-and-Active-Record.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10319.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Pain reduction: creating ductile tests</title>
            <link>http://ayende.com/Blog/archive/2008/06/13/Pain-reduction-creating-ductile-tests.aspx</link>
            <description>&lt;p&gt;Take a look at this test:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;[Test]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_not_consider_webcasts_published_in_the_future()
{
	var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(-2) };
	With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
	var webcast2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast { Name = "&lt;span style="color: #8b0000"&gt;test&lt;/span&gt;", PublishDate = DateTime.Now.AddDays(2) };
	With.Transaction(() =&amp;gt; webcastRepository.Save(webcast2));
	Assert.AreEqual(webcast.Id, webcastRepository.GetLatest().Id);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;It looks like a valid test, doesn't it? It has a &lt;strong&gt;huge&lt;/strong&gt; problem. It is brittle.&lt;/p&gt;

&lt;p&gt;I just added a new non null property, and all the tests broke. I started to add the new property value to the test, before I realize what I was doing. I run into a friction point, and I was trying to cover it with code. Next time I would add such a property, I would run into the same problem. &lt;/p&gt;

&lt;p&gt;This is unacceptable. &lt;/p&gt;

&lt;p&gt;The standard solution for this is to create a factory for this, or use an &lt;a href="http://martinfowler.com/bliki/ObjectMother.html"&gt;Object Mother&lt;/a&gt;. This was never something that I was fond of. I always need more flexibility than I can usually get from it, and I hate building builders, that is &lt;em&gt;so&lt;/em&gt; boring.&lt;/p&gt;

&lt;p&gt;Turn out, I can eat the cake and keep it. &lt;/p&gt;

&lt;p&gt;I created the following test class:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;[ActiveRecord("&lt;span style="color: #8b0000"&gt;Webcasts&lt;/span&gt;")]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; TestableWebcast : Webcast
{
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TestabbleWebcast()
	{
		Name = "&lt;span style="color: #8b0000"&gt;Test name&lt;/span&gt;";
		Description = "&lt;span style="color: #8b0000"&gt;Test description&lt;/span&gt;";
	}
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;And now the test change to:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;[Test]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_asking_for_latest_webcast_will_not_consider_webcasts_published_in_the_future()
{
	var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TestableWebcast { PublishDate = DateTime.Now.AddDays(-2) };
	With.Transaction(() =&amp;gt; webcastRepository.Save(webcast));
	var webcast2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TestableWebcast { PublishDate = DateTime.Now.AddDays(2) };
	With.Transaction(() =&amp;gt; webcastRepository.Save(webcast2));
	Assert.AreEqual(webcast.Id, webcastRepository.GetLatest().Id);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;I get to keep the nice object initializer syntax, and I even get more clarity, since I can now specify only the properties that I am actually interested in.&lt;/p&gt;

&lt;p&gt;The only annoying thing is that I have to define the TestableWebcast as an entity as well, but I can live with it.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10269.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/06/13/Pain-reduction-creating-ductile-tests.aspx</guid>
            <pubDate>Thu, 12 Jun 2008 23:07:36 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/06/13/Pain-reduction-creating-ductile-tests.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10269.aspx</wfw:commentRss>
        </item>
        <item>
            <title>The test of fire: Rhino Mocks 3.5 in the real world</title>
            <link>http://ayende.com/Blog/archive/2008/06/13/The-test-of-fire-Rhino-Mocks-3.5-in-the-real.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ThetestoffireRhinoMocks3.5intherealworld_B91/image_6.png"&gt;&lt;img style="margin: 0px 25px 0px 30px" height="267" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/ThetestoffireRhinoMocks3.5intherealworld_B91/image_thumb_2.png" width="198" align="right" border="0" /&gt;&lt;/a&gt;I have been waiting on the release for Rhino Mocks 3.5, seeing what kind of feedback I can get from users. I also had another reason, I hadn't had the chance to really give it a good testing, in the only manner that matter, using it to develop production ready software. &lt;/p&gt;  &lt;p&gt;Here is my latest test, which I am fairly pleased with.&lt;/p&gt;  &lt;pre&gt;[TestFixture]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WebcastControllerTest
{ 
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; WebcastController controller;
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IRepository&amp;lt;Webcast&amp;gt; repositoryStub;
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; StubEngineContext engineContext;
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IUnitOfWork unitOfWorkStub;
	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IDisposable disposeGlobalUnitOfWorkRegistration;

	[SetUp]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Setup()
	{
		repositoryStub = MockRepository.GenerateStub&amp;lt;IRepository&amp;lt;Webcast&amp;gt;&amp;gt;();
		unitOfWorkStub = MockRepository.GenerateStub&amp;lt;IUnitOfWork&amp;gt;();
		controller = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WebcastController(repositoryStub)
		             	{
		             		ControllerContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ControllerContext{Name = "&lt;span style="color: #8b0000"&gt;webcast&lt;/span&gt;"},
		             	};
		engineContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StubEngineContext();
		controller.SetEngineContext(engineContext);
		disposeGlobalUnitOfWorkRegistration = UnitOfWork.RegisterGlobalUnitOfWork(unitOfWorkStub);
	}

	[TearDown]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TearDown()
	{
		disposeGlobalUnitOfWorkRegistration.Dispose();
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_index_called_will_send_existing_webcasts_to_view()
	{
		var webcasts = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Webcast&amp;gt;();
		repositoryStub.Stub(x =&amp;gt; x.FindAll()).Return(webcasts);

		controller.Index();

		Assert.AreSame(webcasts, controller.PropertyBag["&lt;span style="color: #8b0000"&gt;webcasts&lt;/span&gt;"]);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_display_called_will_send_webcast_to_view()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();
		controller.Display(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["&lt;span style="color: #8b0000"&gt;webcast&lt;/span&gt;"]);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_edit_called_with_webcast_will_send_webcast_to_view()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();
		controller.Edit(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["&lt;span style="color: #8b0000"&gt;webcast&lt;/span&gt;"]);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_saving_invalid_webcast_will_redirect_to_edit()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "&lt;span style="color: #8b0000"&gt;edit&lt;/span&gt;");
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_saving_invalid_webcast_will_flash_error_summary_and_webcast_in_flash()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.AreSame(webcast, controller.Flash["&lt;span style="color: #8b0000"&gt;webcast&lt;/span&gt;"]);
		Assert.AreSame(controller.Validator.GetErrorSummary(webcast), controller.Flash["&lt;span style="color: #8b0000"&gt;errorSummary&lt;/span&gt;"]);
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_saving_valid_webcast_will_redirect_to_display()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();

		&lt;span style="color: #008000"&gt;// explicitly not calling validation, the controller will assume &lt;/span&gt;
		&lt;span style="color: #008000"&gt;// that this is a valid object&lt;/span&gt;

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "&lt;span style="color: #8b0000"&gt;display&lt;/span&gt;");
	}

	[Test]
	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; When_saving_valid_webcast_will_save_and_flash_unit_of_work()
	{
		var webcast = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Webcast();

		&lt;span style="color: #008000"&gt;// explicitly not calling validation, the controller will assume &lt;/span&gt;
		&lt;span style="color: #008000"&gt;// that this is a valid object&lt;/span&gt;

		controller.Save(webcast);

		repositoryStub.AssertWasCalled(x=&amp;gt;x.Save(webcast));
		unitOfWorkStub.AssertWasCalled(x=&amp;gt;x.TransactionalFlush());
	}
}&lt;/pre&gt;&lt;img src="http://ayende.com/Blog/aggbug/10268.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/06/13/The-test-of-fire-Rhino-Mocks-3.5-in-the-real.aspx</guid>
            <pubDate>Thu, 12 Jun 2008 21:49:54 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/06/13/The-test-of-fire-Rhino-Mocks-3.5-in-the-real.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10268.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Painless Persistence with Castle Active Record</title>
            <link>http://ayende.com/Blog/archive/2008/06/03/Painless-Persistence-with-Castle-Active-Record.aspx</link>
            <description>&lt;p&gt;About a year ago me and &lt;a href="http://hammett.castleproject.org"&gt;Hammett&lt;/a&gt; gave a few talks about Castle in JAOO. I am not sure why the recording of the talk came up now, but it have.&lt;/p&gt;  &lt;p&gt;You can watch this presentation here: &lt;a title="http://www.infoq.com/presentations/eini-verissimo-castle-active-record" href="http://www.infoq.com/presentations/eini-verissimo-castle-active-record"&gt;http://www.infoq.com/presentations/eini-verissimo-castle-active-record&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For all the people who wanted to see a video of one of my presentation, there you go.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10251.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/06/03/Painless-Persistence-with-Castle-Active-Record.aspx</guid>
            <pubDate>Mon, 02 Jun 2008 23:43:25 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/06/03/Painless-Persistence-with-Castle-Active-Record.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10251.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Donjon - Hammett's Teasing</title>
            <link>http://ayende.com/Blog/archive/2008/01/20/Donjon--Hammetts-Teasing.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://hammett.castleproject.org/"&gt;Hammett&lt;/a&gt; has just posted &lt;a href="http://hammett.castleproject.org/?p=235"&gt;teaser image&lt;/a&gt; on his blog.&lt;/p&gt; &lt;p&gt;Go check it out. I have some idea about how long ago it started, and to get to this point is amazing (and no, I don't have any extra knowledge about what it does otherwise, except maybe free us from OutOfMemoryError s and manual restarts).&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/10009.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/01/20/Donjon--Hammetts-Teasing.aspx</guid>
            <pubDate>Sun, 20 Jan 2008 20:08:51 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/01/20/Donjon--Hammetts-Teasing.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/10009.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Active Record: Mapping Rewriting</title>
            <link>http://ayende.com/Blog/archive/2008/01/11/Active-Record-Mapping-Rewriting.aspx</link>
            <description>&lt;p&gt;One of the really nice things about using the NHibernate / Active Record stack is that there are so many extensions points.&lt;/p&gt; &lt;p&gt;One of the more fun things is the ability to do runtime modifications of the mapping. Here is a simple example:&lt;/p&gt;&lt;pre&gt;ActiveRecordStarter.ModelsCreated+=&lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;(ActiveRecordModelCollection models, IConfigurationSource source)
{
    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (ActiveRecordModel model &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; models)
    {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(model.Type == &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(User))
        {
            model.ActiveRecordAtt.Table = "&lt;span style="color: #8b0000"&gt;MyUsers&lt;/span&gt;";
        }
    }
};&lt;/pre&gt;
&lt;p&gt;Here we are re-writing the table that the User entity will go to. We can get much more complex, since we have all the knowledge of the structure of the code and can apply things like naming convention, validation, etc. It is also a fast way to translate between database/conventions.&lt;/p&gt;
&lt;p&gt;NHibernate has a similar concept, INamingStrategy, which can be used to some of the same purposes, but I like this approach better, since it gives me more semantic information.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/9997.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2008/01/11/Active-Record-Mapping-Rewriting.aspx</guid>
            <pubDate>Fri, 11 Jan 2008 14:38:37 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2008/01/11/Active-Record-Mapping-Rewriting.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/9997.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Castle Style Errors</title>
            <link>http://ayende.com/Blog/archive/2007/11/05/Castle-Style-Errors.aspx</link>
            <description>&lt;p&gt;I had to compare different styles of error handling approaches, and I automatically compared the ideal, Castle Style errors, to the nasty, Mystery HRESUTL of the Week.&lt;/p&gt; &lt;p&gt;But what does Castle Style errors means?&lt;/p&gt; &lt;p&gt;Let us take a look at a few of them. When an module that was registered before the MonoRail http module had thrown an exception:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Exception(
	"&lt;span style="color: #8b0000"&gt;An exception happened on Global application or on a module that run before MonoRail's module. &lt;/span&gt;" + 
	"&lt;span style="color: #8b0000"&gt;MonoRail will not be initialized and further requests are going to fail. &lt;/span&gt;" + 
	"&lt;span style="color: #8b0000"&gt;Fix the cause of the error reported below.&lt;/span&gt;", context.Context.Error);&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Or what happens when you are trying to access an ActiveRecord class when you didn't initialize it properly?&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;String.Format("&lt;span style="color: #8b0000"&gt;An ActiveRecord class ({0}) was used but the framework seems not &lt;/span&gt;" +
   "&lt;span style="color: #8b0000"&gt;properly initialized. Did you forget about ActiveRecordStarter.Initialize() ?&lt;/span&gt;",
   type.FullName);&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;And:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;String.Format("&lt;span style="color: #8b0000"&gt;You have accessed an ActiveRecord class that wasn't properly initialized. &lt;/span&gt;" +
   "&lt;span style="color: #8b0000"&gt;The only explanation is that the call to ActiveRecordStarter.Initialize() didn't include {0} class&lt;/span&gt;",
   type.FullName);&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;The common theme for those errors is that they are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Descriptive&lt;/li&gt;
&lt;li&gt;Show all the relevant information&lt;/li&gt;
&lt;li&gt;Suggest a probable solution&lt;/li&gt;
&lt;li&gt;Save time&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;I added the following exception:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActiveRecordException(String.Format(
	"&lt;span style="color: #8b0000"&gt;You can't use [Property] on {0}.{1} because {2} is an active record class, did you mean to use BelongTo?&lt;/span&gt;",
	model.Property.DeclaringType.Name, model.Property.Name, propertyType.FullName));&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;I added that after I spent half an hour trying to figure out why something was wrong. Since then, I &lt;em&gt;keep&lt;/em&gt; running into this exception, and then it is a "slap on the head, replace [Property] with [BelongsTo] and move on". And that is me, who wrote this bloody annoying exception that I am supposed to already know and avoid triggering. I can't imagine how many hours this exception alone has saved, just for my team.&lt;/p&gt;
&lt;p&gt;In fact, when I gave a talk at DevTeach about MonoRail, I have literally built the entire demo by just following the instructions from the exceptions.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;That&lt;/em&gt; is good error handling, and that is what I consider as the standard that you should aspire to. Anything less than that is cause for anger, anxiety and angst. &lt;em&gt;Do &lt;/em&gt;save yourself the ulcer, put in the best errors you can.&lt;/p&gt;&lt;img src="http://ayende.com/Blog/aggbug/9839.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ayende Rahien</dc:creator>
            <guid>http://ayende.com/Blog/archive/2007/11/05/Castle-Style-Errors.aspx</guid>
            <pubDate>Sun, 04 Nov 2007 22:06:05 GMT</pubDate>
            <comments>http://ayende.com/Blog/archive/2007/11/05/Castle-Style-Errors.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://ayende.com/Blog/comments/commentRss/9839.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>