Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,264
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 222 words

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.

time to read 3 min | 594 words

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.

time to read 2 min | 281 words

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.

time to read 1 min | 99 words

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.

time to read 1 min | 71 words

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.

time to read 4 min | 756 words

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.

time to read 3 min | 494 words

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.

time to read 3 min | 477 words

I need to develop a set of tasks that would run in internals. Now, we need to do several dozens of those, and at that point, it is not important how we actually schedule them, we can defer that decision. But we really need to be able to start develop them soon.

So, I came up with this idea. The basic structure is this:

[OccuresEvery(Occurances.Day)]
public class SendBirthdayEmails : ScheduledTask
{
	public override void Execute()
	{
		foreach(Employee emp in Repository<Employee>.FindAll(Where.Employee.Birthday == DateTime.Today)
		{
			Email
				.From(Settings.Default.HumanResourcesEmail)
				.To(emp.Email)
				.Template(Templates.Email)
				.Parameter("employee", emp)
			.Send();
		}
	}
}

This is not really interesting, but the rest is. Remember that I don't want to deal with deciding how to actually schedule them, but we need to be able to run them right now for test / debug / demo purposes.

In my windsor.boo:

//Controllers
controllersAssembly = Assembly.Load("MyApp.Web")
for type in controllersAssembly.GetTypes():
	continue if type.Name == "ScheduledTasksController"
	continue if not typeof(Controller).IsAssignableFrom(type)
	IoC.Container.AddComponent(type.FullName, type)

//register scheduled tasks
scheduledTasksAssembly = Assembly.Load("MyApp.ScheduledTasks")
scheduledTasks = []
for type in scheduledTasksAssembly.GetTypes():
	continue if not typeof(ScheduledTask).IsAssignableFrom(type)
	IoC.Container.AddComponent(type.FullName, type)
	scheduledTasks.Add(type)
//register scheduled tasks controller independently, since it requires special configuration 
Component("ScheduledTasksController", ScheduledTasksController,
	scheduledTasks: scheduledTasks.ToArray(Type) )

So it will automatically scan the scheduled tasks assembly, and the only thing that I have left is to write the ScheduledTasksController. This is a very simple one:

image

It has just two methods, one to list all the tasks, and the second to execute them. This is strictly a dev only part of the application, so I took most of the available shortcuts that I could. So the UI looks like this:

image

And the view code is:

<% 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 %>

I really like the PascalCaseToWord helper, really nice.

On the controller's side of things, I have this:

public ScheduledTasksController(Type[] scheduledTasks)
{
	scheduledTaskDescriptions = new ScheduledTaskDescription[scheduledTasks.Length];
	for (int i = 0; i < scheduledTasks.Length; i++)
	{
		scheduledTaskDescriptions[i] = new ScheduledTaskDescription(scheduledTasks[i]);
	}
}

public void Index()
{
	PropertyBag["tasks"] = scheduledTaskDescriptions;
}

Not a best practice code, but I did knock the whole thing very quickly. ScheduledTaskDescription just takes a type and unpack it in terms of attributes, name, etc.

The end result is that the other developers on my team can add a new scheduled task by simply adding a class that inherits from ScheduledTask, go to the browser, hit F5 and start executing it.

Now that is RAD.

time to read 7 min | 1349 words

Mats Helander is in love with WebForms, and he explains why. I think that I have already explained why I don't agree with that, but allow me to go over his points. One important thing to notice is that Mats ignore the problem of "WebForms tries to be WinForms", because, as he says, that is usually an issue raised to explain the root cause WebForms problems.

I think that this is a mistake, because the rest of the problems in WebForms are non as critical as the issue of trying to be WinForms. And the main problem there is state. The web is stateless, windows is stateful. Once you break that basic concept, you already in a world of hurt.

I am much more in love with the WebForms model, which in my opinion is beautiful, efficient, powerful, flexible, scalable, portable, un-obtrusive, perfect for spitting out html, has a really well designed page lifecycle and it jives very nicely with MVC thank-you-very-much

image I was going to try to formulate an answer to that myself, but I think that I will let Mats' own word handle that:

The WebForms page lifecycle model is too complex to wrap your head around

Well, ok, it is.

But it is also really, really good. I freely admit that whenever I need to do something more complex than implement Page_Load and the event handlers of controls, I get totally lost. But when I eventually get it to work – by luck, swearing and occult sacrifice – I must admit I am impressed with the results.

And after saying that, you still think that you can call it good?! That is my definition of Hell. Building software should be predictable, maintainable and obvious. I don't have an issue with learning complex stuff, but needing occult sacrifice (which I have felt the need as well) to get it to work is out of the question. To quote Paul Graham:

It's pretty easy to say what kinds of problems are not interesting: those where instead of solving a few big, clear, problems, you have to solve a lot of nasty little ones. One of the worst kinds of projects is writing an interface to a piece of software that's full of bugs. Another is when you have to customize something for an individual client's complex and ill-defined needs. To hackers these kinds of projects are the death of a thousand cuts.

Sorry, just that is enough to keep me away from WebForms.

Mats then talks about using the DOM that WebForms provides:

Say that you were asked to implement the following method:

