Ayende @ Rahien

Unnatural acts on source code

Optimizing Windsor

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.

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.

Luckily, there was no real requirement for an O(N^2) operation, and I was able to change that to an O(N) operation.

Huge optimization win, right?

In numbers, we are talking about 9.2 seconds to register 500 components with no matching dependencies. After the optimization, we dropped that to 500 milliseconds. And when we are talking about larger number of components, this is still a problem.

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.

The problem is that we are still paying that O(N) cost for each registration. 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:

var kernel = new DefaultKernel();
using (kernel.OptimizeDependencyResolution())
{
for (int i = 0; i < 500; i++)
{
kernel.AddComponent("key" + i, typeof(string), typeof(string));
}
}

Using this method, registering 5,000 components drops down to 2.5 seconds.

I then spent additional time finding all the other nooks and crannies where optimizations hid, dropping the performance down to 1.4 seconds.

Now, I have to say that this is not linear performance improvement. Registering 20,000 components will take about 25 seconds. This is not a scenario that we worry over much about.

The best thing about the non linear curve is that for a 1,000 components, which is what we do care about, registration takes 240 milliseconds. Most applications don’t get to have a thousand components, anyway.

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.

Castle Windsor 2.0 RTM Released

imageSome would say that it is about 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.

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.

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

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.

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.

You can get the new release from the source forge site.

Logging - the AOP way

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 billions of transactions a day(that is for you, Jdn), and seeing something like this:

public void DoSomethingInteresting(string arg1, int arg2)
{
	LogGateway.Enter("DoSomethingInteresting", arg1, arg2);
	try
	{
		// actual method code 
		LogGateway.Success("DoSomethingInteresting", arg1, arg2);
	}
	catch(Exception e)
	{
		LogGateway.Error(e, "DoSomethingInteresting", arg1, arg2);
		throw e;
	}
	finally
	{
		LogGateway.Exit("DoSomethingInteresting", arg1, arg2);
	}
}

That was repeated for each and every method in the system. It was horrible.

I don't care how you do it, but there are at least 7 AOP approaches in the CLR, at least three of them are applicable in your environment.

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:

public interface ISmsSender
{
	int Send(string to, string msg);
}

public class SmsSender : ISmsSender
{
	public int Send(string to, string msg)
	{
		if(msg.Length>160)
			throw new ArgumentException("too long","msg");
		return to.Length;
	}
}

And now we need to define the interceptor:

public class LoggingInterceptor : IInterceptor
{
	public void Intercept(IInvocation invocation)
	{
		var logger = LogManager.GetLogger(invocation.TargetType);
		try
		{
			StringBuilder sb = null;
			if (logger.IsDebugEnabled)
			{
				sb = new StringBuilder(invocation.TargetType.FullName)
					.Append(".")
					.Append(invocation.Method)
					.Append("(");
				for (int i = 0; i < invocation.Arguments.Length; i++)
				{
					if (i > 0)
						sb.Append(", ");
					sb.Append(invocation.Arguments[i]);
				}
				sb.Append(")");
				logger.Debug(sb);
			}

			invocation.Proceed();
			if(logger.IsDebugEnabled)
			{
				
				logger.Debug("Result of " + sb + " is: " + invocation.ReturnValue);
			}
		}
		catch (Exception e)
		{
			logger.Error(e);
			throw;
		}
	}
}

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.

If there was an error, we log that as well.

Here is my test code:

var container = new WindsorContainer()
	.Register(
		Component.For<LoggingInterceptor>(),
		Component.For<ISmsSender>().ImplementedBy<SmsSender>()
			.Interceptors(new InterceptorReference(typeof(LoggingInterceptor))).First
	);
BasicConfigurator.Configure(); // configure log4net
var sender = container.Resolve<ISmsSender>();
try
{
	sender.Send("ayende", "short");
	sender.Send("rahien", new string('q', 161));
}
catch (Exception)
{
	
}

And the output for that is:

241 [1] DEBUG ConsoleApplication9.SmsSender (null) - ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(ayende, short)
272 [1] DEBUG ConsoleApplication9.SmsSender (null) - Result of ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(ayende, short) is: 6
272 [1] DEBUG ConsoleApplication9.SmsSender (null) - ConsoleApplication9.SmsSender.Int32 Send(System.String, System.String)(rahien,
    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
    qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq)
273 [1] ERROR ConsoleApplication9.SmsSender (null) - System.ArgumentException: too long
Parameter name: msg
   at ConsoleApplication9.SmsSender.Send(String to, String msg) in C:\Users\ayende\Documents\Visual Studio 2008\Projects\ConsoleApplication9\ConsoleApplication9\ISmsSender.cs:line 15
   at ISmsSenderProxyb24fc36182fb434fa7f466d148259c48.InvocationSend_1.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS\Castle\Tools\Castle.DynamicProxy2\Castle.DynamicProxy\AbstractInvocation.cs:line 140
   at ConsoleApplication9.LoggingInterceptor.Intercept(IInvocation invocation) in C:\Users\ayende\Documents\Visual Studio 2008\Projects\ConsoleApplication9\ConsoleApplication9\Program.cs:line 65

Simple, elegant, and doesn't clutter my code.

Integrating NHibernate and Active Record

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.)

A week or so ago I added support for doing it the other way around, of adding POCO NHibernate entities into the ActiveRecord model.

Here is the test:

[Test]
public void CanIntegrateNHibernateAndActiveRecord()
{
	ActiveRecordStarter.ModelsValidated += delegate
	{
		new ActiveRecordModelBuilder().CreateDummyModelFor(typeof(NHibernateClass));
	};
	ActiveRecordStarter.Initialize(
		GetConfigSource(),
		typeof(ActiveRecordClass),
		typeof(NHibernateClass));

	Recreate();

	using (TransactionScope tx = new TransactionScope())
	{
		ActiveRecordClass ar = new ActiveRecordClass();
		ar.Friend = new NHibernateClass();
		ActiveRecordMediator.Save(ar.Friend);
		ActiveRecordMediator.Save(ar);
		tx.VoteCommit();
	}

	using (TransactionScope tx = new TransactionScope())
	{
		ActiveRecordClass first = ActiveRecordMediator<ActiveRecordClass>.FindFirst();
		Assert.IsNotNull(first);
		Assert.IsNotNull(first.Friend);
	}
}

Note that I would reserve this to advance scenarios only, in most cases, it is recommended to only use a consistent approach.

Pain reduction: creating ductile tests

Take a look at this test:

[Test]
public void When_asking_for_latest_webcast_will_not_consider_webcasts_published_in_the_future()
{
	var webcast = new Webcast { Name = "test", PublishDate = DateTime.Now.AddDays(-2) };
	With.Transaction(() => webcastRepository.Save(webcast));
	var webcast2 = new Webcast { Name = "test", PublishDate = DateTime.Now.AddDays(2) };
	With.Transaction(() => webcastRepository.Save(webcast2));
	Assert.AreEqual(webcast.Id, webcastRepository.GetLatest().Id);
}

It looks like a valid test, doesn't it? It has a huge problem. It is brittle.

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.

This is unacceptable.

The standard solution for this is to create a factory for this, or use an Object Mother. 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 so boring.

Turn out, I can eat the cake and keep it.

I created the following test class:

[ActiveRecord("Webcasts")]
public class TestableWebcast : Webcast
{
	public TestabbleWebcast()
	{
		Name = "Test name";
		Description = "Test description";
	}
}

And now the test change to:

[Test]
public void When_asking_for_latest_webcast_will_not_consider_webcasts_published_in_the_future()
{
	var webcast = new TestableWebcast { PublishDate = DateTime.Now.AddDays(-2) };
	With.Transaction(() => webcastRepository.Save(webcast));
	var webcast2 = new TestableWebcast { PublishDate = DateTime.Now.AddDays(2) };
	With.Transaction(() => webcastRepository.Save(webcast2));
	Assert.AreEqual(webcast.Id, webcastRepository.GetLatest().Id);
}

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.

The only annoying thing is that I have to define the TestableWebcast as an entity as well, but I can live with it.

The test of fire: Rhino Mocks 3.5 in the real world

imageI 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.

Here is my latest test, which I am fairly pleased with.

[TestFixture]
public class WebcastControllerTest
{ 
	private WebcastController controller;
	private IRepository<Webcast> repositoryStub;
	private StubEngineContext engineContext;
	private IUnitOfWork unitOfWorkStub;
	private IDisposable disposeGlobalUnitOfWorkRegistration;

	[SetUp]
	public void Setup()
	{
		repositoryStub = MockRepository.GenerateStub<IRepository<Webcast>>();
		unitOfWorkStub = MockRepository.GenerateStub<IUnitOfWork>();
		controller = new WebcastController(repositoryStub)
		             	{
		             		ControllerContext = new ControllerContext{Name = "webcast"},
		             	};
		engineContext = new StubEngineContext();
		controller.SetEngineContext(engineContext);
		disposeGlobalUnitOfWorkRegistration = UnitOfWork.RegisterGlobalUnitOfWork(unitOfWorkStub);
	}

	[TearDown]
	public void TearDown()
	{
		disposeGlobalUnitOfWorkRegistration.Dispose();
	}

	[Test]
	public void When_index_called_will_send_existing_webcasts_to_view()
	{
		var webcasts = new List<Webcast>();
		repositoryStub.Stub(x => x.FindAll()).Return(webcasts);

		controller.Index();

		Assert.AreSame(webcasts, controller.PropertyBag["webcasts"]);
	}

