My favorite NHibernate exception

We have a rather large, connected domain model, so we use quite a bit of lazy loading to deal with the richness all these connections provide.  The one thing I would have liked C# to get from Java is “virtual by default”, if only for one selfish reason: so I don’t see this exception ever, ever again:

The following types may not be used as proxies:
Project.Domain.Model.Customer: method GetFavorites should be ‘public/protected virtual’ or ‘protected internal virtual’

I always forget to mark members as virtual, and I still haven’t hunted down all of the templates and code snippets that spit out class members and fixed them.  “Virtual by default” isn’t just about testability.  It’s about the false assumption that we can predict exactly how end users want to use our API.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in C#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • superbecio

    lol, I just incurred in the same mistake! My problem now is to fix things like this:

    public virtual int Id
    get {return _id;}
    internal set {_id = value;} // wrong must be protected virtual

  • Ray

    Oh yes, ditto here. Guess this is a case when “RTFM!!111″ is so important.

  • Nick

    I could have been in a dream, but I vaguely remember reading a post where Ayende actually said NHibernate didn’t require virtual methods anymore and he just hasn’t gone in and removed the check yet.

  • Allen P

    Totally agreed, that exception is really irritating.

  • “Virtual by default” has nothing about testability, probably if you have to put your objects in “not expected” state (by overriding parts of the object) you are wasting time on testing syntetic or impossible stuff. This actually the same antipattern as testing private methods with reflection.

    Regarding “false assumption”, well, so your point of view is not to think at all? Overridability is some sor of the selfdocumentaiton, means that when you have code with all overridable members, you do not know where to extend it.

    Hope this makes sence.

  • I’m still a bit torn over virtual by default – many methods almost never make sense to override.

    What I would like though is a class keyword to make all members of that single class virtual :-)

  • You can actually turn off the “virtual by default” option in the NHibernate source code. I had to do this once before, it is in the central configuration class. Sorry I cant remember the actual name of this class of the top of my head, but there is a main configuration class that holds all kinds of interesting default settings!