Hacker News new | past | comments | ask | show | jobs | submit login

The accumulation of abstraction layers is an architectural problem, not a result of statically typed languages. The issue here is the author plainly doesn't understand the unit of work pattern and has made an awful technology choice (EF).

In the case provided, the whole thing was just an architectural mess.

There should be one abstraction which is the transaction and unit of work boundary in the form of a service layer so the application looks like:

controller <--> service <-> model/repository

The transaction and unit of work boundary above is inside the service. This should be entirely controlled by framework/container or chucked in there manually (see example below).

The model/repository should pretty much be whatever the native ORM interface is. it ain't worth abstracting it for shit as you're not going to change it, ever. In the case of NHibernate, which I'd recommend over anything else, your code would look like:

   class UserService {
       // ... DI crud here.
       public BooleanResult AddUser(UserTransferObject userTransferObject) {
           // Validate shit here

           // Create shit
           using (var session = sessionFactory.OpenSession()) // UOW boundary
           using (var trans = session.BeginTransaction()) // Transaction boundary
           {
               var user = User.CreateFromTransferObject(userTransferObject);
               session.Add(user);
               trans.Commit();
               return BooleanResult.Success();
           }
       }
   }

This model can be applied to pretty much everything from API endpoints, web app endpoints, message bus endpoints, queue endpoints, SMTP endpoints. You name it, without having to piss around and let your abstraction leak into the controllers.

You can add a repository abstraction in there as well if you really fancy it but I wouldn't bother.




EF really isn't that bad anymore, the 1.0 times were rough but it's gotten much better.

I agree with your your example though, as well as your point about the model/repository being whatever the native ORM interface is. If you're using EF and you REALLY thought you might swap it out later for something else you could always use its POCO mode so you would at least have your business objects intact and reusable.


Thanks for your comment! Did I have a choice about what ORM I used? No

I agree about your approach regarding a service in a larger app but in a smaller app I have come to the conclusion today that IDBContext injected into a controller would be better than a repo, as you say you arent going to change ORMs in reality and it exposes the native functionality of your ORM.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: