Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET ORMs need virtual, and can't deal with sealed?

I am just getting started with .NET ORMs, to the point where I haven't even decided between Entity Framework and NHibernate. But in both cases, I'm running into a problem in that they seem to want me to compromise the integrity of my domain model in various ways, especially on finer points of C# object design. This is one of several questions on the subject.


There is a reason virtual is not the default for methods in C#. The objects in my domain model are not prepared to make promises about the behaviors of subclasses, except in very specific cases where I mark them as such. Put another way, for very few methods on my domain objects is it appropriate to add a hook for unspecified new functionality.

Yet NHibernate wants me to make everything virtual, and Entity Framework wants me to make all entity references virtual. I realize why they need it (to create proxy objects), and I realize it's actually a legitimate use of inheritance and virtual---they actually are hooking in to my properties in order to add new functionality. But it grates on me that I have to annotate my domain model classes with something that is entirely about persistence, and not at all expressive of their actual contract to implementers and consumers.

As a smaller issue, which I realize I probably cannot do anything about, often it is expressive to annotate my classes with sealed for all the usual reasons. This is a bit less grating though, since omitting an annotation from my domain objects for the purpose of persistence seems less bad than adding one.


It is frustrating that after several years reading books like Effective C# or blogs like those of Eric Lippert, which give great advice on how to design expressive and bulletproof C# objects, the need to use ORMs is making me throw much of that knowledge out of the window. I am hoping that someone here can point out where I am wrong, either in my grasp of their capabilities or in my thinking about domain modeling and the role of ORMs.

like image 701
Domenic Avatar asked Mar 19 '11 19:03

Domenic


People also ask

Can sealed class have virtual methods?

A sealed class cannot be used as a base class, and a virtual method has to be implemented in a derived class, which is a contradiction.

Can virtual method be sealed in C#?

You can override a virtual method or property and seal it so that it cannot be overridden further in the inheritance hierarchy. That is the use of sealed methods.

Can we instantiate sealed class in C#?

A sealed class, in C#, is a class that cannot be inherited by any class but can be instantiated. The design intent of a sealed class is to indicate that the class is specialized and there is no need to extend it to provide any additional functionality through inheritance to override its behavior.

Why sealed class is used in C#?

sealed (C# Reference) This enables you to allow classes to derive from your class and prevent them from overriding specific virtual methods or properties.


2 Answers

It's not just .NET ORMs - the same constraints apply to Java ORMs as well.

Though, in Java, everything is virtual unless you explicitly declare otherwise, so the need to satisfy the ORM is much like the situation you're finding with sealed:

omitting an annotation from my domain objects for the purpose of persistence seems less bad than adding one.

What it boils down to is this: Persistence Ignorance is a worthwhile goal, but it's not one that can be 100% achieved unless you're willing to also ignore minor details like memory load and performance as well.

If memory load and performance are of no concern, stop using proxies and require all your objects to be fully populated as soon as they're hydrated - NHibernate can do this through config. The side effect will be that all related objects will be loaded in one go, so you'll end up with most of the database loaded into memory. The app will need a lot of memory and take a lot of time to start up - but it'll work.

Persistance is a leaky abstraction - while you can hide most of it behind the curtain, there will always be elements that leak into other areas of your application.

like image 91
Bevan Avatar answered Sep 21 '22 14:09

Bevan


How to put this gently.... Sorry, I can't. Get over it.

I agree with you 100%, but using frameworks always means compromise. Don't want to compromise? Build it yourself. That's really all there is to it.

To be a little less antagonistic, There is a solution to your problem, and that's to use something like automapper to translate between your leaky persistence subystem and the rest of your application. Basically, you keep your domain model clean and tidy and designed exactly the way you like, and then use a translation layer to map between it and your nasty, ugly ORM.

But, that's really a lot of work. And for the small amount of purity you give up you save a lot of effort.

like image 38
Erik Funkenbusch Avatar answered Sep 21 '22 14:09

Erik Funkenbusch