Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,124 | Comments: 45,475

filter by tags archive

Taking a look at S#arp Lite–final thoughts

time to read 3 min | 490 words

This is a review of the S#arp Lite project, the version from Nov 4, 2011.

This project is significantly better than the S#arp Arch project that I reviewed a while ago, but that doesn’t mean that it is good. There is a lot to like, but frankly, the insistence to again abstract the data access behind complex base classes and repositories makes things much harder in the longer run.

If you are writing an application and you find yourself writing abstractions on top of CUD operations, stop, you are doing it wrong.

I quite like S#arp approach for querying, though. You expose things directly, and if it is ugly, you just wrap it in a dedicated query object. That is how you should be handling things.

Finally, whenever possible, push things to the infrastructure, it is usually pretty good and that is the right level of handling things like persistence, validation, etc. And no, you don’t have to write that, it is already there.

A lot of the code in the sample project was simply to manage persistence and validation (in fact, there was an entire project for that) that could be safely deleted in favor of:

public class ValidationListener : NHibernate.Event.IPreUpdateEventListener, NHibernate.Event.IPreInsertEventListener
    public bool OnPreUpdate(PreUpdateEvent @event)
        if (!DataAnnotationsValidator.TryValidate(@event.Entity)) 
            throw new InvalidOperationException("Updated entity is in an invalid state");

        return false;

    public bool OnPreInsert(PreInsertEvent @event)
        if (!DataAnnotationsValidator.TryValidate(@event.Entity))
            throw new InvalidOperationException("Updated entity is in an invalid state");

        return false;

Register that with NHibernate, and it will do that validation work for you, for example. Don’t try too hard, it should be simple, if it ain’t, you are either doing something very strange or you are doing it wrong, and I am willing to bet on the later.

To be clear, the problems that I had with the codebase were mostly with regards to the data access portions. I didn’t have any issues with the rest of the architecture.


Wayne M

I find it very interesting that so many developers still abstract away the CRUD functionality even when they don't have to.

I would still like to see more examples/discussion about the "query object" pattern, as I can't seem to find much in the way of concrete samples and it seems like a very good idea to start using.


@Wayen M I believe it is called the specification pattern


Maybe it would have been good to elaborate on a few more of the good points then Ayende?

Moses Fetters

I would love to see a discussion about the "query object" pattern and the pros and cons of using it.

I have read Fabio's take on it here http://fabiomaulo.blogspot.com/2010/07/enhanced-query-object.html


When's Ayende's framework (or best practice example solution) coming? :) Something that brings together all of what you've been critiquing lately into a concrete example of the "right way" to do things. I'm sure a lot of developers would be inspired by it. It would be a great service to the community and serve the same purpose the S#arp authors are providing. Not just critiquing but a concrete example and valid attempt to make the lives of us developers easier.



Did you find any benefits of using this framework? Querying is something that can easily abstracted using straight NHibernate.

John Farrell

@magelings: https://github.com/ayende

Robert O'Donnell

I wonder if rather than using a "framework" perhaps having a scaffolding that uses a bunch of libraries would be a better way to go...


magelings, he said specifically raccoonblog was built recently with these principles, so go look for that.

Bystrik Jurina

Your ValidationListener works nice in theory but what about integration in Asp.Net MVC validation pipeline? I also don't like some aspects of SharpArch. For example I don't like Tasks and I prefer Fluent Validation instead validation attributes, but I must defend the Repository pattern. NHibernate Session exposes at least 50 public properties and methods. WTF??? Session has stuff like Connection, Dispose(), ActiveEntityMode and so on. Such API should be used in Controller? I think generic Repository exposing IQueriable, Get adn Remove methods is very cheap pattern and it can be easily extended if neccessary.


raccoonblog uses ravendb...a document database. I was leaning more towards a best practice NHibernate example...

Christopher Wright

I quite like having validation wired into your ORM. Like DB constraints but usable. I'll keep that in mind next time I'm using NHibernate (though I presume Hibernate has something similar).

Granted, you need to have some nicer stuff in place in case of bad input, but that style of validation has the advantage of being all-encompassing.

Get Real


When's Ayende's framework (or best practice example solution) coming?

I hate to say it, but you just inadvertently outed yourself as a newbie. Dont worry though, it happens weekly, if not daily.