	[Test]
	public void When_display_called_will_send_webcast_to_view()
	{
		var webcast = new Webcast();
		controller.Display(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["webcast"]);
	}

	[Test]
	public void When_edit_called_with_webcast_will_send_webcast_to_view()
	{
		var webcast = new Webcast();
		controller.Edit(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["webcast"]);
	}

	[Test]
	public void When_saving_invalid_webcast_will_redirect_to_edit()
	{
		var webcast = new Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "edit");
	}

	[Test]
	public void When_saving_invalid_webcast_will_flash_error_summary_and_webcast_in_flash()
	{
		var webcast = new Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.AreSame(webcast, controller.Flash["webcast"]);
		Assert.AreSame(controller.Validator.GetErrorSummary(webcast), controller.Flash["errorSummary"]);
	}

	[Test]
	public void When_saving_valid_webcast_will_redirect_to_display()
	{
		var webcast = new Webcast();

		// explicitly not calling validation, the controller will assume 
		// that this is a valid object

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "display");
	}

	[Test]
	public void When_saving_valid_webcast_will_save_and_flash_unit_of_work()
	{
		var webcast = new Webcast();

		// explicitly not calling validation, the controller will assume 
		// that this is a valid object

		controller.Save(webcast);

		repositoryStub.AssertWasCalled(x=>x.Save(webcast));
		unitOfWorkStub.AssertWasCalled(x=>x.TransactionalFlush());
	}
}

Donjon - Hammett's Teasing

Hammett has just posted teaser image on his blog.

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).

Active Record: Mapping Rewriting

One of the really nice things about using the NHibernate / Active Record stack is that there are so many extensions points.

One of the more fun things is the ability to do runtime modifications of the mapping. Here is a simple example:

ActiveRecordStarter.ModelsCreated+=delegate(ActiveRecordModelCollection models, IConfigurationSource source)
{
    foreach (ActiveRecordModel model in models)
    {
        if(model.Type == typeof(User))
        {
            model.ActiveRecordAtt.Table = "MyUsers";
        }
    }
};

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.

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.

Castle Style Errors

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.

But what does Castle Style errors means?

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:

throw new Exception(
	"An exception happened on Global application or on a module that run before MonoRail's module. " + 
	"MonoRail will not be initialized and further requests are going to fail. " + 
	"Fix the cause of the error reported below.", context.Context.Error);

Or what happens when you are trying to access an ActiveRecord class when you didn't initialize it properly?

String.Format("An ActiveRecord class ({0}) was used but the framework seems not " +
   "properly initialized. Did you forget about ActiveRecordStarter.Initialize() ?",
   type.FullName);

And:

String.Format("You have accessed an ActiveRecord class that wasn't properly initialized. " +
   "The only explanation is that the call to ActiveRecordStarter.Initialize() didn't include {0} class",
   type.FullName);

The common theme for those errors is that they are:

  • Descriptive
  • Show all the relevant information
  • Suggest a probable solution
  • Save time

I added the following exception:

throw new ActiveRecordException(String.Format(
	"You can't use [Property] on {0}.{1} because {2} is an active record class, did you mean to use BelongTo?",
	model.Property.DeclaringType.Name, model.Property.Name, propertyType.FullName));

I added that after I spent half an hour trying to figure out why something was wrong. Since then, I keep 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.

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.

That 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. Do save yourself the ulcer, put in the best errors you can.

Model View Action

Adam has an interesting discussion here about handling common actions in MonoRail. This has sparked some discussion in the MonoRail mailing list. I wanted to take the chance to discuss the idea in more detail here.

Basically, he is talking about doing this:

public class IndexAction : SmartDispatcherAction
{
   private ISearchableRepository repos;
   private string indexView;

   public IndexAction(
      ISearchableRepository repos,
      string indexView)
   {
      this.repos = repos;
      this.indexView = indexView;
   }

   public void Execute(string name)
   {
      ISearchable item = repos.FindByName(name);
      if(item == null)
      {
         PropertyBag["UnknownSearchTerm"] = name;
         RenderView("common/unknown_quick_search");
      }

      PropertyBag["Item"] = item;
      RenderView(indexView);
   }
}

And then registering it with the routing engine like this:

new Route("/products/<name>",
    new IndexAction(new ProductRepository(), "display_product"));
new Route("/categories/<name>",
    new IndexAction(new CategoryRepository(), "display_category"));

Now, accessing "/categories/cars" will give you all the items in the cars category.

On the face of it, it seems like a degenerated controller, no? Why do we need it? We can certainly map more than a single URL to a controller, so can't we solve that problem that way?

Let us stop for a moment and think about the MVC model. Where did it come from? From Smalltalk, when GUI was something brand new & sparkling. It is a design pattern for a connected system. In that case, the concept of a controller made a lot of sense.

But when we are talking about the web? The web is a disconnected world. What is the sense in having a controller there? An Action, or a Command, pattern seems much more logical here, no?

