Ayende @ Rahien

Hi!
My name is Ayende Rahien
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

@

Posts: 5,949 | Comments: 44,545

filter by tags archive

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.


Comments

Shane Courtrille

The question then becomes how do you easily test this. I have always had a hard time testing things that had heavy inheritance. Or is that just me? :)

Ayende Rahien

Abstract Test Fixture is the answer to that, in my case.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. The RavenDB Comic Strip: Part III – High availability & sleeping soundly - 17 hours from now

There are posts all the way to May 28, 2015

RECENT SERIES

  1. The RavenDB Comic Strip (3):
    20 May 2015 - Part II – a team in trouble!
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats