My project is layered as follows:-
DAL (Entity) --> BLL (DTO) --> ApplicationComponent (ViewModel).
There will be multiple components of application (ApplicationComponent) which will access BLL. Components include windows services, web services, web API and MVC controller.
I am transforming NHibernate Entity objects to DTO objects while passing them from DAL to BLL. While passing this state to ApplicationComponent, BLL again converts it to ViewModel.
This helps me separate the concerns and how data is handled in each layer. I am not in favor of returning NHibernate Entity object to view for following reasons: -
Data get exposed to UI that I want to hide (or only expose if needed) like passwords, user type, permission etc.
On references/joins, NHibernate executes additional queries when property is accessed which nullify the use of lazy loading.
Unnecessary data exposed to user (of Entity) creates confusion and gap for bugs.
Persistence implementations leaking into BLL/UI. Entity is not designed for UI. It cannot serve UI in all cases.
We use attributes on DTO properties for user input validation which looks odd with Entity.
I am facing following problems with this approach: -
Biggest and obvious problem is redundant objects with similar members and functionality.
I have to write mapper methods in each layer to transform object. This could be minimized by using AutoMapper or something similar; but it does not fully resolve problem.
Questions:-
Is this an over separation and should be avoided (at least minimized)?
If this approach is correct, I do not see any simple way to fully bypass two problems I stated above. Please suggest.
If this approach is incorrect, please suggest corrections.
References:-
Link1 suggests to transfer Entity object to view which in my understanding not a good idea.
Link2 suggests to map Entity with DTO that I am already doing.
Link3 does not help.
Link4 suggests using something like auto mapper tools which is OK. But it still does not solve the problem completely.
Link5 is great post. It explains why those should be separate which I agree. It does not comment on how to minimize the overhead caused by it.
Link6 is not helpful again.
Link7 is an excellent answer which suggests use Entity as is in UI if possible. It still does not apply to most of my project.
Linl8 is another excellent resource that suggest to go on mapping two way as I am doing now. It still does not suggest a way to minimize overhead.
Have you considered creating a shared interface between the DTO and the Entity? You should not tightly couple your ORM to the rest of your application. Or in fact use anything other than interfaces between them if at all possible.
You could, in theory, have a separate project that just holds the contract/abstractions of what you expect to be passed around. To minimize mapping overhead and to leave it open for the extension you can ensure that the entity implements the interface as expected (omitting what is not needed), and in cases where you need a bespoke DTO you can create a model with mapping using the interfaces.
There is some overhead when adding extra interface projects but it will keep your code cleaner and more maintainable in the long run.
namespace Data
{
public class FakeRepo : IFakeRepo
{
public IThisIsAnEntity GetEntity()
{
return new ThisIsAnEntity();
}
}
public class ThisIsAnEntity : IThisIsAnEntity
{
public string HiddenField { get; set; }
public long Id { get; set; }
public string SomeField { get; set; }
public string AnotherField { get; set; }
}
}
namespace Data.Abstractions
{
public interface IFakeRepo
{
IThisIsAnEntity GetEntity();
}
}
namespace Abstractions
{
public interface IThisIsAnEntity : IThisIsAnSlimmedDownEntity
{
string SomeField { get; set; }
}
public interface IThisIsAnSlimmedDownEntity
{
long Id { get; set; }
string AnotherField { get; set; }
}
}
namespace Services.Abstractions
{
public interface ISomeBusinessLogic
{
IThisIsAnEntity GetEntity();
IThisIsAnSlimmedDownEntity GetSlimmedDownEntity();
}
}
namespace Services
{
public class SomeBusinessLogic : ISomeBusinessLogic
{
private readonly IFakeRepo _repo;
public SomeBusinessLogic(IFakeRepo repo)
{
_repo = repo;
}
public IThisIsAnEntity GetEntity()
{
return _repo.GetEntity();
}
public IThisIsAnSlimmedDownEntity GetSlimmedDownEntity()
{
return _repo.GetEntity();
}
}
}
namespace UI
{
public class SomeUi
{
private readonly ISomeBusinessLogic _service;
public SomeUi(ISomeBusinessLogic service)
{
_service = service;
}
public IThisIsAnSlimmedDownEntity GetViewModel()
{
return _service.GetSlimmedDownEntity();
}
public IComposite GetCompositeViewModel()
{
var dto = _service.GetSlimmedDownEntity();
var viewModel = Mapper.Map<IThisIsAnSlimmedDownEntity, IComposite>(dto);
viewModel.SomethingSpecial = "Something else";
return viewModel;
}
}
public class SomeViewModel : IComposite
{
public long Id { get; set; }
public string AnotherField { get; set; }
public string SomethingSpecial { get; set; }
}
}
namespace UI.Abstractions
{
public interface IComposite : IThisIsAnSlimmedDownEntity, ISomeExtraInfo
{
}
public interface ISomeExtraInfo
{
string SomethingSpecial { get; set; }
}
}
nhibernate is one of those orm`s that allow you to avoid having DAL entities and it will be better for performance to avoid extra mapping from BLL TO DAL, but if it is not critical for you, it will be better to keep it at as it is to have application layers loose coupled
Related
First of all I'm sorry if this is going to be a long post, but I don't know how to explain the problem in the correct way without the required details.
I'm having troubles finding a way to abstract my DAL from an Entity Framework implementation. The project I'm working on is very small, but if in future I'd want to switch to another ORM like NHibernate, or just plain ADO.NET, I'd like to write code just for the implementation, not the entire DAL.
Say I have these entities in my MyWallet.DAL:
public interface IWallet {
long Id { get; set; }
float TotalAmountOfMoney { get; set; }
long CurrencyId { get; set; }
ICurrency Currency { get; set; }
DateTime RecordedOn { get; set; }
ICollection<IMoneyMovement> MoneyMovements { get; set; }
}
public interface ICurrency {
long Id { get; set; }
char Symbol { get; set; }
string Code { get; set; }
string Description { get; set; }
}
public interface IMoneyMovement {
long Id { get; set; }
float Amount { get; set; }
string Description { get; set; }
long WalletId { get; set; }
IWallet Wallet { get; set; }
DateTime RecordedOn { get; set; }
DateTime MovedOn { get; set; }
}
As you can see these are plain interfaces which I plan to implement on another library which will contain the actual Entity Framework implementation (say MyWallet.DAL.EntityFramework). Of course I'm going to decorate the entities implementation with Entity Framework specific attributes as [Key] or [ForeignKey] and stuff like that.
I also defined some repository in MyWallet.DAL like IWalletRepository, IMoneyMovementRepository, ICurrencyRepository to gain access to the entities. Actually I don't know if this is the right way to design access to the entities. Of course I also defined factories to get the concrete implementation of the entities.
In my business layer I defined services to handle the object request, work with the DAL entities and return a business object, like this:
public class WalletService {
private readonly IWalletRepository _walletRepository;
private readonly IWalletFactory _walletFactory;
public WalletService(IWalletRepository walletRepository,
IWalletFactory walletFactory) {
_walletRepository = walletRepository;
_walletFactory = walletFactory;
}
public CreatedWallet CreateWallet(CreateWalletRequest request) {
var wallet = _walletFactory.Create();
wallet.CurrencyId = request.CurrencyId;
wallet.TotalAmountOfMoney = request.TotalAmountOfMoney;
wallet.RecordedOn = DateTime.Now;
_walletRepository.Create(wallet);
_walletRepository.SaveChanges();
return new CreatedWallet {
Id = wallet.Id
}
}
}
I thought this was going to work seamlessly, or at worst - in a situation when I've got more than one repository - I could share the DataContext so I'd need to fire the SaveChanges method on just one to reflect the changes on the database.
The problem is with the repository implementation, in this case I'll continue with Entity Framework:
public class EFDataContext : DbContext {
public EFDataContext() : base ("name=MyConnectionString") {
}
public virtual DbSet<EFWallet> Wallets { get; set; }
public virtual DbSet<EFMoneyMovement> MoneyMovements { get; set; }
public virtual DbSet<EFCurrency> Currencies { get; set; }
}
public class EFWalletRepository : IWalletRepository {
private readonly EFDbContext _dataContext;
public EFWalletRepository(EFDbContext dataContext) {
_dataContext = dataContext ?? new EFDbContext();
}
public int SaveChanges() {
return _dataContext.SaveChanges();
}
public void Dispose() {
_dataContext.Dispose();
}
public void Create(IWallet wallet) {
...???
}
}
Now that's the problem: how do I work with interfaces when the DataContext knows only about concrete implementations? Am I doing this all wrong?
UPDATE:
Ok so, basically, as stated out by #TomTom, why fight Entity Framework when you could just embrace its power? I guess I'll just let EF be the abstraction. In fact, by letting EF act as the DAL, you can just focus on the business logic of your project.
And to put it all together and respond to #tdragon regarding the repositories / unit of work issue: yes, I could either wrap multiple repositories inside an unit of work or simply let the DbContext be the unit of work:
public class EFWalletRepository : IWalletRepository {
private readonly EFDbContext _dataContext;
public EFWalletRepository() {
_dataContext = new EFDbContext();
}
public void Dispose() {
_dataContext.Dispose();
}
public IEnumerable<Wallet> Wallets {
get { return _dataContext.Wallets; }
}
public void SaveWallet(Wallet wallet) {
if (wallet.Id == 0) {
_dataContext.Wallets.Add(wallet);
} else {
var databaseEntry = _dataContext.Wallets.Find(wallet.Id);
//update properties
}
_dataContext.SaveChanges();
}
}
Simply speaking: yes, you do it wrong. You introduce a bad abstraction (that costs you dearly in functionality) "because of". EF already is an abstraction.
Any abstraction on top of it will cost you in terms of functionality used - which in terms of databases comes with a big performance impact. Want an example? "Include" to preload navigation properties (instead of lazy loading). You will have to work around this and a lot of more detailed behavior that is ORM specific - for the gain of having what? And if you give up on those higher more specific functions your performance WILL suffer.
I can't see any reason to abstract your model (entities). Do you expect them to change when you change the way you access your database?
But if you want to keep it that way, you can make your repository interfaces generic, and pass the concrete entity type when defining repository, so you would end up with:
public class EFWalletRepository : IWalletRepository<EFWallet>
{
public void Create(EFWallet wallet)
{
_dataContext.Add(wallet);
}
}
Other suggestions:
You should not expose sets for your model properties. It's against OOP rules - you should rather expose some methods to manipulate the objects, the state should be more internal.
You probably should not add SaveChanges() method to your repository - this should be a "unit of work" job to commit all changes to the database.
You would face a problem when you would use more than one repository in your service layer, as you create a new DbContext for repository, when you should have one for single "unit of work".
A few queries on EF.
Questions -
Should the methods that directly use database context object be part of Controller classes or Models?
ContactManagerContext.cs (which I am considering as a DAL layer?) Is my assumption correct?
Where should the ContactManager class be placed? Model or DAL? It is currently part of the Model class.
will add more questions
This is how I have structured the classes - Models and Controllers.
Please review and comment on if the code is structured correctly or not and how it can be improved.
Model class (Contact.cs):
using Contact_Manager.DAL;
namespace Contact_Manager.Models
{
public class Contact
{
[Key]
public int ContactId { get; set; }
[Required, MaxLength(100)]
public string FirstName { get; set; }
[Required, MaxLength(100)]
public string LastName { get; set; }
public string EMail { get; set; }
public string Phone { get; set; }
public string BusinessName { get; set; }
}
public class ContactManager
{
ContactContext db = new ContactContext();
public IEnumerable<Contact> ContactList(int? selectedContact)
{
IQueryable<Contact> contacts = db.Contacts;
return contacts.ToList();
}
}
}
ContactManagerContext.cs (DAL)
------------------------------
using System.Data.Entity;
using System.Linq;
using Contact_Manager.Models;
namespace Contact_Manager.DAL
{
public class ContactContext : DbContext
{
public ContactContext()
: base("ContactMgrDBContext")
{
Database.SetInitializer<ContactContext>(new DropCreateDatabaseIfModelChanges<ContactContext>());
}
public DbSet<Contact> Contacts { get; set; }
}
}
ContactController.cs (Controller class):
using System.Web.Mvc;
using System.Linq;
using Contact_Manager.Models;
namespace Contact_Manager.Controllers
{
public class ContactController : Controller
{
//
// GET: /Contact/
public JsonResult ContactList()
{
ContactManager cMgr = new ContactManager();
IEnumerable<Contact> contactList = cMgr.ContactList(0);
//var contactsJson = JsonConvert.SerializeObject(contacts.ToList());
return Json(contactList, JsonRequestBehavior.AllowGet);
}
public ActionResult Index()
{
return View();
}
}
}
The MVC pattern is one of the most misunderstood architecture patterns.
Also if it is used very often in UI it is a more general approach. The common usage has to be separated from the aim to adress different responsibilities.
The best way to explain MVC is to see it as a pattern that separates responsibilities AND the collaboration between them in ONE layer. So you may have MVC in the UI-Layer, but also in the DAO-Layer.
For example in the UI-Layer a model object is an object that holds the state of a UI-Component. The View-Object is the UI-Component that holds logic to draw itself on base of the model object state. The Controller retreives events from different sources and orchestrates communication between model and view.
In the DAO-Layer the model object is a part of a database state (often a row). Think of an ORM-Object. The view object is the representation for the "next" layer. The controller is the DAO that orchestrates mappings and changes.
In general you need something that holds a STATE (model). Then you need an external representaion of the STATE to PUBLISH (view) avoiding coupling to the STATE. After all you have to have BEHAVIOUR (controller) orchestrate changes and mappings.
The approach to see MVC as layers may work for small projects. In larger projects you will face problems in maintainability because you have definitely MORE than three responsibilities. And if you only have three layers you will mix responsibilities lacking the Single Responsibility Principle.
To answer your questions:
No. Write a separate DAO for that. The controller and/or the model should use that.
No. See 1.
If we talk about MVC the controller is the controller. Nothing else. If we talk about layers the controller seems to mix responsibilities of UI, Model maybe DAO. So the assignment is ambiguous.
You can you the three Layers' model in the Controller part. the Controller will be the highest layer, and it will "talk" with the BL and so on.
The Models suppose to be simple and clean.
When I program using LINQ with a .dbml file, there is only one context. But, when I do an MVC site, it seems like I have separate contexts for each entity (which is the way the MVC tutorial showed me how to do it; with "movies" context).
I have:
public class AccountsContext : DbContext
{
public AccountsContext()
: base("DefaultConnection")
{
}
public DbSet<Account> Accounts { get; set; }
}
And, I have:
public class ClientsContext : DbContext
{
public ClientsContext()
: base("DefaultConnection")
{
}
public DbSet<Client> Clients { get; set; }
}
When I call these, I have to create separate contexts, like:
private AccountsContext db = new AccountsContext();
private ClientsContext clientsContext = new ClientsContext();
... Which is both annoying, and it seems redundant since I know that when I use LINQ, I only have to instantiate a single database object.
Is there a way to use only one contextŠ± and is this recommended?
There shouldn't be anything stopping you from using one context. The database, and the tooling used to access it, should be completely independent of anything outside of it (business logic, service layer, UI, etc...).
The number of contexts, or how you use them, shouldn't change based on your client technology.
What about MVC leads you to believe that you would need more than one context? And what's stopping you from doing so?
If you think you need to use a context for each entity, because the sample was that way, you don't. Just use one context.
If it helps, this is what a simple context looks like with more than one entity:
public partial class abook_dbEntities : DbContext
{
public abook_dbEntities()
: base("name=abook_dbEntities")
{
}
public DbSet<Entity> Entities { get; set; }
public DbSet<Contact> Contacts { get; set; }
}
If it helps, a typical business flow looks like this:
UI -> Controller -> Business logic -> Data access -> Database
Your data contexts would go in your data layer. Your logic would go in your business logic layer.
From what I have read POCO classes should be persistence ignorant and should not contain references to repositories.
Q1. Given the above, how would I populate the QuestionBlocks collection? I have read that POCO's should contain behavior so you don't end of with an anemic model, so I'm kind of confused as how one is supposed to do that without persistence. If that's the case then what kind of behavior would you put in a POCO?
Ex:
public class Survey
{
public int SurveyId { get; set; }
public string Title { get; set; }
public int BrandId { get; set; }
public DateTime Created { get; set; }
public List<SurveyQuestionBlock> QuestionBlocks { get; set; }
[ResultColumn]
public string Name { get; set; }
/// <summary>
/// Constructor
/// </summary>
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
I would append another view: POCO states for objects which are not dependent on any framework. The wiki definition of a POJO is much more meaningful to me then the one for POCO:
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
To paraphrase the wiki definition of the POJO, we can say that POCO object might not be forced to:
I. Extend prespecified class:
public class MyClass : AnyFramework.ObjectBase {...
II. Implement prespecified interfaces
public class MyClass : AnyFramework.IHaveDependency {...
III. Contain prespecified attribute
[AnyFramework.KeyAttribute]
public class MyClass {...
Given this (almost anything else is allowed) in the meaning of taking care about the object state. Other words, if object will check Business logic, it is correct.
But any POCO object can be used in a framework. Today it is mostly for ORM which is responsible for persistence. All application tiers are working with POCO objects, while data layer is responsible for loading and persisting (CRUD). This is mostly done via Proxies of these POCO objects.
So, POCO could be used as full business object, which can take care about itself (check correctness of collection items, properties...). This makes it different from DTO
Given the above, how would I populate the QuestionBlocks collection?
When reading from a database, the persistence infrastructure should populate the QuestionBlocks collection - reconstitution. Reconstruction should not invoke behavior, it should only set appropriate fields on the POCO. This is the responsibility of the repository. A repository is typically referenced from an application service, which sets up the stage for invoking entity behavior.
If that's the case then what kind of behavior would you put in a POCO?
The behavior in the POCO entity should be concerned with making changes to the entity itself as well as maintaining invariants - ie ensuring the integrity of the entity. In your example, the simplest kind of behavior on the POCO should be method for adding a new question block to the collection on the survey. Ideally, you would make many of the properties on the survey entity read-only:
public class Survey
{
public int SurveyId { get; private set; }
public string Title { get; private set; }
public int BrandId { get; private set; }
public DateTime Created { get; private set; }
public IList<SurveyQuestionBlock> QuestionBlocks { get; private set; }
public string Name { get; private set; }
public void AddQuestionBlock(string questionBlockInfo)
{
this.QuestionBlocks.Add(new SurveyQuestionBlock(...));
}
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
The persistence layer should be able to set the values of the read-only properties via reflection. You can go a step further and only expose the question blocks collection as a read-only collection to ensure that it can only be modified from within the entity itself.
First off, I think this is somewhat ridiculous to do but the other members of my team insist upon it and I can't come up with a good argument against it other than "I think it's dumb"...
What we're trying to do is create a completely abstract data layer and then have various implementations of that data layer. Simple enough, right? Enter Entity Framework 4.1...
Our end goal here is that the programmers (I do my best to stay only on the data layer) never want to have to be exposed to the concrete classes. They only ever want to have to use interfaces in their code, aside from obviously needing to instantiate the factory.
I want to achieve something like the following:
First we have our "Common" library of all of the interfaces, we'll call it "Common.Data":
public interface IEntity
{
int ID { get; set; }
}
public interface IUser : IEntity
{
int AccountID { get; set; }
string Username { get; set; }
string EmailAddress { get; set; }
IAccount Account { get; set; }
}
public interface IAccount : IEntity
{
string FirstName { get; set; }
string LastName { get; set; }
DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
}
public interface IEntityFactory
{
DbSet<IUser> Users { get; }
DbSet<IAccount> Accounts { get; }
}
From that we then have an implementation library, we'll call it "Something.Data.Imp":
internal class User : IUser
{
public int ID { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public IAccount Account { get; set; }
public class Configuration : EntityTypeConfiguration<User>
{
public Configuration() : base()
{
...
}
}
}
internal class Account : IAccount
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
public class Configuration : EntityTypeConfiguration<Account>
{
public Configuration() : base()
{
...
}
}
}
Factory:
public class ImplEntityFactory : IEntityFactory
{
private ImplEntityFactory(string connectionString)
{
this.dataContext = new MyEfDbContext(connectionString);
}
private MyEfDbContext dataContext;
public static ImplEntityFactory Instance(string connectionString)
{
if(ImplEntityFactory._instance == null)
ImplEntityFactory._instance = new ImplEntityFactory(connectionString);
return ImplEntityFactory._instance;
}
private static ImplEntityFactory _instance;
public DbSet<IUser> Users // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Users; }
}
public DbSet<IAccount> Accounts // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Accounts; }
}
}
Context:
public class MyEfDataContext : DbContext
{
public MyEfDataContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<MyEfDataContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new User.Configuration());
modelBuilder.Configurations.Add(new Account.Configuration());
base.OnModelCreating(modelBuilder);
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
}
Then the front-end programmers would be using it such as:
public class UsingIt
{
public static void Main(string[] args)
{
IEntityFactory factory = new ImplEntityFactory("SQLConnectionString");
IUser user = factory.Users.Find(5);
IAccount usersAccount = user.Account;
IAccount account = factory.Accounts.Find(3);
Console.Write(account.Users.Count());
}
}
So that's pretty much it... I'm hoping someone on here might be able to either point me in the right direction or help me out with a good argument that I can fire back at the development team. I've looked at some other articles on this site about EF not being able to work with interfaces and one reply saying that you can't implement IDbSet (which I find kind of curious, why would they provide it if you couldn't implement it?) but so far to no avail.
Thanks in advance for any help!
J
The first argument is that EF doesn't work with interfaces. DbSet must be defined with a real entity implementation.
The second argument is that your entities should not contain DbSet - that is context related class and your entities should be pure of such dependency unless you are going to implement Active record pattern. Even in such case you will definitely not have access to DbSet of different entity in another entity. Even if you wrap set you are still too close to EF and entity never have property accessing all entities of another entity type (not only those related to current instance).
Just to make it clear DbSet in EF has very special meaning - it is not a collection. It is entry point to database (for example each LINQ query on DbSet hits database) and it is in normal scenarios not exposed on entities.
The third argument is that you are using a single context per application - you have a single private instance per singleton factory. Unless you are doing some single run batch application it is definitely wrong.
The last argument is simply practical. You are paid for delivering features not for wasting time on abstraction which doesn't give you (and your customer) any business value. It is not about proving why you should not create this abstraction. It is about proving why you should do it. What value will you get from using it? If your colleagues are not able to come with arguments which have business value you can simply go to your product manager and let him use his power - he holds the budget.
Generally abstraction is part of well designed object oriented application - that is correct. BUT:
Every abstraction will make your application somehow more complex and it will increase cost and time of development
Not every abstraction will make your application better or more maintainable - too much abstraction has reverse effect
Abstracting EF is hard. Saying that you will abstract data access in the way that you can replace it with another implementation is task for data access gurus. First of all you must have very good experience with many data access technologies to be able to define such abstraction which will work with all of them (and in the end you can only tell that your abstraction works with technologies you thought about when you design that). Your abstraction will work only with EF DbContext API and with nothing else because it is not an abstraction. If you want to build universal abstraction you should start studying Repository pattern, Unit of Work pattern and Specification pattern - but that is a big deal of work to make them and to implement them universal. The first step needed is to hide everything related to data access behind that abstraction - including LINQ!
Abstracting data access to support multiple APIs make sense only if you need it now. If you only think that it can be useful in future than it is in business driven projects completely wrong decision and developer who came with that idea is not competent to make business targeting decisions.
When it make sense to do "a lot of" abstraction?
You have such requirement now - that moves burden of such decision to person responsible for budget / project scope / requirements etc.
You need abstraction now to simplify design or solve some a problem
You are doing open source or hobby project and you are not driven by business needs but by purity and quality of your project
You are working on platform (long living retail product which will live for a long time) or public framework - this generally returns to the first point because this type of products usually have such abstraction as requirement
If you are working only targeted application (mostly single purpose applications on demand or outsourced solutions) the abstraction should be used only if necessary. These applications are driven by costs - the target is delivering working solution for minimal costs and in the shortest time. This target must be achieved even if resulting application will not be very good internally - the only thing which matters is if application meets requirements. Any abstraction based on "what if ... happens" or "perhaps we will need ..." increases costs by virtual (non existing) requirements which will in 99% never happen and in most cases initial contract with customer didn't count which such additional costs.
Btw. this type of applications is targeted by MS APIs and designer strategy - MS will make a lot of designers and code generators which will create non optimal but cheap and quick solutions which can be created by people with smaller skill set and are very cheap. The last example is LightSwitch.