image image But then we have things that just doesn't fit this model. Consider the example of CRUD on orders. We can have a controller, which will handle all of the logic for this use case in a single location, or we can have four separate classes, each taking care of a single aspect of the use case.

Personally, I would rather have the controller to do the work in this scenario, because this way I have all the information in a single place, and I don't need to hunt multiply classes in order to find it.

But, there are a lot of cases where we do want to have just this single action to happen, or maybe we want to add some common operations to the controller, without having to get in to crazy inheritance schemes.

For this, MonoRail supports the idea of Dynamic Actions, which supports seamless attachment of actions to a controller.

Hammett describe them best:

image

DynamicActions offers a way to have an action that is not a method in the controller. This way you can “reuse an action” in several controllers, even among projects, without the need to create a complex controller class hierarchy.

The really interesting part in this is that we have both IDynamicAction and IDynamicActionProvider. This means that we get mixin-like capabilities.

Dynamic Actions didn't get all the love they probably deserve, we don't have the SmartDispatcherAction (yet), so if we want to use them, we will need to handle with the raw request data, rather than with the usual niceties that MonoRail provides.

Nevertheless, on a solid base it is easy enough to add.

Now all we need to solve is the ability to route the requests to the correct action, right? This is notepad code, so it is ugly and not something that I would really use, but it does the job:

public class ActionRoutingController : Controller
{
	public delegate IDynamicAction CreateDynamicAction();
	
	public static IDictionary<string, CreateDynamicAction> Routing 
		= new Dictionary<string, CreateDynamicAction>();
	
	protected override void InternalSend(string action, IDictionary actionArgs)
	{
		if(Routing.ContainsKey(action) == )
			throw new NoActionFoundException(action);
			
		Routing[action]().Execute(this);
	}
}

What this means is that you can now do this:

public void AddRoutedActions()
{
	AddRoutedAction("categories", "/categories/<name:string>", delegate {
		return  new IndexAction(new CategoryRepository(), "display_category");
	});
	
	AddRoutedAction("products", "/products/<name:string>", delegate {
		return new IndexAction(new ProductRepository(), "display_product");
	});
}

public void AddRoutedAction(string action, string url, CreateDynamicAction actionFactory)
{
	RoutingModuleEx.Engine.Add(
		PatternRule.Build(action, url, typeof(ActionRoutingController), action));
    
    ActionRoutingController.Routing.Add(action, actionFactory);
	
}

And get basically the same result.

Again, all of this is notepad code, just doodling away, but it is nice to see that all the building blocks are there.

Template Controllers

imageSharing common functionality across controllers is something that I have run into several times in the past. It is basically needing to offer the same functionality across different elements in the application.

Let us take for a moment a search page. In my current application, a search page has to offer rich search functionality for the user, the ability to do pattern matching, so given a certain entity, match all the relevant related entities that can fit this entity. Match all openings for a candidate. Match all candidates for an opening.

That is unique, mostly, but then we have a lot of boiler plate functionality, which moves from printing, paging, security, saving the query and saving the results, changing the results, exporting to XML, loading saved queries and saved results, etc, etc etc. Those requirements are shared among several

On the right you can see one solution for this problem, the Template Controller pattern. Basically, we concentrated all the common functionality into the Base Specification Controller.

What you can't see is that the declaration of the controller also have the following generic constraints:

image public class BaseSpecificationController<TSpecification, TEntity> : BaseController
	where TSpecification : BaseSpecification<TEntity>, new()
	where TEntity : IIdentifable

This means that the base controller can perform most of its actions on the base classes, without needing to specialize just because of the different types.

Yes, dynamic language would makes things much easier, I know.

Note that while I am talking about sharing the controller logic here, between several controllers, we can also do the same for the views using shared views. Or not. That is useful if we want to use different UI for the search.

In fact, given that we need to show a search screen, it is not surprising that we would need a different UI, and some different behavior for each search controller, to get the data required to specify a search.

Now that we have the background all set up, let us see what we can do with the concrete search controllers, shall we.

imageYou can see the structure of them on the right. The search candidates is doing much more than the search orders, but a lot of the functionality between the two is shared. And more importantly, easily shared.

Well, if you define the generics syntax above as easy, at least.

The main advantage of this approach is that I can literally develop a feature on the candidates controller, and then generalize it to support all the other searches in the application.

In this scenario, we started with searching for candidates, and after getting the basic structure done, I moved to start working on the search orders.

At the same time, another guy was implementing all the extra functionality (excel export, sending SMS and emails, etc).

After we I finished the search order page, we merged and refactored up most of the functionality that we needed in both places.

This is a good approach if you can utilize inheritance in your favor. But there is a kink, if you want to aggregate functionality from several sources, then you are going to go back to delegation or duplication.

Adam has interesting discussion about this issue, and an interesting proposition. But that will be another post.

Trusting the benchmark

imageI was scanning this article when I read noticed this bit.  A benchmark showing superior performance to another dynamic proxy implementation.  

I should mention in advance that I am impressed. I have built one from scratch, and am an active member of DP2 (and DP1, when it was relevant). That is not something that you approach easily. It is hard, damn hard. And the edge cases will kill you there.

But there are two problems that I have with this benchmark. They are mostly universal for benchmarks, actually.

First, it tests unrealistic scenario, you never use a proxy generation framework with the caching off. Well, not unless you want out of memory exceptions.

Second, it tests the wrong thing. DP2 focus is not on generation efficiency (it is important, but not the main focus), the main focus are correctness (DP2 produces verifiable code) and runtime performance. You only generate a proxy type once, this means that if you can do more in the generation phase to make it run faster at runtime, you do it.

Again, it is entirely possible that the LinFu proxies are faster at runtime as well, but I have no idea, and I don't mean to test those. Benchmarks are meaningless most of the time, you need to test for performance yourself.

Commercial support for Castle Windsor, Castle MonoRail, NHibernate, etc

This post by Ben Scheirman is interesting. He points out that the MS.MVC stuff is targeted toward a different crowd than the one who is using MonoRail, it is targeted toward the corporate developers and the All-Microsoft Shops.

The question of support has been raised again, and it prompted this post. It seems that there isn't a lot of awareness that there are commercial support options for those tools.

  • Castle Stronghold is the obvious place for commercial support for Castle.
  • JBoss / RedHat are offering commercial support for NHibernate. JBoss no longer support NHibernate.
  • We!* (Hebrew site) is offering commercial support for NHibernate and Castle.
  • Mindscape is offering commercial support for Castle.

I am actually not very interested in getting support for those, so it is entirely possible (and likely) that I missed some. Most of the active members of the community are members of consultancies that are capable offering support, but those are the one that I am aware of.

* Full disclosure: I work there.

Multiple parents in Cascading Drop Downs in MonoRail

Apparently I am suffering from the Bug Duplication Syndrom. Shortly after posting about cascading drop downs in MonoRail, I realized that I have actually duplicated a bug that I have run into while using the cascading drop down extender in the ASP.Net Ajax toolkit. That is not a fixable bug, btw, and has to do with what happens when you have more than a single parent. You can see my post about this scenario here, but be aware that the solution in that post is vulnerable to race conditions, and I have finally declared that unpracticle to use.

At any rate, I have duplicate the inability to have multiply parents in my previous solution using MonoRail. And I decided that instead of fixing it in place, I'll show the steps neccesary to fix the problem. Basically, we want to update both the secondaries select and the tertiaries select, which means that our GetSecondaryProfressionsByPrimary.brailjs will now contains:

page.Replace( 'secondaries',
    Form.Select('secondaries',SecondaryProfessions,
        {@value: @Id, @text: @Name, @firstoption: res.Select})           
)
page.Replace( 'tertiaries',
    Form.Select('tertiaries',TertiaryProfessions,
        {@value: @Id, @text: @Name, @firstoption: res.Select})           
)
page.Call( @hookSecondariesChangeEvent );

And that the GetSecondaryProfressionsByPrimary action is now:

public void GetSecondaryProfressionsByPrimary(Guid id)
{
	PropertyBag["SecondaryProfessions"] =
		professionRepository.FindSecondariesByPrimaryIdOrAll(id);
	PropertyBag["TertiaryProfessions"] =
		professionRepository.FindTertiariesByPrimaryIdOrAll(id);
}

Oh, and that was it.

Cascading Drop Downs in MonoRail

I just had this need, and I decided to explore what I could do without referring to what other people has already done. There are probably better ways, but this one has tickled my fancy.

Anyway, the idea here is to display three levels of hierarchy in a profression. Here is the HTML:

<table>
	<tr>
		<td>
			${res.PrimaryProfession}
		</td>
		<td>
			${Form.Select("primaries",PrimaryProfessions, 
{@value: @Id, @text: @Name, @firstoption: res.Select}) } </td> <td> ${res.SecondaryProfession} </td> <td> ${Form.Select("secondaries",SecondaryProfessions,
{@value: @Id, @text: @Name, @firstoption: res.Select}) } </td> <td> ${res.TertiaryProfession} </td> <td> ${Form.Select("tertiaries",TertiaryProfessions,
{@value: @Id, @text: @Name, @firstoption: res.Select}) } </td> </tr> </table>

This is not very fancy, and the CSS guys would be all over me for using a table, but let us leave that aside. Basically, we render three select elements. Now, let us see the server side, shall we?

public void Index()
{
	PropertyBag["PrimaryProfessions"] =
		professionRepository.FindAllPrimaries();

	PropertyBag["SecondaryProfessions"] =
		professionRepository.FindAllSecondaries();

	PropertyBag["TertiaryProfessions"] =
		professionRepository.FindAllTertiaries();
}