     public string SerializeToXml(Employee employee);

There are two obvious ways to do this:

StringBuilder

Using a StringBuilder object (or a plain string) you simply build up the xml as a string, doing things like stringBuilder.Append(“[name]” + employee.Name + “[/name]”);

XmlDocument

Using an XmlDocument object you build up your xml as a Document Object Model (DOM), doing things like xmlNodeEmployee.ChildNodes.Append(xmlNodeName);

When asked to implement the following method, you have the same basic choice:

     public string SerializeToHtml(Employee employee);

You can either use a StringBuilder and just build up the html as a string, or you can build up a DOM representation of your html.

imageMu! I can also do the smart thing and use a templating language. Using XmlDocument to generate XML is tedious in the extreme, because the DOM is built to the document model, not to ease the way we build XML. There is a reason why Orcas has a whole new set of ways to work with XML, because going the DOM approach is just too awkward.

As anyone who has ever worked with AST / DOM can tell you, just because it is the way the computer thinks that way, it does not means that this is the best way to generate it. If I wanted to generate XML, I would much prefer to use something like BooML than XmlDocument. Take a look at the differences:

[XmlLiteral()]
def GetBooksXml(books):
    books:
        for book as Book in books:
            book:
                @id = book.Id
                title book.Title
                author book.Author

The same goes for generating HTML. The DOM is a very awkward way to handle it.

 Mats then raise several cases where having a DOM is useful. Multiply outputs and wanting to delete an existing node after the fact are two of the issues he raises, he then says:

The problem, in my view, with going with a platform that doesn’t offer the flexibility of a DOM is that you don’t have the option the day it would become useful.

I would say YAGNI to that, while adding that if you want it, it is already there. In MonoRail it is DSL Support for Brail, in Ruby on Rails it is Haml. Here is how it looks like:

<?brail
dsl Html:
	body:
		component SmartGridComponent, {"source" : names}
	end
end
?>

Right now it does direct calls to HTML, but it is trivially possible to add HtmlDOM implementation, and handle that.

Mats has this to say on the page lifecycle complexity issue:

So my response to this accusation is to say that the complexity is usually hidden from the application developer.

Really? Take a repeater and put a button in the ItemTemplate, with an OnClick handler to a method. Now DataBind it, send it to the client, and press on one of those buttons. A postback occurs, but the event is not raised. Why?

This is just one of several hundreds of examples that I have where, as an application developer, I need to intimately understand the page lifecycle model and how it affects me. I don't really think that you can say that that an app dev is free from having to always deal with that on all but the simplest page.

imageHere is another telling statement:

Since it is too complex for me to understand, I really couldn’t make a judgment

Mats wrote an OR/M  implementation, which is one complex piece of software. I have a lot of personal respect for that, since I know what is involved in making such an effort. If he can't grasp the page lifecycle, what is the chance that most developers would be able to?

 WebForms and MVC

I have talked about the issues that WebForms MVC has extensively here, but I can surmise it simply as: There is no way for the controller to know that a user has pressed a button without the view being involved, or to build a Controller that doesn't need to be modified to fit the page lifecycle.

You can see how I think about the flow of a request using an MVC platform in the image. Notice that the view is the last thing that is involved, since it is not an important player until the very very end.

One thing that come up as a result of that is that a lot of the DOM manipulation games that Mats talks so much about are simply not necessary when you are using an MVC architecture, it is not needed because you know, in advance of building the view, exactly what you need to do.

I have done extensive work in this area, and my conclusion is that it is simply not possible to get separation from the view layer in WebForms, it is built into the platform, and cannot be changed.

Conclusion, while Mats may have intended to support the WebForm model, but I think that he had managed to bring up the points where using WebForms hurts.

And, as the joke says, stop doing that.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...