This guy is never going to do this. Remember MADCO, or MATCO, or whatever ?? Heck it's been so long I bet he even forgot the name. I few rough screen drawings and he lost interest.

It's much easier to dissect and destroy instead of laying your own footprints in the concrete - lest they be dissected by someone else.

Yawn, smack, smack, Ayende, arent you bored by reviewing other peoples work by now?

Tien Do

I don't know why people keep inventing these frameworks, did they just create these projects for their work and then made them open source later?

@Ayende: They asked you for a review e.g. this project, Ntier architecture from MS Spain etc., did you get their feedback later since there were many negative points?

P.S: I can't login by Goolge, the error is No OpenID endpoint found.


Ayende, I'm quite interested in using validation that way, as well as in another point from your previous post:

Extend the model binder so it would load the entity from NHibernate and bind to that instance directly.

I just opened up RacoonBlog to take a look at an example of those, but there's still

public ActionResult Add(UserInput input) { if (!ModelState.IsValid) return View("Edit", input); var user = new User(); input.MapPropertiesToInstance(user); RavenSession.Store(user); return RedirectToAction("Index"); } Which both uses validation right inside an action and AutoMapper to map user input to db-entity. And that's what I'm used to in my own projects, because view/input models usually differs at least a bit from what I have in DB. Could you please suggest an oss-example where principles that you've mentioned are used?


Sorry for ugly code formatting, it seems parser ate my line-breaks.

Bystrik Jurina

I think Ayendes post about SharpArch is harmfull. It creates sense that SharpArch is bad framework, but that is far from truth. Maybe it's not perfect, but it's still better than 90% of handroll solutions. And for example RacoonBlog has also code smells. Some controller methods are really fat. Nothing is perfect...

Lev Gorodinski

"Finally, whenever possible, push things to the infrastructure, it is usually pretty good and that is the right level of handling things like persistence, validation, etc."

I agree. However, one must be weary of creating needless abstractions in this way, as you caution. In fact I believe the repository abstraction and in particular the overly abstract LINQ specification pattern based repository results from an attempt to push things to infrastructure by detecting patterns in data access. Just like validation injected directly into the ORM is a result of the observation that the ORM persists entities, entities must be validated before persistence, so lets inject validation.


If they want to separate responsibilities like this, YOU HAVE TO use the DetachedCriteria construct. This would allow you to solve that need to include the child items to avoid the N+1 problem.

Billy McCafferty

@dotnetchris, actually, you don't have to use the DetachedCriteria. In fact, you can still use NHibernate directly if you find LINQ to NHibernate to be inadequate for any specific scenarios.

This provides as good as any opportunity to provide a couple of links to specifically address dotnetchris' concern, as well as discussion concerning my response to Ayende's series of posts on S#arp Lite:

  • Encapsulating NHibernate-specific calls within a custom repository - http://groups.google.com/group/sharp-lite/browse_thread/thread/c653325f5f61e46c

  • Why have a task layer? - http://groups.google.com/group/sharp-lite/browse_thread/thread/692c4baf1454cc

  • A direct response to the Ayende's review - http://groups.google.com/group/sharp-lite/browse_thread/thread/77a4ed0b857427b0

When it comes down to it; if S#arp Lite jives with the way you/your-team wants to develop, then consider using it. If it doesn't, then don't. ;)


What is the difference between repositories and queries? As I understand they are both use NHibernate in this sample. So they are both abstraction over abstraction.

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.5 whirl wind tour: You want all the data, you can’t handle all the data - 10 hours from now
  2. The design of RavenDB 4.0: Making Lucene reliable - about one day from now
  3. RavenDB 3.5 whirl wind tour: I’ll find who is taking my I/O bandwidth and they SHALL pay - 2 days from now
  4. The design of RavenDB 4.0: Physically segregating collections - 3 days from now
  5. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 4 days from now

And 14 more posts are pending...

There are posts all the way to May 30, 2016


  1. RavenDB 3.5 whirl wind tour (14):
    29 Apr 2016 - A large cluster goes into a bar and order N^2 drinks
  2. The design of RavenDB 4.0 (13):
    28 Apr 2016 - The implications of the blittable format
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series



Main feed Feed Stats
Comments feed   Comments Feed Stats