The ProfressionRepository uses Repository<T> internally, I want to avoid using Repository<T> directly in my controllers. Now, we need to actually respond to change events on the client side:

$j(document).ready(function()
{
	$j('#primaries').change(function()
	{
		$j.ajax({ 
			url:'GetSecondaryProfressionsByPrimary.ashx',
			data: { id: $j('#primaries').val() },
			dataType: 'script'
		});
	});
	hookSecondariesChangeEvent();
});

function hookSecondariesChangeEvent()
{
	$j('#secondaries').change(function()
	{
		$j.ajax({ 
			url:'GetTertiaryProfressionsBySecondary.ashx',
			data: { id: $j('#secondaries').val() },
			dataType: 'script'
		});
	});
}

This is done using jQuery, to hook the events and issue Ajax requests to the server when they are done. Note that I am registering the seconderies change event in a separate function, it will be soon clear why.

Now, how does the server handles this?

public void GetSecondaryProfressionsByPrimary(Guid id)
{
	PropertyBag["SecondaryProfessions"] =
		professionRepository.FindSecondariesByPrimaryIdOrAll(id);
}

public void GetTertiaryProfressionsBySecondary(Guid id)
{
	PropertyBag["TertiaryProfessions"] =
		professionRepository.FindTertiariesBySecondaryIdOrAll(id);
}

So we just pass the parameters to the repository, which does all the work for us, in this case, getting the children if the id is valid, or all if it isn't. Now let us move to the relevant views, shall we? We are using BrailJS here, so here is GetSecondaryProfressionsByPrimary.brailjs:

page.Replace( 'secondaries', 
	Form.Select('secondaries',SecondaryProfessions, 
		{@value: @Id, @text: @Name, @firstoption: res.Select})			
)
page.Call( @hookSecondariesChangeEvent );

As you can see, I ask the page to replace the element secondaries with the newly rendered select element. I then acll the hookSecondariesChangeEvent function, since I actually replace the entire element, and not just its content. I am doing this because I don't feel like extracting the part that renders just the options from the Form.Select() method, but I will probably will the next time I need it.

The GetTertiaryProfressionsBySecondary.brailjs is actually simpler:

page.Replace( 'tertiaries', 
	Form.Select('tertiaries',TertiaryProfessions, 
		{@value: @Id, @text: @Name, @firstoption: res.Select})			
)

Again, there are probably betters way, but this is the one I just came up with.

Handling javascript localization in Mono Rail

I run into the issue of having to alert the user of some error, and it brought home the fact that English & Hebrew are not easy to mix. In fact, code such as this is consider a very bad sign, usually code that you don't really want to touch, see or believe in:

image

So, we need some sort of a way to externalize those strings, even if the only language that this application is going to use is Hebrew, simply because of the pain of mixing the two together.

After thinking about it for a while, I decided to create this view (JavascriptResources/index.brail):

<%
for de in controller.Resources:
	resourceName = de.Key
%>
	var ${resourceName} = {
	<% for item in GetParameter(resourceName): %>
		${item.Key}: '${item.Value.Replace("'","\\'") }',
	<% end %>
		Empty: ''
	};
<%
end
%>

And here is the definition of the controller:

[Resource("Processes", "MyApp.Resources.Javascript.Processes")]
[Resource("Errors", "MyApp.Resources.Javascript.Errors")]
[Resource("Messages", "MyApp.Resources.Javascript.Messages")]
public class JavascriptResourcesController : Controller
{
	public void Index()
	{
		
	}
}

But what the hell does this do, anyway? Not much, actually, but it will iterate over all the registered resources for the controller, and output something that looks like this for each of those resources:

var Processes = {
 	EmploymentType: 'Employment Type',
	Details: 'Details',
	Dates: 'The dates',
	Empty: ''
};

The nice thing is that I can now write: alert(Errors.RecursiveError);*. As a side affect (as I said, the application is just in Hebrew so I don't care about that much), I also get the usual benefits of localization.

* You have to read Hebrew to get the joke, I am afraid.

Open Source & Forking

Joe raises an interesting question as a result of my post about Dunn & Churchill forking a commercial version of Active Record. I mentioned that I am alright, personally, with this behavior, and he asks:

Why would you be alright with that? Hammett, yourself and others have put countless hours in to the project and then these two dopes repackage and sell your work. I understand that legally it may be OK, but it doesn't pass muster in any way at all ethically.

We have two different things going on here at once.

I certainly don't like it, I would much rather that instead of selling "DunnChurchill.Data.DiamondBinding.ActiveRecord", which is a copy of Castle ActiveRecord, they would package their product with Castle ActiveRecord. Just in terms of allowing their users to know that they can go to the Castle Forums and ask a question, or google for a question regarding that, it would be a significant difference. Quite a side from the matter of giving credit where it is due.

But, and this is important, when I worked on Castle, I explicitly decided that my contributions should go under an open source license. Let us look at the definition of that, shall we? Here are the two relevant clauses for this discussion:

1. Free Redistribution

The license shall not restrict any party from selling or giving away the software as a component of an aggregate software distribution containing programs from several different sources. The license shall not require a royalty or other fee for such sale.

3. Derived Works

The license must allow modifications and derived works, and must allow them to be distributed under the same terms as the license of the original software.

Most often, the discussion of open source revolves around the free redistribution (well, just the free part of it :-) ), but derived work is just as relevant.

If we go to the Apache license, which is what Castle is released under, we will find:

2. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

So, this it where I (Contributor) grants you the rights to do a whole lots of things on Castle and any derived work from it, in both source and object form. Section 4 of the same license deals with the steps you must take to ensure that you have the right to redistribute, and from a cursory glance, it looks like Dunn & Churchill has done what they are required to do.

Let us go over it again:

  • The OSS definition allows it, in fact, it sees it as a core part of what OSS is about.
  • The specific license allows it.
  • I have agreed to both of those when I contributed.

I don't think that after saying:

  • You can redistribute this software and/or your modifications.
  • You can use this software in commercial products.

We can also add, but if you do all both we will be angry. There is no stealing involved, because it is allowed.

Now, all of that said, I mentioned already that I don't like it. I don't like it because while it is permitted, is it usually not... done. Perhaps I should say that it is not polite to do so? I think that this is a good distinction, it is legal, but not polite. It is certainly not the Right Thing To Do as far as I am concerned.

There are reasons for forking a code base, which move from politics and personal vendettas to disagreeing about code styles to stagnated project or actual wishing to take a code base in a different direction. Without commenting on the validity of these, and keeping in mind that I don't personally like forking in general, all of the above are considered "normal" reasons for forking.

Usually a fork die off, or the parent project die off, but those are what considered to be the acceptable reasons for forking. Forking in order to change the name and sell the product is not, in my opinion, an acceptable reason. Mainly because as far as I can see, the only reason to do that was to be able to package the whole thing under their name.

The value added in this product is the VS integration, I would imagine, and I doubt that any would have a problem with them selling such a product if they kept using Castle ActiveRecord. As it is, it looks like they are trying to offer in their product more than they actually have built, probably because there isn't that much of a need for VS integration alone.

In short, legal, but not polite, and it goes quite outside the usual accepted practices of what you can usually do. I am fine with it because when I contributed, I agreed what can be done legally to my contributions, not just what is considered accepted. Nevertheless, I still don't like it, and I have no problem holding both opinions at the same time.

Imitation is the sincerest form of flattery

Well, I guess that Castle Active Record just a whole shower of flattery. This was just posted to the Castle Forums, apparently Dunn & Churchill have a product called Diamond Binding that looks very much like Castle Active Record.

There is a code project article about it here, and from the API and the license files, it looks like they have taken the Castle Active Record source and repackaged it.  Now, this is allowed by the license, and this is something that I am perfectly fine at.

It looks like they did some nice things with VS integration, but that is just looking at their example, I haven't installed it.

Active Record & MonoRail web casts

Here are the rehearsal sessions for Hammett & me at JAOO. Hammett has just published them. Not anything really new, frankly, and the quality is all over the spectrum. I was having a nasty case of the flu, especially on the MR screen cast, and that one was recorded close to midnight.

You can see me recording the screen cast, that is a weird movie, I tend to move a lot when I talk, but I don't think Hammett's laptop was very impressed. Ten points if you can find the part when I kicked it.

Random Impressions from JAOO: Web Forms on the Enterprise

When Hamilton and me gave the MonoRail talk to the Enterprise Application track, we asked how many people were .NET vs JAVA vs Ruby. The results where roughly 43%, 43% and 4%, respectively.

The interesting part was when I asked how many of the .NET guys used Web Forms, almost all of them said that they do. Then I asked how many enjoyed using Web Forms.

No one raised their hands.

Refactoring MonoRail Views

imageAs I mentioned, I build a very quick & dirty solution to display a collection of scheduled task descriptions. The end result looked like this:

image

This works, and it should start producing value as of next week, but I didn't really like the way I built it.

Here is the original view code:

<table cellspacing="0" cellpadding="0">
	<thead>
		<tr>
			<th>
				Name:</th>
			<th>
				Occurances</th>
			<th>
				&nbsp;</th>
		</tr>
	</thead>
	<tbody>
		<% for task in tasks: %>
		<tr>
			<td>
			${Text.PascalCaseToWord(task.Name)}
			</td>
			<td>
			Every ${task.OccuranceEvery}
			</td>
			<td>
			${Html.LinkTo("Execute", "ScheduledTasks", "Execute", task.FullName)}
			</td>
		</tr>
		<% end %>
	</tbody>
