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,260
Privacy Policy · Terms
filter by tags archive
time to read 5 min | 893 words

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.

time to read 3 min | 570 words

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.

time to read 2 min | 223 words

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.

time to read 1 min | 184 words

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.

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 5 min | 886 words

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.

time to read 1 min | 112 words

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.

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