</table>

This work, it is simple and easy to understand, but it still bothered me. So I replaced it with this:

<% component SmartGrid, {@source: tasks}  %>

Well, that was much shorter, but the result was this...

image

I am cropping things, because it is a fairly long picture, but it should be clear that this is not a really nice UI to use.

This was my second attempt;

<% component SmartGrid, {@source: tasks, @columns: [@Name, @OccuranceEvery] }  %>

And it produced this:

image

Better, but not really that much, let us try to have nicer names there, shall we?

<% 
component SmartGrid, {@source: tasks, @columns: [@Name, @OccuranceEvery] }:  
	section Name:
	%>
	<td>${Text.PascalCaseToWord(value)}</td>
	<%
	end
end
%>

And this produced:

image

That is much better on the name side, but we still have the "Occurance Every" column to fix...

<% 
component SmartGrid, {@source: tasks, @columns: [@Name, @OccuranceEvery] }:  
	section OccuranceEveryHeader:
	%>
	<th>Occurances</th>
	<%
	end
	section Name:
	%>
	<td>${Text.PascalCaseToWord(value)}</td>
	<%
	end
	section OccuranceEvery:
	%>
	<td>Every ${value}</td>
	<%
	end
end
%>

With the result being:

image

One last thing that we have left is the additional column at the end, we can manage it like this:

<% 
component SmartGrid, {@source: tasks, @columns: [@Name, @OccuranceEvery] }:  
	section OccuranceEveryHeader:
	%>
	<th>Occurances</th>
	<%
	end
	section MoreHeader:
	%>
	<th></th>
	<%
	end
	section Name:
	%>
	<td>${Text.PascalCaseToWord(value)}</td>
	<%
	end
	section OccuranceEvery:
	%>
	<td>Every ${value}</td>
	<%
	end
	section More:
	%>
	<td>${Html.LinkTo("Execute", "ScheduledTasks", "Execute", item.FullName)}</td>
	<%
	end
end
%>

So here is the final result:

image

Now that I did that, I am looking at both pieces of code and wondering:

  • What is the fuss about, anyway?
  • Which of those versions is more readable?

Granted, this is a fairly specialized case, but in terms of LoC, the second approach is actually longer, and the "major" benefit here is that I get less HTML in the view, but that is not a really major consideration.

The SmartGrid would produce a pager if needed, but that about it with regards to the differences in their abilities.

Convention over configuration: Structured approach

Hammett has a post that made me think. He is talking about configuring Spring for Java and has this to comment:

I can’t understand this uncontrolled passion that java programmers carry for xml.

I can certainly agree with him about that, but I got to the same point a long time ago with Windsor. I had an application which was rife with components. I am talking about many dozens of generic (as in MyComponent<T>) components, all of which required registration in the config file, which got to be fairly annoying very fast.

I solved that by creating Binsor, a Boo DSL for configuring an IoC container. Initially, it was very similar to the Batch Registration Facility, but I pushed it much further, until today I do all my Windsor configuration using Windsor.boo, and its existence is a core part of my application architecture. Why? Because I can do things like this:

controllersAssemblies = (Assembly.Load("MyApp.Web"), Assembly.Load("Castle.MonoRail.ViewComponents") )
for asm in controllersAssemblies:
	for type in asm.GetTypes():
		continue if type.Name == "ScheduledTasksController"
		if typeof(Controller).IsAssignableFrom(type):
			IoC.Container.AddComponent(type.FullName, type)
		if not typeof(ViewComponent).IsAssignableFrom(type):
			IoC.Container.AddComponent(type.Name, type)

The immediate result of this type of behavior is that I don't have any weight of the IoC, I just develop as I would normally would, and it catches up with everything that it needs to handle.

I recently had the chance to maintain a MonoRail application that used XML for configuring Windsor, and by the third time that I added a controller, I was pretty annoyed. Each and every time, I had an additional step to perform before I could run the code. Compared to the approach that I was using, it was hardly zero friction.

Of course, my approach is not flawless in any mean, there is a bug in the configuration above, can you spot it?

The point of this post, which I have been trying to get to for a while, while random electrical pulses moved my fingers in interesting ways, is that I have began not only to use this to a great extent (all projects in the last year or so are based on this idea), but I have started to actually design with this in mind.

The end result right now is that I am relying a lot more on commands patterns and attributes for selections. This means that I often do things like:

[SelectionCriteria(Selection.FirstOption, Selection.SecondOption)]
public void SomeSpecficCommand : Command<ObjectActingUpon>
{
	public override void Execute()
	{
	}
}

You can see a more real world sample here, but the idea is to declaratively express the intent, have the configuration figure out what I want, and make it happen. The nice thing, most of the time, It Just Works. And the nice thing about utilizing Binsor is that I can adapt the convention very easily. So I can have many nice conventions, each for a particular situation.